Changeset 89

Show
Ignore:
Timestamp:
06/05/07 11:26:34 (1 year ago)
Author:
apdavison
Message:

Implemented AllToAllConnector and OneToOneConnector for nest, neuron and pcsim.

You can now pass either a Connector object or a string plus parameter dict to the Projection constructor, e.g.:

prj1 = Projection(p1, p2, 'allToAll', {'allow_self_connections':False})
prj2 = Projection(p1, p2, AllToAllConnector(allow_self_connections=False))
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/connector-class/common.py

    r75 r89  
     1# encoding: utf-8 
    12""" 
    23Defines the PyNN classes and functions, and hence the FACETS API. 
     
    1819 
    1920# ============================================================================== 
    20 #   Utility classes 
    21 # ============================================================================== 
     21#   Utility classes and functions 
     22# ============================================================================== 
     23 
     24# The following two functions taken from 
     25# http://www.nedbatchelder.com/text/pythonic-interfaces.html 
     26def _functionId(obj, nFramesUp): 
     27    """ Create a string naming the function n frames up on the stack. """ 
     28    fr = sys._getframe(nFramesUp+1) 
     29    co = fr.f_code 
     30    return "%s.%s" % (obj.__class__, co.co_name) 
     31 
     32def _abstractMethod(obj=None): 
     33    """ Use this instead of 'pass' for the body of abstract methods. """ 
     34    raise Exception("Unimplemented abstract method: %s" % _functionId(obj, 1)) 
    2235 
    2336class ID(int): 
     
    649662 
    650663# ============================================================================== 
     664#   Connection method classes 
     665# ============================================================================== 
     666 
     667class Connector(object): 
     668    """Abstract base class for Connector classes.""" 
     669     
     670    def __init__(self): 
     671        _abstractMethod(self) 
     672     
     673    def connect(self,projection): 
     674        """Connect all neurons in ``projection``""" 
     675        _abstractMethod(self) 
     676 
     677class AllToAllConnector(Connector): 
     678    """ 
     679    Connects all cells in the presynaptic population to all cells in the 
     680    postsynaptic population. 
     681    """ 
     682     
     683    def __init__(self, allow_self_connections=True): 
     684        assert isinstance(allow_self_connections, bool) 
     685        self.allow_self_connections = allow_self_connections 
     686 
     687class OneToOneConnector(Connector): 
     688    """ 
     689    Where the pre- and postsynaptic populations have the same size, connect 
     690    cell i in the presynaptic population to cell i in the postsynaptic 
     691    population for all i. 
     692    In fact, despite the name, this should probably be generalised to the 
     693    case where the pre and post populations have different dimensions, e.g., 
     694    cell i in a 1D pre population of size n should connect to all cells 
     695    in row i of a 2D post population of size (n,m). 
     696    """ 
     697     
     698    def __init__(self): 
     699        pass 
     700     
     701         
     702# ============================================================================== 
    651703#   Utility classes 
    652704# ============================================================================== 
  • branches/connector-class/nest.py

    r88 r89  
    861861        self._targets = []     # holds gids 
    862862        self._sources = []     # holds gids 
    863         connection_method = getattr(self,'_%s' % method) 
    864         if target: 
    865             self.nconn = connection_method(methodParameters,synapse_type=target) 
    866         else: 
     863        self.synapse_type = target 
     864         
     865        if isinstance(method, str): 
     866            connection_method = getattr(self,'_%s' % method)    
    867867            self.nconn = connection_method(methodParameters) 
     868        elif isinstance(method,common.Connector): 
     869            self.nconn = method.connect(self) 
     870 
    868871        assert len(self._sources) == len(self._targets) == len(self._targetPorts), "Connection error. Source and target lists are of different lengths." 
    869872        self.connection = Projection.ConnectionDict(self) 
     
    906909    # --- Connection methods --------------------------------------------------- 
    907910     
    908     def _allToAll(self,parameters=None,synapse_type=None): 
     911    def _allToAll(self,parameters=None): 
    909912        """ 
    910913        Connect all cells in the presynaptic population to all cells in the postsynaptic population. 
     
    914917        if parameters and parameters.has_key('allow_self_connections'): 
    915918            allow_self_connections = parameters['allow_self_connections'] 
    916         self.synapse_type = synapse_type 
    917         postsynaptic_neurons = numpy.reshape(self.post.cell,(self.post.cell.size,)) 
    918         presynaptic_neurons  = numpy.reshape(self.pre.cell,(self.pre.cell.size,)) 
    919         for post in postsynaptic_neurons: 
    920             source_list = presynaptic_neurons.tolist() 
    921             # if self connections are not allowed, check whether pre and post are the same 
    922             if not allow_self_connections and post in source_list: 
    923                 source_list.remove(post) 
    924             self._targets += [post]*len(source_list) 
    925             self._sources += source_list 
    926             self._targetPorts += pynest.convergentConnect(source_list,post,[1.0],[0.1]) 
    927         return len(self._targets) 
    928      
    929     def _oneToOne(self,synapse_type=None): 
     919        c = AllToAllConnector(allow_self_connections) 
     920        return c.connect(self) 
     921     
     922    def _oneToOne(self,parameters=None): 
    930923        """ 
    931924        Where the pre- and postsynaptic populations have the same size, connect 
     
    937930        in row i of a 2D post population of size (n,m). 
    938931        """ 
    939         self.synapse_type = synapse_type 
    940932        if self.pre.dim == self.post.dim: 
    941933            self._sources = numpy.reshape(self.pre.cell,(self.pre.cell.size,)) 
     
    949941            raise Exception("Method 'oneToOne' not yet implemented for the case where presynaptic and postsynaptic Populations have different sizes.") 
    950942     
    951     def _fixedProbability(self,parameters,synapse_type=None): 
     943    def _fixedProbability(self,parameters): 
    952944        """ 
    953945        For each pair of pre-post cells, the connection probability is constant. 
    954946        """ 
    955         self.synapse_type = synapse_type 
    956947        allow_self_connections = True 
    957948        try: 
     
    976967        return len(self._sources) 
    977968     
    978     def _distanceDependentProbability(self,parameters,synapse_type=None): 
     969    def _distanceDependentProbability(self,parameters): 
    979970        """ 
    980971        For each pair of pre-post cells, the connection probability depends on distance. 
     
    982973        for probability, involving 'd', e.g. "exp(-abs(d))", or "float(d<3)" 
    983974        """ 
    984         self.synapse_type = synapse_type 
    985975        allow_self_connections = True 
    986976        if type(parameters) == types.StringType: 
     
    10331023                        self._targetPorts.append(pynest.connect(pre_addr,post_addr)) 
    10341024     
    1035     def _fixedNumberPre(self,parameters,synapse_type=None): 
     1025    def _fixedNumberPre(self,parameters): 
    10361026        """Each presynaptic cell makes a fixed number of connections.""" 
    1037         self.synapse_type = synapse_type 
    10381027        allow_self_connections = True 
    10391028        if type(parameters) == types.IntType: 
     
    10771066                    self._targetPorts.append(pynest.connect(pre_addr,pynest.getAddress(post))) 
    10781067     
    1079     def _fixedNumberPost(self,parameters,synapse_type=None): 
     1068    def _fixedNumberPost(self,parameters): 
    10801069        """Each postsynaptic cell receives a fixed number of connections.""" 
    1081         self.synapse_type = synapse_type 
    10821070        allow_self_connections = True 
    10831071        if type(parameters) == types.IntType: 
     
    11211109                    self._targetPorts.append(pynest.connect(pynest.getAddress(pre),post_addr)) 
    11221110     
    1123     def _fromFile(self,parameters,synapse_type=None): 
     1111    def _fromFile(self,parameters): 
    11241112        """ 
    11251113        Load connections from a file. 
    11261114        """ 
    1127         self.synapse_type = synapse_type 
    11281115        if type(parameters) == types.FileType: 
    11291116            fileobj = parameters 
     
    11501137        f.close() 
    11511138         
    1152         self._fromList(input_tuples, synapse_type
    1153          
    1154     def _fromList(self,conn_list,synapse_type=None): 
     1139        self._fromList(input_tuples
     1140         
     1141    def _fromList(self,conn_list): 
    11551142        """ 
    11561143        Read connections from a list of tuples, 
     
    11591146        lists containing the neuron array coordinates. 
    11601147        """ 
    1161         self.synapse_type = synapse_type 
    11621148        for i in xrange(len(conn_list)): 
    11631149            src, tgt, weight, delay = conn_list[i][:] 
     
    11711157            self._targetPorts.append(pynest.connectWD(pre_addr,post_addr, 1000*weight, delay)) 
    11721158 
    1173     def _2D_Gauss(self,parameters,synapse_type=None): 
     1159    def _2D_Gauss(self,parameters): 
    11741160        """ 
    11751161        Source neuron is connected to a 2D targetd population with a spatial profile (Gauss). 
     
    11811167        sigma: sigma of the Gauss 
    11821168        """ 
    1183         self.synapse_type = synapse_type 
    11841169        def rcf_2D(parameters): 
    11851170            rng = parameters['rng'] 
     
    12281213                rcf_2D(parameters) 
    12291214 
    1230     def _test_delay(self,params,synapse_type=None): 
    1231         self.synapse_type = synapse_type 
     1215    def _test_delay(self,params): 
    12321216        # debug get delays from outside 
    12331217        #delay_array = parameters['delays_array'] 
     
    12451229        print 'leaving test_delay' 
    12461230         
    1247     def _3D_Gauss(self,parameters,synapse_type=None): 
     1231    def _3D_Gauss(self,parameters): 
    12481232        """ 
    12491233        Source neuron is connected to a 3D targetd population with a spatial profile (Gauss). 
     
    15881572        # should be put here or in an external module. 
    15891573        raise Exception("Method not yet implemented") 
    1590   
     1574 
     1575# ============================================================================== 
     1576#   Connection method classes 
     1577# ============================================================================== 
     1578 
     1579class AllToAllConnector(common.AllToAllConnector):     
     1580     
     1581    def connect(self, projection): 
     1582        postsynaptic_neurons = numpy.reshape(projection.post.cell,(projection.post.cell.size,)) 
     1583        presynaptic_neurons  = numpy.reshape(projection.pre.cell,(projection.pre.cell.size,)) 
     1584        for post in postsynaptic_neurons: 
     1585            source_list = presynaptic_neurons.tolist() 
     1586            # if self connections are not allowed, check whether pre and post are the same 
     1587            if not self.allow_self_connections and post in source_list: 
     1588                source_list.remove(post) 
     1589            projection._targets += [post]*len(source_list) 
     1590            projection._sources += source_list 
     1591            projection._targetPorts += pynest.convergentConnect(source_list,post,[1.0],[0.1]) 
     1592        return len(projection._targets) 
     1593 
     1594class OneToOneConnector(common.OneToOneConnector): 
     1595     
     1596    def connect(self, projection): 
     1597        if projection.pre.dim == projection.post.dim: 
     1598            projection._sources = numpy.reshape(projection.pre.cell,(projection.pre.cell.size,)) 
     1599            projection._targets = numpy.reshape(projection.post.cell,(projection.post.cell.size,)) 
     1600            for pre,post in zip(projection._sources,projection._targets): 
     1601                pre_addr = pynest.getAddress(pre) 
     1602                post_addr = pynest.getAddress(post) 
     1603                projection._targetPorts.append(pynest.connect(pre_addr,post_addr)) 
     1604            return projection.pre.size 
     1605        else: 
     1606            raise Exception("Connection method not yet implemented for the case where presynaptic and postsynaptic Populations have different sizes.") 
     1607     
     1608     
    15911609# ============================================================================== 
    15921610#   Utility classes 
  • branches/connector-class/neuron.py

    r88 r89  
    11551155        hoc_commands = ['objref %s' % self.hoc_label, 
    11561156                        '%s = new List()' % self.hoc_label] 
    1157         connection_method = getattr(self,'_%s' % method) 
    11581157        self.synapse_type = target 
    11591158        self._syn_objref = _translate_synapse_type(self.synapse_type) 
    11601159         
    1161         if target: 
    1162             hoc_commands += connection_method(methodParameters,synapse_type=target) 
    1163         else: 
     1160        if isinstance(method, str): 
     1161            connection_method = getattr(self,'_%s' % method)    
    11641162            hoc_commands += connection_method(methodParameters) 
     1163        elif isinstance(method,common.Connector): 
     1164            hoc_commands += method.connect(self) 
    11651165        hoc_execute(hoc_commands, "--- Projection[%s].__init__() ---" %self.label) 
    11661166         
     
    12211221        if parameters and parameters.has_key('allow_self_connections'): 
    12221222            allow_self_connections = parameters['allow_self_connections'] 
    1223         hoc_commands = [] 
    1224         for tgt in self.post.gidlist: 
    1225             for src in self.pre.fullgidlist: 
    1226                 if allow_self_connections or self.pre != self.post or tgt != src: 
    1227                     hoc_commands += self.__connect(src,tgt) 
    1228         return hoc_commands 
     1223        c = AllToAllConnector(allow_self_connections) 
     1224        return c.connect(self) 
    12291225         
    12301226    def _oneToOne(self,parameters=None): 
     
    12371233        cell i in a 1D pre population of size n should connect to all cells 
    12381234        in row i of a 2D post population of size (n,m). 
    1239         """    
    1240         if self.pre.dim == self.post.dim: 
    1241             hoc_commands = [] 
    1242             for tgt in self.post.gidlist: 
    1243                 src = tgt - self.post.gid_start + self.pre.gid_start 
    1244                 hoc_commands += self.__connect(src,tgt) 
    1245         else: 
    1246             raise Exception("Method '%s' not yet implemented for the case where presynaptic and postsynaptic Populations have different sizes." % sys._getframe().f_code.co_name) 
    1247         return hoc_commands 
     1235        """ 
     1236        c = OneToOneConnector() 
     1237        return c.connect(self) 
    12481238     
    12491239    def _fixedProbability(self,parameters): 
     
    17581748 
    17591749# ============================================================================== 
     1750#   Connection method classes 
     1751# ============================================================================== 
     1752 
     1753class HocConnector(object): 
     1754     
     1755    def singleConnect(self,projection,src,tgt): 
     1756        """ 
     1757        Write hoc commands to connect a single pair of neurons. 
     1758        """ 
     1759        cmdlist = ['nc = pc.gid_connect(%d,%s.object(%d).%s)' % (src, 
     1760                                                                 projection.post.hoc_label, 
     1761                                                                 projection.post.gidlist.index(tgt), 
     1762                                                                 projection._syn_objref), 
     1763                'tmp = %s.append(nc)' % projection.hoc_label] 
     1764        projection.connections.append((src,tgt)) 
     1765        return cmdlist 
     1766 
     1767class AllToAllConnector(common.AllToAllConnector, HocConnector):     
     1768     
     1769    def connect(self, projection): 
     1770        hoc_commands = [] 
     1771        for tgt in projection.post.gidlist: 
     1772            for src in projection.pre.fullgidlist: 
     1773                if self.allow_self_connections or projection.pre != projection.post or tgt != src: 
     1774                    hoc_commands += self.singleConnect(projection,src,tgt) 
     1775        return hoc_commands 
     1776 
     1777class OneToOneConnector(common.OneToOneConnector, HocConnector): 
     1778     
     1779    def connect(self, projection): 
     1780        if projection.pre.dim == projection.post.dim: 
     1781            hoc_commands = [] 
     1782            for tgt in projection.post.gidlist: 
     1783                src = tgt - projection.post.gid_start + projection.pre.gid_start 
     1784                hoc_commands += self.singleConnect(projection,src,tgt) 
     1785        else: 
     1786            raise Exception("Method '%s' not yet implemented for the case where presynaptic and postsynaptic Populations have different sizes." % sys._getframe().f_code.co_name) 
     1787        return hoc_commands 
     1788     
     1789# ============================================================================== 
    17601790#   Utility classes 
    17611791# ============================================================================== 
  • branches/connector-class/pcsim.py

    r88 r89  
    11041104         
    11051105        # Determine connection decider 
    1106         if method == 'allToAll': 
    1107             decider = RandomConnections(1) 
    1108             wiring_method = DistributedSyncWiringMethod(pcsim_globals.net) 
    1109         elif method == 'fixedProbability': 
    1110             decider = RandomConnections(float(methodParameters)) 
    1111             wiring_method = DistributedSyncWiringMethod(pcsim_globals.net) 
    1112         elif method == 'distanceDependentProbability': 
    1113             decider = EuclideanDistanceRandomConnections(methodParameters[0], methodParameters[1]) 
    1114             wiring_method = DistributedSyncWiringMethod(pcsim_globals.net) 
    1115         elif method == 'fixedNumberPre': 
    1116             decider = DegreeDistributionConnections(ConstantNumber(parameters), DegreeDistributionConnections.incoming) 
    1117             wiring_method = SimpleAllToAllWiringMethod(pcsim_globals.net) 
    1118         elif method == 'fixedNumberPost': 
    1119             decider = DegreeDistributionConnections(ConstantNumber(parameters), DegreeDistributionConnections.outgoing) 
    1120             wiring_method = SimpleAllToAllWiringMethod(pcsim_globals.net) 
    1121         elif method == 'oneToOne': 
    1122             decider = RandomConnections(1) 
    1123             wiring_method = OneToOneWiringMethod(pcsim_globals.net)  
    1124         else: 
    1125             raise Exception("METHOD NOT YET IMPLEMENTED") 
    1126              
     1106        if isinstance(method, str): 
     1107            if method == 'allToAll': 
     1108                decider = RandomConnections(1) 
     1109                wiring_method = DistributedSyncWiringMethod(pcsim_globals.net) 
     1110            elif method == 'fixedProbability': 
     1111                decider = RandomConnections(float(methodParameters)) 
     1112                wiring_method = DistributedSyncWiringMethod(pcsim_globals.net) 
     1113            elif method == 'distanceDependentProbability': 
     1114                decider = EuclideanDistanceRandomConnections(methodParameters[0], methodParameters[1]) 
     1115                wiring_method = DistributedSyncWiringMethod(pcsim_globals.net) 
     1116            elif method == 'fixedNumberPre': 
     1117                decider = DegreeDistributionConnections(ConstantNumber(parameters), DegreeDistributionConnections.incoming) 
     1118                wiring_method = SimpleAllToAllWiringMethod(pcsim_globals.net) 
     1119            elif method == 'fixedNumberPost': 
     1120                decider = DegreeDistributionConnections(ConstantNumber(parameters), DegreeDistributionConnections.outgoing) 
     1121                wiring_method = SimpleAllToAllWiringMethod(pcsim_globals.net) 
     1122            elif method == 'oneToOne': 
     1123                decider = RandomConnections(1) 
     1124                wiring_method = OneToOneWiringMethod(pcsim_globals.net)  
     1125            else: 
     1126                raise Exception("METHOD NOT YET IMPLEMENTED") 
     1127        elif isinstance(method,common.Connector): 
     1128            decider, wiring_method = method.connect(self) 
     1129         
    11271130        if not target: 
    11281131            self.syn_factory = SimpleScalingSpikingSynapse(1, 1, pcsim_globals.minDelay/1000) 
     
    12651268 
    12661269# ============================================================================== 
     1270#   Connection method classes 
     1271# ============================================================================== 
     1272 
     1273class AllToAllConnector(common.AllToAllConnector):     
     1274     
     1275    def connect(self, projection): 
     1276        # what about allow_self_connections? 
     1277        decider = RandomConnections(1) 
     1278        wiring_method = DistributedSyncWiringMethod(pcsim_globals.net) 
     1279        return decider, wiring_method 
     1280 
     1281class OneToOneConnector(common.OneToOneConnector): 
     1282     
     1283    def connect(self, projection): 
     1284        if projection.pre.dim == projection.post.dim: 
     1285            decider = RandomConnections(1) 
     1286            wiring_method = OneToOneWiringMethod(pcsim_globals.net) 
     1287            return decider, wiring_method 
     1288        else: 
     1289            raise Exception("Connection method not yet implemented for the case where presynaptic and postsynaptic Populations have different sizes.") 
     1290     
     1291 
     1292 
     1293# ============================================================================== 
    12671294#   Utility classes 
    12681295# ============================================================================== 
  • branches/connector-class/test/nesttests.py

    r88 r89  
    410410            for tgtP in [self.target6, self.target33]: 
    411411                prj1 = nest.Projection(srcP, tgtP, "allToAll") 
    412                 assert len(prj1._sources) == len(prj1._targets) 
    413                 weights = [] 
    414                 for src,tgt in prj1.connections(): 
    415                     weights.append(nest.pynest.getWeight(src,tgt)) 
    416                 assert weights == [1.0]*len(prj1._sources) 
    417      
     412                prj2 = nest.Projection(srcP, tgtP, nest.AllToAllConnector()) 
     413                for prj in prj1,prj2: 
     414                    assert len(prj._sources) == len(prj._targets) 
     415                    weights = [] 
     416                    for src,tgt in prj.connections(): 
     417                        weights.append(nest.pynest.getWeight(src,tgt)) 
     418                    assert weights == [1.0]*len(prj._sources) 
     419     
     420    def testoneToOne(self): 
     421        """For all connections created with "OneToOne" it should be possible to obtain the weight using pyneuron.getWeight()""" 
     422        prj1 = nest.Projection(self.source33, self.target33, 'oneToOne') 
     423        prj2 = nest.Projection(self.source33, self.target33, nest.OneToOneConnector()) 
     424        assert len(prj1) == self.source33.size 
     425        assert len(prj2) == self.source33.size 
     426         
    418427    def testdistantDependentProbability(self): 
    419428        """For all connections created with "distanceDependentProbability" it should be possible to obtain the weight using pyneuron.getWeight()""" 
  • branches/connector-class/test/neurontests.py

    r88 r89  
    462462            for tgtP in [self.target6, self.target33]: 
    463463                prj1 = neuron.Projection(srcP, tgtP, 'allToAll') 
     464                prj2 = neuron.Projection(srcP, tgtP, neuron.AllToAllConnector()) 
    464465                prj1.setWeights(1.234) 
    465                 weights = [] 
    466                 for connection_id in prj1.connections: 
    467                     weights.append(HocToPy.get('%s.object(%d).weight' % (prj1.label,prj1.connections.index(connection_id)), 'float')) 
    468                 assert weights == [1.234]*len(prj1) 
    469          
     466                prj2.setWeights(1.234) 
     467                for prj in prj1,prj2: 
     468                    weights = [] 
     469                    for connection_id in prj.connections: 
     470                        weights.append(HocToPy.get('%s.object(%d).weight' % (prj.label,prj.connections.index(connection_id)), 'float')) 
     471                    assert weights == [1.234]*len(prj) 
     472             
    470473    def testFixedProbability(self): 
    471474        """For all connections created with "fixedProbability" it should be possible to obtain the weight using pyneuron.getWeight()""" 
     
    481484        """For all connections created with "OneToOne" it should be possible to obtain the weight using pyneuron.getWeight()""" 
    482485        prj1 = neuron.Projection(self.source33, self.target33, 'oneToOne') 
     486        prj2 = neuron.Projection(self.source33, self.target33, neuron.OneToOneConnector()) 
    483487        assert len(prj1.connections) == self.source33.size 
     488        assert len(prj2.connections) == self.source33.size 
    484489      
    485490    def testdistantDependentProbability(self): 
  • branches/connector-class/test/pcsimtests_population.py

    r88 r89  
    124124class PopulationSetTest(unittest.TestCase): 
    125125          
    126     def setUp(self): 
    127         setup() 
    128         Population.nPop = 0 
    129         self.popul1 = Population((3,3),IF_curr_alpha) 
    130         self.popul2 = Population((5,),CbLifNeuron,{'Vinit':-0.070, 'Inoise':0.001}) 
    131      
    132     def testSetFromDict(self): 
    133         """Population.set(): Parameters set in a dict should all be retrievable from PyPCSIM directly""" 
    134         self.popul1.set({'tau_m':43.21}) 
    135         self.assertAlmostEqual( pcsim_globals.net.object(self.popul1.getObjectID(8)).taum, 0.04321, places = 5) 
     126    def setUp(self): 
     127        setup() 
     128        Population.nPop = 0 
     129        self.popul1 = Population((3,3),IF_curr_alpha) 
     130        self.popul2 = Population((5,),CbLifNeuron,{'Vinit':-0.070, 'Inoise':0.001}) 
     131     
     132    def testSetFromDict(self): 
     133        """Population.set(): Parameters set in a dict should all be retrievable from PyPCSIM directly""" 
     134        self.popul1.set({'tau_m':43.21}) 
     135        self.assertAlmostEqual( pcsim_globals.net.object(self.popul1.getObjectID(8)).taum, 0.04321, places = 5) 
    136136#      
    137      def testSetFromPair(self): 
    138         """Population.set(): A parameter set as a string,value pair should be retrievable using PyPCSIM directly""" 
    139         self.popul1.set('tau_m',12.34) 
    140         self.popul1.set('v_init',-65.0) 
    141         self.assertAlmostEqual( pcsim_globals.net.object(self.popul1.getObjectID(3)).taum, 0.01234, places=5) 
    142         self.assertAlmostEqual( pcsim_globals.net.object(self.popul1.getObjectID(3)).Vinit, -0.065, places=5) 
    143         
    144       
    145      def testSetInvalidFromPair(self): 
    146          """Population.set(): Trying to set an invalid value for a parameter should raise an exception.""" 
    147          self.assertRaises(common.InvalidParameterValueError, self.popul1.set, 'tau_m', []) 
    148       
    149      def testSetInvalidFromDict(self): 
    150          """Population.set(): When any of the parameters in a dict have invalid values, then an exception should be raised. 
    151             There is no guarantee that the valid parameters will be set.""" 
    152          self.assertRaises(common.InvalidParameterValueError, self.popul1.set, {'v_thresh':'hello','tau_m':56.78}) 
    153       
    154      def testSetNonexistentFromPair(self): 
    155          """Population.set(): Trying to set a nonexistent parameter should raise an exception.""" 
    156          self.assertRaises(common.NonExistentParameterError, self.popul1.set, 'tau_foo', 10.0) 
    157       
    158      def testSetNonexistentFromDict(self): 
    159          """Population.set(): When some of the parameters in a dict are inexistent, an exception should be raised. 
    160             There is no guarantee that the existing parameters will be set.""" 
    161          self.assertRaises(common.NonExistentParameterError, self.popul1.set, {'tau_foo': 10.0, 'tau_m': 21.0}) 
    162       
    163      def testSetWithNonStandardModel(self): 
    164          """Population.set(): Parameters set in a dict should all be retrievable using PyPCSIM interface directly""" 
    165          self.popul2.set({'Rm':4.5e6}) 
    166          self.assertAlmostEqual( pcsim_globals.net.object(self.popul2.getObjectID(3)).Rm , 4.5e6, places = 10) 
     137    def testSetFromPair(self): 
     138       """Population.set(): A parameter set as a string,value pair should be retrievable using PyPCSIM directly""" 
     139       self.popul1.set('tau_m',12.34) 
     140       self.popul1.set('v_init',-65.0) 
     141       self.assertAlmostEqual( pcsim_globals.net.object(self.popul1.getObjectID(3)).taum, 0.01234, places=5) 
     142       self.assertAlmostEqual( pcsim_globals.net.object(self.popul1.getObjectID(3)).Vinit, -0.065, places=5) 
     143       
     144     
     145    def testSetInvalidFromPair(self): 
     146        """Population.set(): Trying to set an invalid value for a parameter should raise an exception.""" 
     147        self.assertRaises(common.InvalidParameterValueError, self.popul1.set, 'tau_m', []) 
     148     
     149    def testSetInvalidFromDict(self): 
     150        """Population.set(): When any of the parameters in a dict have invalid values, then an exception should be raised. 
     151           There is no guarantee that the valid parameters will be set.""" 
     152        self.assertRaises(common.InvalidParameterValueError, self.popul1.set, {'v_thresh':'hello','tau_m':56.78}) 
     153     
     154    def testSetNonexistentFromPair(self): 
     155        """Population.set(): Trying to set a nonexistent parameter should raise an exception.""" 
     156        self.assertRaises(common.NonExistentParameterError, self.popul1.set, 'tau_foo', 10.0) 
     157     
     158    def testSetNonexistentFromDict(self): 
     159        """Population.set(): When some of the parameters in a dict are inexistent, an exception should be raised. 
     160           There is no guarantee that the existing parameters will be set.""" 
     161        self.assertRaises(common.NonExistentParameterError, self.popul1.set, {'tau_foo': 10.0, 'tau_m': 21.0}) 
     162     
     163    def testSetWithNonStandardModel(self): 
     164        """Population.set(): Parameters set in a dict should all be retrievable using PyPCSIM interface directly""" 
     165        self.popul2.set({'Rm':4.5e6}) 
     166        self.assertAlmostEqual( pcsim_globals.net.object(self.popul2.getObjectID(3)).Rm , 4.5e6, places = 10) 
     167         
     168    def testTSet(self): 
     169        """Population.tset(): The valueArray passed should be retrievable using the PyPCSIM interface """ 
     170        array_in = numpy.array([[0.1,0.2,0.3],[0.4,0.5,0.6],[0.7,0.8,0.9]]) 
     171        self.popul1.tset('i_offset', array_in) 
     172        for i in 0,1,2: 
     173            for j in 0,1,2: 
     174                self.assertAlmostEqual( array_in[i,j], pcsim_globals.net.object(self.popul1.getObjectID(self.popul1[i,j])).Iinject*1e9 , places = 7 ) 
     175     
     176    def testTSetArrayUnchanged(self): 
     177       array_in1 = numpy.array([[0.1,0.2,0.3],[0.4,0.5,0.6],[0.7,0.8,0.9]]) 
     178       array_in2 = numpy.array([[0.1,0.2,0.3],[0.4,0.5,0.6],[0.7,0.8,0.9]]) 
     179       self.assert_((array_in1==array_in2).all()) 
     180       self.popul1.tset('i_offset', array_in1) 
     181       self.assert_((array_in1==array_in2).all()) 
     182     
     183    def testTSetInvalidDimensions(self): 
     184        """Population.tset(): If the size of the valueArray does not match that of the Population, should raise an InvalidDimensionsError.""" 
     185        array_in = numpy.array([[0.1,0.2,0.3],[0.4,0.5,0.6]]) 
     186        self.assertRaises(common.InvalidDimensionsError, self.popul1.tset, 'i_offset', array_in) 
     187     
     188    def testTSetInvalidValues(self): 
     189        """Population.tset(): If some of the values in the valueArray are invalid, should raise an exception.""" 
     190        array_in = numpy.array([[0.1,0.2,0.3],[0.4,0.5,0.6],[0.7,0.8,'apples']]) 
     191        self.assertRaises(common.InvalidParameterValueError, self.popul1.tset, 'i_offset', array_in) 
     192        """Population.rset(): with native rng. This is difficult to test, so for now just require that all values retrieved should be different. Later, could calculate distribution and assert that the difference between sample and theoretical distribution is less than some threshold.""" 
     193         
     194    def testRSetNative(self): 
     195        self.popul1.rset('tau_m', 
     196                      random.RandomDistribution(rng=NativeRNG(), 
     197                                                distribution='Uniform', 
     198                                                parameters={'a':10.0, 'b':30.0})) 
     199        self.assertNotEqual(pcsim_globals.net.object(self.popul1.getObjectID(3)).taum, 
     200                            pcsim_globals.net.object(self.popul1.getObjectID(6)).taum) 
     201         
     202    def testRSetNumpy(self): 
     203         """Population.rset(): with numpy rng.""" 
     204         rd1 = random.RandomDistribution(rng=random.NumpyRNG(seed=98765), 
     205                                          distribution='uniform', 
     206                                          parameters=[0.9,1.1]) 
     207         rd2 = random.RandomDistribution(rng=random.NumpyRNG(seed=98765), 
     208                                          distribution='uniform', 
     209                                          parameters=[0.9,1.1]) 
     210         self.popul1.rset('cm',rd1) 
     211         output_values = numpy.zeros((3,3),numpy.float) 
     212         for i in 0,1,2: 
     213             for j in 0,1,2:     
     214                 output_values[i,j] = 1e9*pcsim_globals.net.object(self.popul1.getObjectID(self.popul1[i,j])).Cm 
     215         input_values = rd2.next(9) 
     216         output_values = output_values.reshape((9,)) 
     217         for i in range(9): 
     218             self.assertAlmostEqual(input_values[i],output_values[i],places=5) 
    167219          
    168      def testTSet(self): 
    169          """Population.tset(): The valueArray passed should be retrievable using the PyPCSIM interface """ 
    170          array_in = numpy.array([[0.1,0.2,0.3],[0.4,0.5,0.6],[0.7,0.8,0.9]]) 
    171          self.popul1.tset('i_offset', array_in) 
     220    def testRSetNative2(self): 
     221         """Population.rset(): with native rng.""" 
     222         rd1 = random.RandomDistribution(rng=NativeRNG(seed=98765), 
     223                                          distribution='Uniform', 
     224                                          parameters=[0.9,1.1]) 
     225         rd2 = random.RandomDistribution(rng=NativeRNG(seed=98765), 
     226                                          distribution='Uniform', 
     227                                          parameters=[0.9,1.1]) 
     228         self.popul1.rset('cm', rd1) 
     229         output_values_1 = numpy.zeros((3,3),numpy.float) 
     230         output_values_2 = numpy.zeros((3,3),numpy.float) 
    172231         for i in 0,1,2: 
    173232             for j in 0,1,2: 
    174                  self.assertAlmostEqual( array_in[i,j], pcsim_globals.net.object(self.popul1.getObjectID(self.popul1[i,j])).Iinject*1e9 , places = 7 ) 
    175       
    176      def testTSetArrayUnchanged(self): 
    177         array_in1 = numpy.array([[0.1,0.2,0.3],[0.4,0.5,0.6],[0.7,0.8,0.9]]) 
    178         array_in2 = numpy.array([[0.1,0.2,0.3],[0.4,0.5,0.6],[0.7,0.8,0.9]]) 
    179         self.assert_((array_in1==array_in2).all()) 
    180         self.popul1.tset('i_offset', array_in1) 
    181         self.assert_((array_in1==array_in2).all()) 
    182       
    183      def testTSetInvalidDimensions(self): 
    184          """Population.tset(): If the size of the valueArray does not match that of the Population, should raise an InvalidDimensionsError.""" 
    185          array_in = numpy.array([[0.1,0.2,0.3],[0.4,0.5,0.6]]) 
    186          self.assertRaises(common.InvalidDimensionsError, self.popul1.tset, 'i_offset', array_in) 
    187       
    188      def testTSetInvalidValues(self): 
    189          """Population.tset(): If some of the values in the valueArray are invalid, should raise an exception.""" 
    190          array_in = numpy.array([[0.1,0.2,0.3],[0.4,0.5,0.6],[0.7,0.8,'apples']]) 
    191          self.assertRaises(common.InvalidParameterValueError, self.popul1.tset, 'i_offset', array_in) 
    192          """Population.rset(): with native rng. This is difficult to test, so for now just require that all values retrieved should be different. Later, could calculate distribution and assert that the difference between sample and theoretical distribution is less than some threshold.""" 
    193           
    194      def testRSetNative(self): 
    195          self.popul1.rset('tau_m', 
    196                        random.RandomDistribution(rng=NativeRNG(), 
    197                                                  distribution='Uniform', 
    198                                                  parameters={'a':10.0, 'b':30.0})) 
    199          self.assertNotEqual(pcsim_globals.net.object(self.popul1.getObjectID(3)).taum, 
    200                              pcsim_globals.net.object(self.popul1.getObjectID(6)).taum) 
    201           
    202      def testRSetNumpy(self): 
    203           """Population.rset(): with numpy rng.""" 
    204           rd1 = random.RandomDistribution(rng=random.NumpyRNG(seed=98765), 
    205                                            distribution='uniform', 
    206                                            parameters=[0.9,1.1]) 
    207           rd2 = random.RandomDistribution(rng=random.NumpyRNG(seed=98765), 
    208                                            distribution='uniform', 
    209                                            parameters=[0.9,1.1]) 
    210           self.popul1.rset('cm',rd1) 
    211           output_values = numpy.zeros((3,3),numpy.float) 
    212           for i in 0,1,2: 
    213               for j in 0,1,2:     
    214                   output_values[i,j] = 1e9*pcsim_globals.net.object(self.popul1.getObjectID(self.popul1[i,j])).Cm 
    215           input_values = rd2.next(9) 
    216           output_values = output_values.reshape((9,)) 
    217           for i in range(9): 
    218               self.assertAlmostEqual(input_values[i],output_values[i],places=5) 
    219            
    220      def testRSetNative2(self): 
    221           """Population.rset(): with native rng.""" 
    222           rd1 = random.RandomDistribution(rng=NativeRNG(seed=98765), 
    223                                            distribution='Uniform', 
    224                                            parameters=[0.9,1.1]) 
    225           rd2 = random.RandomDistribution(rng=NativeRNG(seed=98765), 
    226                                            distribution='Uniform', 
    227                                            parameters=[0.9,1.1]) 
    228           self.popul1.rset('cm', rd1) 
    229           output_values_1 = numpy.zeros((3,3),numpy.float) 
    230           output_values_2 = numpy.zeros((3,3),numpy.float) 
    231           for i in 0,1,2: 
    232               for j in 0,1,2: 
    233                   output_values_1[i,j] = pcsim_globals.net.object(self.popul1.getObjectID(self.popul1[i,j])).Cm 
    234                    
    235           self.popul1.rset('cm', rd2) 
    236           for i in 0,1,2: 
    237               for j in 0,1,2: 
    238                   output_values_2[i,j] = pcsim_globals.net.object(self.popul1.getObjectID(self.popul1[i,j])).Cm 
    239  
    240           output_values_1 = output_values_1.reshape((9,)) 
    241           output_values_2 = output_values_2.reshape((9,)) 
    242           for i in range(9): 
    243               self.assertAlmostEqual(output_values_1[i],output_values_2[i],places=5)     
     233                 output_values_1[i,j] = pcsim_globals.net.object(self.popul1.getObjectID(self.popul1[i,j])).Cm 
     234                  
     235         self.popul1.rset('cm', rd2) 
     236         for i in 0,1,2: 
     237             for j in 0,1,2: 
     238                 output_values_2[i,j] = pcsim_globals.net.object(self.popul1.getObjectID(self.popul1[i,j])).Cm 
     239 
     240         output_values_1 = output_values_1.reshape((9,)) 
     241         output_values_2 = output_values_2.reshape((9,)) 
     242         for i in range(9): 
     243             self.assertAlmostEqual(output_values_1[i],output_values_2[i],places=5)     
    244244         
    245245# ============================================================================== 
    246246class PopulationCallTest(unittest.TestCase): # to write later 
    247     """Tests of the _call() and _tcall() methods of the Population class.""" 
    248     pass 
     247    """Tests of the _call() and _tcall() methods of the Population class.""" 
     248    pass 
    249249 
    250250 # ============================================================================== 
    251251class PopulationRecordTest(unittest.TestCase): # to write later 
    252     """Tests of the record(), record_v(), printSpikes(), print_v() and 
    253         meanSpikeCount() methods of the Population class.""" 
    254      
    255     def setUp(self): 
    256         Population.nPop = 0 
    257         self.popul = Population((3,3),IF_curr_alpha) 
    258          
    259     def tearDown(self):          
    260         end() 
    261          
    262     def testRecordAll(self): 
    263         """Population.record(): not a full test, just checking there are no Exceptions raised.""" 
    264         self.popul.record() 
    265          
    266     def testRecordInt(self): 
    267         """Population.record(n): not a full test, just checking there are no Exceptions raised.""" 
    268         self.popul.record(5) 
    269          
    270     def testRecordWithRNG(self): 
    271         """Population.record(n,rng): not a full test, just checking there are no Exceptions raised.""" 
    272         # self.popul.record(5,random.NumpyRNG()) 
    273          
    274     def testRecordList(self): 
    275         """Population.record(list): not a full test, just checking there are no Exceptions raised.""" 
    276         self.popul.record([self.popul[(2,2)],self.popul[(1,2)],self.popul[(0,0)]]) 
     252    """Tests of the record(), record_v(), printSpikes(), print_v() and 
     253       meanSpikeCount() methods of the Population class.""" 
     254     
     255    def setUp(self): 
     256        Population.nPop = 0 
     257        self.popul = Population((3,3),IF_curr_alpha) 
     258         
     259    def tearDown(self):          
     260        end() 
     261         
     262    def testRecordAll(self): 
     263        """Population.record(): not a full test, just checking there are no Exceptions raised.""" 
     264        self.popul.record() 
     265         
     266    def testRecordInt(self): 
     267        """Population.record(n): not a full test, just checking there are no Exceptions raised.""" 
     268        self.popul.record(5) 
     269         
     270    def testRecordWithRNG(self): 
     271        """Population.record(n,rng): not a full test, just checking there are no Exceptions raised.""" 
     272        # self.popul.record(5,random.NumpyRNG()) 
     273         
     274    def testRecordList(self): 
     275        """Population.record(list): not a full test, just checking there are no Exceptions raised.""" 
     276        self.popul.record([self.popul[(2,2)],self.popul[(1,2)],self.popul[(0,0)]]) 
    277277 
    278278 # ============================================================================== 
    279279class PopulationOtherTest(unittest.TestCase): # to write later 
    280     """Tests of the randomInit() method of the Population class.""" 
    281     pass 
     280    """Tests of the randomInit() method of the Population class.""" 
     281    pass 
    282282 
    283283# ============================================================================== 
    284284class ProjectionInitTest(unittest.TestCase): 
    285      """Tests of the __init__() method of the Projection class.""" 
     285    """Tests of the __init__() method of the Projection class.""" 
     286         
     287    def setUp(self): 
     288        Population.nPop = 0 
     289        # Projection.nProj = 0 
     290        self.target33    = Population((3,3),IF_curr_alpha) 
     291        self.target6     = Population((6,),IF_curr_alpha) 
     292        self.source5     = Population((5,),SpikeSourcePoisson) 
     293        self.source22    = Population((2,2),SpikeSourcePoisson) 
     294        self.source33    = Population((3,3),SpikeSourcePoisson) 
     295        self.expoisson33 = Population((3,3),SpikeSourcePoisson,{'rate': 100}) 
     296         
     297    def testAllToAll(self): 
     298        """For all connections created with "allToAll" it should be possible to obtain the weight using pyneuron.getWeight()""" 
     299        for srcP in [self.source5, self.source22]: 
     300            for tgtP in [self.target6, self.target33]: 
     301                prj1 = Projection(srcP, tgtP, 'allToAll') 
     302                prj2 = Projection(srcP, tgtP, AllToAllConnector()) 
     303                for prj in prj1, prj2: 
     304                   prj.setWeights(1.234) 
     305                   weights = [] 
     306                   for i in range(len(prj)): 
     307                       weights.append(pcsim_globals.net.object(prj.pcsim_projection[i]).W) 
     308                   for w in weights: 
     309                       self.assertAlmostEqual(w,1.234*1e-9, places = 7) 
    286310          
    287      def setUp(self): 
    288          Population.nPop = 0 
    289          # Projection.nProj = 0 
    290          self.target33    = Population((3,3),IF_curr_alpha) 
    291          self.target6     = Population((6,),IF_curr_alpha) 
    292          self.source5     = Population((5,),SpikeSourcePoisson) 
    293          self.source22    = Population((2,2),SpikeSourcePoisson) 
    294          self.source33    = Population((3,3),SpikeSourcePoisson) 
    295     &n