Changeset 367

Show
Ignore:
Timestamp:
06/17/08 17:44:22 (5 months ago)
Author:
apdavison
Message:

More work on neuron2

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/src/common.py

    r366 r367  
    1111from math import * 
    1212from pyNN import random 
     13 
     14DEFAULT_WEIGHT = 0.0 
    1315 
    1416class InvalidParameterValueError(Exception): pass 
  • trunk/src/neuron/__init__.py

    r366 r367  
    307307    def record(self, ids): 
    308308        """Add the cells in `ids` to the set of recorded cells.""" 
    309         ids = Set([id for id in ids if id in self.population.gidlist]) 
     309        if self.population: 
     310            ids = Set([id for id in ids if id in self.population.gidlist]) 
     311        else: 
     312            ids = Set(ids) # what about non-local cells? 
    310313        new_ids = list( ids.difference(self.recorded) ) 
    311314        self.recorded = self.recorded.union(ids) 
     
    397400                write_data() 
    398401        else: 
    399             filename += ".%d" % myid     
     402            self.filename += ".%d" % myid     
    400403            write_data() 
    401404                 
  • trunk/src/neuron2/__init__.py

    r366 r367  
    3737    simulator but not by others. 
    3838    """ 
    39     global initialised, quit_on_end, running, pc 
     39    global initialised, quit_on_end, running, parallel_context 
    4040    if not initialised: 
    4141        h('min_delay = 0') 
    4242        h('tstop = 0') 
    43         pc = neuron.ParallelContext() 
    44         pc.spike_compress(1,0) 
     43        parallel_context = neuron.ParallelContext() 
     44        parallel_context.spike_compress(1,0) 
    4545        cvode = neuron.CVode() 
    4646        utility.init_logging("neuron2.log.%d" % rank(), debug) 
     
    6060    for recorder in recorder_list: 
    6161        recorder.write(gather=False, compatible_output=compatible_output) 
    62     pc.runworker() 
    63     pc.done() 
     62    parallel_context.runworker() 
     63    parallel_context.done() 
    6464    if quit_on_end: 
    6565        logging.info("Finishing up with NEURON.") 
     
    7272    if not running: 
    7373        running = True 
    74         local_minimum_delay = pc.set_maxstep(10) 
     74        local_minimum_delay = parallel_context.set_maxstep(10) 
    7575        h.finitialize() 
    7676        h.tstop = 0 
     
    8080                   "There are connections with delays (%g) shorter than the minimum delay (%g)" % (local_minimum_delay, get_min_delay()) 
    8181    h.tstop = simtime 
    82     pc.psolve(h.tstop) 
     82    parallel_context.psolve(h.tstop) 
    8383    return get_current_time() 
    8484 
     
    100100 
    101101def num_processes(): 
    102     return int(pc.nhost()) 
     102    return int(parallel_context.nhost()) 
    103103 
    104104def rank(): 
    105105    """Return the MPI rank.""" 
    106     return int(pc.id()) 
     106    return int(parallel_context.id()) 
    107107 
    108108def list_standard_models(): 
     
    118118        gid = int(self) 
    119119        self._cell = celltype.model(**celltype.parameters)  # create the cell object 
    120         pc.set_gid2node(gid, rank())                        # assign the gid to this node 
     120        parallel_context.set_gid2node(gid, rank())                        # assign the gid to this node 
    121121        nc = neuron.NetCon(self._cell.source, None)         # } associate the cell spike source 
    122         pc.cell(gid, nc.hoc_obj)                            # } with the gid (using a temporary NetCon) 
     122        parallel_context.cell(gid, nc.hoc_obj)                            # } with the gid (using a temporary NetCon) 
    123123        self.parent = parent 
    124124     
    125125    def get_native_parameters(self): 
    126126        D = {} 
    127         for name in ('tau_m', 'cm', 'v_rest', 'v_thresh', 't_refrac', 
    128                      'i_offset', 'v_reset', 'v_init', 'tau_e', 'tau_i'): 
     127        for name in self._cell.parameter_names: 
    129128            D[name] = getattr(self._cell, name) 
    130129        return D 
     
    138137#   Low-level API for creating, connecting and recording from individual neurons 
    139138# ============================================================================== 
     139 
     140def _create(celltype, n, parent=None): 
     141    """ 
     142    Function used by both `create()` and `Population.__init__()` 
     143    """ 
     144    global gid_counter 
     145    assert n > 0, 'n must be a positive integer' 
     146    first_id = gid_counter 
     147    last_id = gid_counter + n 
     148    all_ids = numpy.array([id for id in range(first_id, last_id)], ID) 
     149    # mask_local is used to extract those elements from arrays that apply to the cells on the current node 
     150    mask_local = all_ids%num_processes()==0 # round-robin distribution of cells between nodes 
     151    for i,(id,is_local) in enumerate(zip(all_ids, mask_local)): 
     152        if is_local: 
     153            all_ids[i] = ID(id) 
     154            all_ids[i]._build_cell(celltype, parent=parent) 
     155    gid_counter += n 
     156    return all_ids, mask_local, first_id, last_id 
     157 
     158def create(cellclass, param_dict=None, n=1): 
     159    """ 
     160    Create n cells all of the same type. 
     161    If n > 1, return a list of cell ids/references. 
     162    If n==1, return just the single id. 
     163    """ 
     164    all_ids, mask_local, first_id, last_id = _create(cellclass(param_dict), n) 
     165    for id in all_ids[mask_local]: 
     166        id.cellclass = cellclass 
     167    if len(all_ids) == 1: 
     168        all_ids = all_ids[0] 
     169    return all_ids 
     170 
     171def _single_connect(source, target, weight, delay, synapse_type): 
     172    """ 
     173    Private function to connect two neurons. 
     174    Used by `connect()` and the `Connector` classes. 
     175    """ 
     176    if synapse_type is None: 
     177        synapse_type = weight>=0 and 'excitatory' or 'inhibitory' 
     178    if weight is None: 
     179        weight = common.DEFAULT_WEIGHT 
     180    if "cond" in target.cellclass.__name__: 
     181        weight = abs(weight) # weights must be positive for conductance-based synapses 
     182    elif synapse_type == 'inhibitory' and weight > 0: 
     183        weight *= -1         # and negative for inhibitory, current-based synapses 
     184    if delay is None: 
     185        delay = get_min_delay() 
     186    elif delay < get_min_delay(): 
     187        raise common.ConnectionError("delay (%s) is too small (< %s)" % (delay, get_min_delay())) 
     188    synapse_object = getattr(target._cell, synapse_type).hoc_obj 
     189    nc = parallel_context.gid_connect(int(source), synapse_object) 
     190    nc.weight[0] = weight 
     191    nc.delay  = delay 
     192    return nc 
     193 
     194def connect(source, target, weight=None, delay=None, synapse_type=None, p=1, rng=None): 
     195    """Connect a source of spikes to a synaptic target. source and target can 
     196    both be individual cells or lists of cells, in which case all possible 
     197    connections are made with probability p, using either the random number 
     198    generator supplied, or the default rng otherwise. 
     199    Weights should be in nA or µS.""" 
     200    logging.debug("connecting %s to %s on host %d" % (source, target, rank())) 
     201    if not common.is_listlike(source): 
     202        source = [source] 
     203    if not common.is_listlike(target): 
     204        target = [target] 
     205    if p < 1: 
     206        rng = rng or numpy.random 
     207    connection_list = [] 
     208    for tgt in target: 
     209        sources = numpy.array(source) 
     210        if p < 1: 
     211            rarr = rng.uniform(0, 1, len(source)) 
     212            sources = sources[rarr<p] 
     213        for src in sources: 
     214            nc = _single_connect(src, tgt, weight, delay, synapse_type) 
     215            connection_list.append((src, tgt, nc)) 
     216    return connection_list 
     217 
     218def set(cells, param, val=None): 
     219    """Set one or more parameters of an individual cell or list of cells. 
     220    param can be a dict, in which case val should not be supplied, or a string 
     221    giving the parameter name, in which case val is the parameter value. 
     222    """ 
     223    if val: 
     224        param = {param:val} 
     225    if not hasattr(cells, '__len__'): 
     226        cells = [cells] 
     227    # see comment in Population.set() below about the efficiency of the 
     228    # following 
     229    for cell in cells: 
     230        cell.set_parameters(**param) 
     231 
     232def record(source, filename): 
     233    """Record spikes to a file. source can be an individual cell or a list of 
     234    cells.""" 
     235    # would actually like to be able to record to an array and choose later 
     236    # whether to write to a file. 
     237    if not hasattr(source, '__len__'): 
     238        source = [source] 
     239    recorder = Recorder('spikes', file=filename) 
     240    recorder.record(source) 
     241    recorder_list.append(recorder) 
     242 
     243def record_v(source, filename): 
     244    """ 
     245    Record membrane potential to a file. source can be an individual cell or 
     246    a list of cells.""" 
     247    # would actually like to be able to record to an array and 
     248    # choose later whether to write to a file. 
     249    if not hasattr(source, '__len__'): 
     250        source = [source] 
     251    recorder = Recorder('v', file=filename) 
     252    recorder.record(source) 
     253    recorder_list.append(recorder) 
    140254 
    141255# ============================================================================== 
     
    167281        label is an optional name for the population. 
    168282        """ 
    169         global gid_counter 
     283        ##global gid_counter 
    170284        common.Population.__init__(self, dims, cellclass, cellparams, label) 
    171285        self.recorders = {'spikes': Recorder('spikes', population=self), 
    172286                          'v': Recorder('v', population=self)} 
    173         self.first_id = gid_counter 
    174         self.last_id = gid_counter + self.size 
     287        ##self.first_id = gid_counter 
     288        ##self.last_id = gid_counter + self.size 
    175289        self.label = self.label or 'population%d' % Population.nPop 
     290        self.celltype = cellclass(cellparams) 
    176291         
    177292        # Build the arrays of cell ids 
     
    179294        # All are stored in a single numpy array for easy lookup by address 
    180295        # The local cells are also stored in a list, for easy iteration 
    181         self._all_ids = numpy.array([id for id in range(self.first_id, self.last_id)], ID) #.reshape(self.dim) 
    182         # _mask_local is used to extract those elements from arrays that apply to the cells on the current node, e.g. for tset(
    183         self._mask_local = self._all_ids%num_processes()==0 # round-robin distribution of cells between nodes 
    184         ## _map_local is used to map addresses to the index within the list of local cells 
    185         #self._map_local = numpy.where(self._mask_local, self._all_ids/int(num_processes()), None) 
    186         for i,(id,is_local) in enumerate(zip(self._all_ids, self._mask_local)): 
    187             if is_local: 
    188                 self._all_ids[i] = ID(id) 
     296         
     297        self._all_ids, self._mask_local, self.first_id, self.last_id = _create(self.celltype, self.size, parent=self
     298        ##self._all_ids = numpy.array([id for id in range(self.first_id, self.last_id)], ID) #.reshape(self.dim) 
     299        ### _mask_local is used to extract those elements from arrays that apply to the cells on the current node, e.g. for tset() 
     300        ##self._mask_local = self._all_ids%num_processes()==0 # round-robin distribution of cells between nodes 
     301        ##for i,(id,is_local) in enumerate(zip(self._all_ids, self._mask_local)): 
     302        ##    if is_local: 
     303        ##        self._all_ids[i] = ID(id) 
    189304        # _local_ids is a list containing only those cells that exist on the current node 
    190305        self._local_ids = self._all_ids[self._mask_local] 
     
    192307        self._mask_local = self._mask_local.reshape(self.dim) 
    193308         
    194         self.celltype = cellclass(cellparams) 
    195         for id in self._local_ids: 
    196             id._build_cell(self.celltype, parent=self) 
    197         gid_counter += self.size 
     309         
     310        ##for id in self._local_ids: 
     311        ##    id._build_cell(self.celltype, parent=self) 
     312        #gid_counter += self.size 
    198313        Population.nPop += 1 
    199314        logging.info(self.describe('Creating Population "%(label)s" of shape %(dim)s, '+ 
     
    352467            fixed_list=True 
    353468        elif record_from is None: # record from all cells: 
    354             record_from = self._all_ids 
     469            record_from = self._all_ids.flatten() 
    355470        elif isinstance(record_from, int): # record from a number of cells, selected at random   
    356471            # Each node will record N/nhost cells... 
     
    358473            if not rng: 
    359474                rng = numpy.random 
    360             record_from = rng.permutation(self._all_ids)[0:nrec] 
     475            record_from = rng.permutation(self._all_ids.flatten())[0:nrec] 
    361476            # need ID objects, permutation returns integers 
    362477            # ??? 
     
    365480        # record_from is now a list or numpy array. We do not have to worry about whether the cells are 
    366481        # local because the Recorder object takes care of this. 
     482        logging.info("%s.record('%s', %s)", self.label, record_what, record_from[:5]) 
    367483        self.recorders[record_what].record(record_from) 
    368484 
  • trunk/src/neuron2/cells.py

    r366 r367  
    5959        self.esyn = synapse_model(self, 0.5) 
    6060        self.isyn = synapse_model(self, 0.5) 
     61        self.excitatory = self.esyn # } aliases 
     62        self.inhibitory = self.isyn # } 
    6163 
    6264        # insert current source 
     
    6971         
    7072        # process arguments 
    71         for name in ('tau_m', 'cm', 'v_rest', 'v_thresh', 't_refrac', 
    72                      'i_offset', 'v_reset', 'v_init', 'tau_e', 'tau_i'): 
     73        self.parameter_names = ['tau_m', 'cm', 'v_rest', 'v_thresh', 't_refrac', 
     74                                'i_offset', 'v_reset', 'v_init', 'tau_e', 'tau_i'] 
     75        if syn_type == 'conductance': 
     76            self.parameter_names.extend(['e_e', 'e_i']) 
     77        for name in self.parameter_names: 
    7378            setattr(self, name, locals()[name]) 
    7479        if self.v_reset is None: 
     
    7681        if self.v_init is None: 
    7782            self.v_init = self.v_rest 
    78         if syn_type == 'conductance': 
    79             self.e_e = e_e 
    80             self.e_i = e_i 
    8183             
    8284        # need to deal with FinitializeHandler for v_init? 
    83         #self.fih = neuron.FInitializeHandler("memb_init()", obj=self) 
    84         #self.fih2 = neuron.FInitializeHandler('print "kjyuyv"', obj=self) 
     85        self.fih = neuron.h.FInitializeHandler("memb_init()", self) 
     86        self.fih2 = neuron.h.FInitializeHandler('print "kjyuyv"') 
     87        self.spiketimes = neuron.Vector(0) 
     88        self.fih.allprint() 
    8589 
    8690    def __set_tau_m(self, value): 
     
    107111        if active: 
    108112            rec = neuron.NetCon(self.source, None) 
    109             rec.record(self.spiketimes
     113            rec.record(self.spiketimes.hoc_obj
    110114     
    111115    def record_v(self, active): 
     
    113117            self.vtrace = neuron.Vector() 
    114118            self.vtrace.record(self, 'v') 
     119            self.record_times = neuron.Vector() 
     120            neuron.h('%s.record(&t)' % self.record_times.name) 
    115121        else: 
    116122            self.vtrace = None 
     123            self.record_times 
    117124     
    118125    def memb_init(self, v_init=None): 
     126        print "memb_init() called" 
    119127        if v_init: 
    120128            self.v_init = v_init 
     
    209217        ('e_rev_I',    'e_i') 
    210218    ) 
    211     hoc_name = "StandardIF" 
     219    model = StandardIF 
    212220     
    213221    def __init__(self, parameters): 
    214222        common.IF_cond_alpha.__init__(self, parameters) # checks supplied parameters and adds default 
    215223                                                       # values for not-specified parameters. 
    216         self.parameters = self.translate(self.parameters) 
    217224        self.parameters['syn_type']  = 'conductance' 
    218225        self.parameters['syn_shape'] = 'alpha' 
     
    237244        ('e_rev_I',    'e_i') 
    238245    ) 
    239     hoc_name = "StandardIF" 
     246    model = StandardIF 
    240247     
    241248    def __init__(self, parameters): 
    242249        common.IF_cond_exp.__init__(self, parameters) # checks supplied parameters and adds default 
    243250                                                       # values for not-specified parameters. 
    244         self.parameters = self.translate(self.parameters) 
    245251        self.parameters['syn_type']  = 'conductance' 
    246252        self.parameters['syn_shape'] = 'exp' 
     
    266272        ('e_rev_I',    'e_i'), 
    267273    ) # v_init? 
    268     hoc_name = "StandardIF" 
     274    model = StandardIF 
    269275 
    270276    def __init__(self, parameters): 
    271277        common.IF_facets_hardware1.__init__(self, parameters) 
    272         self.parameters = self.translate(self.parameters) 
    273278        self.parameters['syn_type']  = 'conductance' 
    274279        self.parameters['syn_shape'] = 'exp' 
     
    284289        ('duration', 'number',    "int(rate/1000.0*duration)", "number*interval"), # should there be a +/1 here? 
    285290    ) 
    286     hoc_name = 'SpikeSource' 
    287     
     291    model = SpikeSource 
     292     
    288293    def __init__(self, parameters): 
    289294        common.SpikeSourcePoisson.__init__(self, parameters) 
    290         self.parameters = self.translate(self.parameters) 
    291295        self.parameters['source_type'] = 'NetStim'     
    292296        self.parameters['noise'] = 1 
     
    299303        ('spike_times', 'spiketimes'), 
    300304    ) 
    301     #hoc_name = 'SpikeSource' 
     305    model = SpikeSource 
    302306     
    303307    def __init__(self, parameters): 
    304308        common.SpikeSourceArray.__init__(self, parameters) 
    305         self.parameters = self.translate(self.parameters)   
    306         #self.parameters['source_type'] = 'VecStim' 
    307         SpikeSource.__init__(self, source_type=VecStim, spiketimes=self.parameters['spiketimes']) 
     309        self.parameters['source_type'] = VecStim 
     310        #SpikeSource.__init__(self, source_type=VecStim, spiketimes=self.parameters['spiketimes']) 
    308311         
    309312         
     
    343346    def __init__(self, parameters): 
    344347        common.EIF_cond_alpha_isfa_ista.__init__(self, parameters) 
    345         self.parameters = self.translate(self.parameters) 
    346348        self.parameters['syn_type']  = 'conductance' 
    347349        self.parameters['syn_shape'] = 'alpha' 
  • trunk/src/neuron2/connectors.py

    r275 r367  
    11# ============================================================================== 
    22# Connection method classes for neuron 
    3 # $Id: connectors.py 191 2008-01-29 10:36:00Z apdavison $ 
     3# $Id: connectors.py 361 2008-06-12 16:17:59Z apdavison $ 
    44# ============================================================================== 
    55 
    66from pyNN import common 
    77from pyNN.random import RandomDistribution, NativeRNG 
     8from pyNN.neuron.__init__ import hoc_execute, h, get_min_delay 
    89import numpy 
    910from math import * 
     11 
     12common.get_min_delay = get_min_delay 
    1013 
    1114# ============================================================================== 
     
    1922        Write hoc commands to connect a single pair of neurons. 
    2023        """ 
     24        if "cond" in tgt.cellclass.__name__: 
     25            weight = abs(weight) # Weights must be positive for conductance-based synapses 
    2126        cmdlist = ['nc = pc.gid_connect(%d,%s.object(%d).%s)' % (src, 
    2227                                                                 projection.post.hoc_label, 
    2328                                                                 projection.post.gidlist.index(tgt), 
    2429                                                                 projection._syn_objref), 
    25                 'nc.weight = %f' %weight, 
    26                 'nc.delay  = %f' %delay, 
     30                'nc.weight = %f' % weight, 
     31                'nc.delay  = %f' % delay, 
    2732                'tmp = %s.append(nc)' % projection.hoc_label] 
    2833        projection.connections.append((src, tgt)) 
     
    3035     
    3136    def getWeight(self, w): 
    32         if w is not None:  
    33             weight = w 
     37        if w is not None: 
     38            if hasattr(w, '__len__'): # d is an array 
     39                weight = w.__iter__() 
     40            else: 
     41                weight = w 
    3442        else:  
    3543            weight = 1. 
     
    3846    def getDelay(self, d): 
    3947        if d is not None: 
    40             delay = d 
    41         else: 
    42             delay = _min_delay 
     48            if hasattr(d, '__len__'): # d is an array 
     49                delay = d.__iter__() 
     50            else: 
     51                delay = max((d, get_min_delay())) 
     52        else: 
     53            delay = get_min_delay() 
    4354        return delay 
    4455 
     56    def _process_conn_list(self, conn_list, projection): 
     57        """Extract fields from list of tuples and construct the hoc commands.""" 
     58        hoc_commands = [] 
     59        for i in xrange(len(conn_list)): 
     60            src, tgt, weight, delay = conn_list[i][:] 
     61            src = projection.pre[tuple(src)] 
     62            tgt = projection.post[tuple(tgt)] 
     63            hoc_commands += self.singleConnect(projection, src, tgt, weight, delay) 
     64        return hoc_commands 
     65 
     66 
    4567class AllToAllConnector(common.AllToAllConnector, HocConnector):     
    4668     
    4769    def connect(self, projection): 
    4870        weight = self.getWeight(self.weights) 
    49         delay = self.getWeight(self.delays) 
    50         hoc_commands = [] 
    51         for tgt in projection.post.gidlist: 
    52             for src in projection.pre.fullgidlist: 
     71        delay = self.getDelay(self.delays) 
     72        hoc_commands = [] 
     73        for src in projection.pre.fullgidlist: 
     74            for tgt in projection.post.gidlist:     
    5375                if self.allow_self_connections or projection.pre != projection.post or tgt != src: 
    54                     if isinstance(weight, RandomDistribution): w = weight.next() 
    55                     else: w = weight 
    56                     if isinstance(delay, RandomDistribution): d = delay.next() 
    57                     else: d = delay 
     76                    if hasattr(weight, 'next'): 
     77                        w = weight.next() 
     78                    else: 
     79                        w = weight 
     80                    if hasattr(delay, 'next'): 
     81                        d = delay.next() 
     82                    else: 
     83                        d = delay 
     84                    #print "Setting connection delay from %s to %s in %s to %g" % (src, tgt, projection.label, d) 
    5885                    hoc_commands += self.singleConnect(projection, src, tgt, w, d) 
    5986        return hoc_commands 
    6087 
     88 
    6189class OneToOneConnector(common.OneToOneConnector, HocConnector): 
    6290     
    6391    def connect(self, projection): 
    6492        weight = self.getWeight(self.weights) 
    65         delay = self.getWeight(self.delays) 
     93        delay = self.getDelay(self.delays) 
    6694        if projection.pre.dim == projection.post.dim: 
    6795            hoc_commands = [] 
    6896            for tgt in projection.post.gidlist: 
    6997                src = tgt - projection.post.gid_start + projection.pre.gid_start 
    70                 if isinstance(weight, RandomDistribution): w = weight.next() 
    71                 else: w = weight 
    72                 if isinstance(delay, RandomDistribution): d = delay.next() 
    73                 else: d = delay 
     98                if hasattr(weight, 'next'): 
     99                    w = weight.next() 
     100                else: 
     101                    w = weight 
     102                if hasattr(delay, 'next'): 
     103                    d = delay.next() 
     104                else: 
     105                    d = delay 
    74106                hoc_commands += self.singleConnect(projection, src, tgt, w, d) 
    75107        else: 
    76             raise Exception("Method '%s' not yet implemented for the case where presynaptic and postsynaptic Populations have different sizes." % sys._getframe().f_code.co_name) 
    77         return hoc_commands 
     108            raise Exception("OneToOneConnector does not support presynaptic and postsynaptic Populations of different sizes.") 
     109        return hoc_commands 
     110 
    78111 
    79112class FixedProbabilityConnector(common.FixedProbabilityConnector, HocConnector): 
     
    81114    def connect(self, projection): 
    82115        weight = self.getWeight(self.weights) 
    83         delay = self.getWeight(self.delays) 
     116        delay = self.getDelay(self.delays) 
    84117        if isinstance(projection.rng, NativeRNG): 
    85118            hoc_commands = ['rng = new Random(%d)' % 0 or distribution.rng.seed, 
     
    88121            # catch the connections from NEURON 
    89122            hoc_execute(hoc_commands) 
    90             rarr = [HocToPy.get('rng.repick()','float') for j in xrange(projection.pre.size*projection.post.size)]         
    91         else: 
    92             rarr = projection.rng.uniform(0,1, projection.pre.size*projection.post.size) 
    93         hoc_commands = [] 
    94         j = 0         
    95         for tgt in projection.post.gidlist: 
    96             for src in projection.pre.fullgidlist: 
     123            #rarr = [HocToPy.get('rng.repick()','float') for j in xrange(projection.pre.size*projection.post.size)] 
     124            rarr = [h.rng.repick() for j in xrange(projection.pre.size*projection.post.size)] 
     125        else: 
     126            # We use concatenate, rather than just creating 
     127            # n=projection.pre.size*projection.post.size random numbers, 
     128            # in case of uneven distribution of neurons between MPI nodes 
     129            rarr = numpy.concatenate([projection.rng.next(projection.post.size, 'uniform', (0,1)) \ 
     130                                      for src in projection.pre.fullgidlist]) 
     131        hoc_commands = [] 
     132        j = 0 
     133        required_rarr_length = len(projection.pre.fullgidlist) * len(projection.post.gidlist) 
     134        assert len(rarr) >= required_rarr_length, \ 
     135               "Random array is too short (%d elements, needs %d)" % (len(rarr), required_rarr_length) 
     136        for src in projection.pre.fullgidlist: 
     137            for tgt in projection.post.gidlist: 
    97138                if self.allow_self_connections or projection.pre != projection.post or tgt != src: 
    98139                    if rarr[j] < self.p_connect:   
    99                         if isinstance(weight, RandomDistribution): w = weight.next() 
    100                         else: w = weight 
    101                         if isinstance(delay, RandomDistribution): d = delay.next() 
    102                         else: d = delay 
    103                         hoc_commands += self.singleConnect(projection, src, tgt, w, d) 
     140                        if hasattr(weight, 'next'): 
     141                            w = weight.next() 
     142                        else: 
     143                            w = weight 
     144                        if hasattr(delay, 'next'): 
     145                            d = delay.next() 
     146                        else: 
     147                            d = delay 
     148                        hoc_commands += self.singleConnect(projection, src, tgt, w, d)  
    104149                j += 1 
    105150        return hoc_commands 
    106151 
     152 
    107153class DistanceDependentProbabilityConnector(common.DistanceDependentProbabilityConnector, HocConnector): 
    108154     
    109155    def connect(self, projection): 
    110156        weight = self.getWeight(self.weights) 
    111         delay = self.getWeight(self.delays) 
     157        delay = self.getDelay(self.delays) 
    112158        periodic_boundaries = self.periodic_boundaries 
    113159        if periodic_boundaries is not None: 
     
    120166            # catch the connections from NEURON 
    121167            hoc_execute(hoc_commands) 
    122             rarr = [HocToPy.get('rng.repick()','float') for j in xrange(projection.pre.size*projection.post.size)]         
     168            #rarr = [HocToPy.get('rng.repick()','float') for j in xrange(projection.pre.size*projection.post.size)] 
     169            rarr = [h.rng.repick() for j in xrange(projection.pre.size*projection.post.size)] 
    123170        else: 
    124171            rarr = projection.rng.uniform(0,1, projection.pre.size*projection.post.size) 
     
    135182                    p = eval(self.d_expression) 
    136183                    if p >= 1 or (0 < p < 1 and rarr[j] < p): 
    137                         if isinstance(weight, RandomDistribution): w = weight.next() 
    138                         else: w = weight 
    139                         if isinstance(delay, RandomDistribution): d = delay.next() 
    140                         else: d = delay 
     184                        if hasattr(weight, 'next'): 
     185                            w = weight.next() 
     186                        else: 
     187                            w = weight 
     188                        if hasattr(delay, 'next'): 
     189                            d = delay.next() 
     190                        else: 
     191                            d = delay 
    141192                        hoc_commands += self.singleConnect(projection, src, tgt, w, d) 
    142193                j += 1 
     
    144195        return hoc_commands 
    145196 
    146  
    147 class FixedNumberPreConnector(common.FixedNumberPreConnector): 
    148      
    149     def connect(self, projection): 
    150         raise Exception("Not implemented yet !") 
    151  
    152  
    153 class FixedNumberPostConnector(common.FixedNumberPostConnector): 
    154      
    155     def connect(self, projection): 
    156         raise Exception("Not implemented yet !") 
     197class _FixedNumberConnector(common.FixedNumberPreConnector, HocConnector): 
     198     
     199    def _connect(self, projection, x_list, y_list, type): 
     200        weight = self.getWeight(self.weights) 
     201        delay = self.getDelay(self.delays) 
     202        hoc_commands = [] 
     203         
     204        if projection.rng: 
     205            if isinstance(projection.rng, NativeRNG): 
     206                raise Exception("NativeRNG not yet supported for the FixedNumberPreConnector") 
     207            rng = projection.rng 
     208        else: 
     209            rng = numpy.random 
     210        for y in y_list:             
     211            # pick n neurons at random 
     212            if hasattr(self, 'rand_distr'): 
     213                n = self.rand_distr.next() 
     214            elif hasattr(self, 'n'): 
     215                n = self.n 
     216            candidates = x_list 
     217            xs = [] 
     218            while len(xs) < n: # if the number of requested cells is larger than the size of the 
     219                                    # presynaptic population, we allow multiple connections for a given cell 
     220                xs += [candidates[candidates.index(id)] for id in rng.permutation(candidates)[0:n]] 
     221                # have to use index() because rng.permutation returns ints, not ID objects 
     222            xs = xs[:n] 
     223            for x in xs: 
     224                if self.allow_self_connections or (x != y): 
     225                    if hasattr(weight, 'next'): 
     226                        w = weight.next() 
     227                    else: 
     228                        w = weight 
     229                    if hasattr(delay, 'next'): 
     230                        d = delay.next() 
     231                    else: 
     232                        d = delay 
     233                    if type == 'pre': 
     234                        hoc_commands += self.singleConnect(projection, x, y, w, d) 
     235                    elif type == 'post': 
     236                        hoc_commands += self.singleConnect(projection, y, x, w, d) 
     237                    else: 
     238                        raise Exception('Problem in _FixedNumberConnector') 
     239        return hoc_commands 
     240 
     241 
     242class FixedNumberPreConnector(_FixedNumberConnector): 
     243     
     244    def connect(self, projection): 
     245        return self._connect(projection, projection.pre.gidlist, projection.post.gidlist, 'pre') 
     246 
     247 
     248class FixedNumberPostConnector(_FixedNumberConnector): 
     249      
     250    def connect(self, projection): 
     251        return self._connect(projection, projection.post.gidlist, projection.pre.gidlist, 'post') 
     252 
     253 
     254class FromListConnector(common.FromListConnector, HocConnector): 
     255     
     256    def connect(self, projection): 
     257        return self._process_conn_list(self.conn_list, projection) 
     258 
     259     
     260class FromFileConnector(common.FromFileConnector, HocConnector): 
     261     
     262    def connect(self, projection): 
     263        if self.distributed: 
     264            myid = int(h.pc.id()) 
     265            self.filename += ".%d" % myid 
     266        # open the file... 
     267        f = open(self.filename, 'r', 10000) 
     268        lines = f.readlines() 
     269        f.close() 
     270        # gather all the data in a list of tuples (one per line) 
     271        input_tuples = [] 
     272        for line in lines: 
     273            single_line = line.rstrip() 
     274            src, tgt, w, d = single_line.split("\t", 4) 
     275            src = "[%s" % src.split("[",1)[1] 
     276            tgt = "[%s" % tgt.split("[",1)[1] 
     277            input_tuples.append((eval(src), eval(tgt), float(w), float(d))) 
     278        return self._process_conn_list(input_tuples, projection) 
  • trunk/src/neuron2/utility.py

    r366 r367  
    22import platform 
    33import logging 
     4import numpy 
    45import os.path 
    56import neuron 
     
    2526    """Encapsulates data and functions related to recording model variables.""" 
    2627     
     28    formats = {'spikes': "%g\t%d", 
     29               'v': "%g\t%g\t%d"} 
     30     
    2731    def __init__(self, variable, population=None, file=None): 
    2832        """ 
     
    4044        """Add the cells in `ids` to the set of recorded cells.""" 
    4145        logging.debug('Recorder.record(%s)', str(ids)) 
    42         ids = set([id for id in ids if id in self.population._local_ids]) 
     46        if self.population: 
     47            ids = set([id for id in ids if id in self.population._local_ids]) 
     48        else: 
     49            ids = set(ids) # how to decide if the cell is local? 
    4350        new_ids = list( ids.difference(self.recorded) ) 
    44         logging.info("%s.record('%s', %s)", self.population.label, self.variable, new_ids[:5]) 
     51         
    4552        self.recorded = self.recorded.union(ids) 
     53        logging.debug('Recorder.recorded = %s' % self.recorded) 
    4654        if self.variable == 'spikes': 
    47             for cell in new_ids: 
    48                 cell.record(1) 
     55            for id in new_ids: 
     56                id._cell.record(1) 
    4957        elif self.variable == 'v': 
    50             for cell in new_ids: 
    51                 cell.record_v(1) 
     58            for id in new_ids: 
     59                id._cell.record_v(1) 
    5260         
    5361    def get(self, gather=False): 
    5462        """Returns the recorded data.""" 
    55         pass 
     63        if self.variable == 'spikes': 
     64            data = numpy.empty((0,2)) 
     65            for id in self.recorded: 
     66                spikes = id._cell.spiketimes.toarray() 
     67                if len(spikes) > 0: 
     68                    new_data = numpy.array([spikes, numpy.ones(spikes.shape)*id]).T 
     69                    data = numpy.concatenate((data, new_data)) 
     70        elif self.variable == 'v': 
     71            data = numpy.empty((0,3)) 
     72            for id in self.recorded: 
     73                v = id._cell.vtrace.toarray() 
     74                t = id._cell.record_times.toarray() 
     75                new_data = numpy.array([t, v, numpy.ones(v.shape)*id]).T 
     76                data = numpy.concatenate((data, new_data)) 
     77        return data 
    5678     
    5779    def write(self, file=None, gather=False, compatible_output=True): 
    58         pass 
     80        data = self.get(gather) 
     81        numpy.savetxt(file or self.filename, data, Recorder.formats[self.variable]) 
     82         
     83class Initializer(object): 
     84     
     85    def __init__(self): 
     86        self.cell_list = [] 
     87        self.population_list = [] 
     88        neuron.h('objref initializer') 
     89        neuron.h('initializer = PythonObject(self)') 
     90     
     91    def initialize(self): 
     92        for cell in self.cell_list: 
     93            cell.memb_init() 
     94 
    5995 
    6096load_mechanisms()