Show
Ignore:
Timestamp:
03/12/10 01:26:31 (2 years ago)
Author:
pierre
Message:

Add a nice progress bar to all the new connectors in connectors2.py. Now, a verbose flag allows to display or not a progress bar indicating the percentage of connections established. Can be useful to know how long connections will take. Some minors ameliorations. Everything is now OK, some informal tests shows numbers of synapses are ok for all the connectors. The last point to test is to make sure distances are correct. Should be the case, but should be sure....

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/src/connectors2.py

    r728 r729  
    1 import numpy 
    2 from pyNN import errors, common, core, random 
     1import numpy, logging, sys 
     2from pyNN import errors, common, core, random, utility 
    33from pyNN.space import Space 
    44from pyNN.random import RandomDistribution 
     
    77                    sin, sinh, sqrt, tan, tanh, maximum, minimum 
    88 
     9logger = logging.getLogger("PyNN") 
     10 
    911class ConnectionAttributeGenerator(object): 
    1012     
     
    1315        self.local_mask = local_mask 
    1416        self.safe       = safe 
     17        if self.safe: 
     18            self.get = self.get_safe     
    1519        if isinstance(self.source, numpy.ndarray): 
    1620            self.source_iterator = iter(self.source) 
    1721     
    18     def get(self, N, distance_matrix=None, sub_mask=None): 
     22    def check(self, data): 
     23        return data 
     24         
     25    def extract(self, N, distance_matrix=None, sub_mask=None): 
    1926        if isinstance(self.source, basestring): 
    2027            assert distance_matrix is not None 
     
    3946            if sub_mask: 
    4047                values = values[sub_mask] 
    41             return values 
     48            return values     
     49 
     50    def get_safe(self, N, distance_matrix=None, sub_mask=None): 
     51        return self.check(self.extract(N, distance_matrix, sub_mask)) 
     52     
     53    def get(self, N, distance_matrix=None, sub_mask=None): 
     54        return self.extract(N, distance_matrix, sub_mask) 
    4255 
    4356 
     
    7487            logger.debug("Can't check weight, conductance status unknown.") 
    7588        return weight 
    76  
    77     def get(self, N, distance_matrix=None, sub_mask=None): 
    78       values = ConnectionAttributeGenerator.get(self, N, distance_matrix, sub_mask)       
    79       if self.safe: 
    80           values = self.check(values) 
    81       return values 
    82  
     89         
     90     
    8391 
    8492class DelayGenerator(ConnectionAttributeGenerator): 
     
    8896        self.min_delay = common.get_min_delay() 
    8997        self.max_delay = common.get_max_delay() 
    90  
     98         
    9199    def check(self, delay): 
    92100        all_negative = (delay<=self.max_delay).all() 
     
    94102        if not (all_negative and all_positive): 
    95103            raise errors.ConnectionError("delay (%s) is out of range [%s,%s]" % (delay, common.get_min_delay(), common.get_max_delay())) 
    96         return delay 
    97  
    98     def get(self, N, distance_matrix=None, sub_mask=None): 
    99         values = ConnectionAttributeGenerator.get(self, N, distance_matrix, sub_mask) 
    100         if self.safe: 
    101             values = self.check(values) 
    102         return values 
    103  
     104        return delay     
    104105 
    105106class ProbaGenerator(ConnectionAttributeGenerator): 
     
    113114        self.space = space 
    114115        if mask is not None: 
    115             self.B = ((B.T)[mask]).T 
     116            self.B = B[:,mask] 
    116117        else: 
    117118            self.B = B 
     
    133134class Connector(object): 
    134135     
    135     def __init__(self, weights=0.0, delays=None, space=Space(), safe=True): 
     136    def __init__(self, weights=0.0, delays=None, space=Space(), safe=True, verbose=True): 
    136137        self.weights = weights 
    137138        self.space   = space 
    138139        self.safe    = safe 
     140        self.verbose = verbose 
    139141        min_delay    = common.get_min_delay() 
    140142        if delays is None: 
     
    143145            if core.is_listlike(delays): 
    144146                assert min(delays) >= min_delay 
    145             else: 
     147            elif not (isinstance(delays, basestring) or isinstance(delays, RandomDistribution)): 
    146148                assert delays >= min_delay 
    147             self.delays = delays 
    148      
     149            self.delays = delays         
     150         
    149151    def connect(self, projection): 
    150152        pass 
    151153     
     154    def progressbar(self, N): 
     155        self.prog = utility.ProgressBar(0, N, 20, mode='fixed')         
     156     
     157    def progression(self, count): 
     158        if self.verbose: 
     159            self.prog.update_amount(count) 
     160            print self.prog, "\r", 
     161            sys.stdout.flush() 
     162             
    152163 
    153164 
     
    207218    """ 
    208219     
    209     def __init__(self, allow_self_connections=True, weights=0.0, delays=None, space=Space(), safe=True): 
     220    def __init__(self, allow_self_connections=True, weights=0.0, delays=None, space=Space(), safe=True, verbose=True): 
    210221        """ 
    211222        Create a new connector. 
     
    223234                   dependent weights or delays 
    224235        """ 
    225         Connector.__init__(self, weights, delays, space, safe) 
     236        Connector.__init__(self, weights, delays, space, safe, verbose) 
    226237        assert isinstance(allow_self_connections, bool) 
    227238        self.allow_self_connections = allow_self_connections 
     
    229240    def connect(self, projection): 
    230241        connector = ProbabilisticConnector(projection, self.weights, self.delays, self.allow_self_connections, self.space, safe=self.safe)         
     242        self.progressbar(len(projection.pre)) 
    231243        for count, src in enumerate(projection.pre.all()): 
    232244            connector._probabilistic_connect(src, 1) 
    233  
    234  
     245            self.progression(count) 
     246             
    235247     
    236248 
     
    240252    """ 
    241253     
    242     def __init__(self, p_connect, allow_self_connections=True, weights=0.0, delays=None, space=Space(), safe=True): 
     254    def __init__(self, p_connect, allow_self_connections=True, weights=0.0, delays=None, space=Space(),  
     255                       safe=True, verbose=True): 
    243256        """ 
    244257        Create a new connector. 
     
    258271                   dependent weights or delays 
    259272        """ 
    260         Connector.__init__(self, weights, delays, space, safe) 
     273        Connector.__init__(self, weights, delays, space, safe, verbose) 
    261274        assert isinstance(allow_self_connections, bool) 
    262275        self.allow_self_connections = allow_self_connections 
     
    267280        #assert projection.rng.parallel_safe 
    268281        connector = ProbabilisticConnector(projection, self.weights, self.delays, self.allow_self_connections, self.space, safe=self.safe) 
    269         for src in projection.pre.all(): 
     282        self.progressbar(len(projection.pre)) 
     283        for count, src in enumerate(projection.pre.all()): 
    270284            connector._probabilistic_connect(src, self.p_connect) 
    271  
     285            self.progression(count) 
     286             
    272287 
    273288class DistanceDependentProbabilityConnector(ProbabilisticConnector): 
     
    277292     
    278293    def __init__(self, d_expression, allow_self_connections=True, 
    279                  weights=0.0, delays=None, space=Space(), safe=True): 
     294                 weights=0.0, delays=None, space=Space(), safe=True, verbose=True): 
    280295        """ 
    281296        Create a new connector. 
     
    290305                     to the global minimum delay. 
    291306        """ 
    292         Connector.__init__(self, weights, delays, space, safe) 
     307        Connector.__init__(self, weights, delays, space, safe, verbose) 
    293308        assert isinstance(d_expression, str) 
    294309        try: 
     
    305320        connector       = ProbabilisticConnector(projection, self.weights, self.delays, self.allow_self_connections, self.space, safe=self.safe) 
    306321        proba_generator = ProbaGenerator(self.d_expression, connector.local) 
    307  
    308         for src in projection.pre.all():      
     322        self.progressbar(len(projection.pre)) 
     323        for count, src in enumerate(projection.pre.all()):      
    309324            connector.distance_matrix.set_source(src.position) 
    310325            proba  = proba_generator.get(connector.N, connector.distance_matrix) 
     
    312327                proba = proba.astype(float) 
    313328            connector._probabilistic_connect(src, proba) 
    314  
     329            self.progression(count) 
     330     
    315331 
    316332class FromListConnector(Connector): 
     
    319335    """ 
    320336     
    321     def __init__(self, conn_list): 
     337    def __init__(self, conn_list, safe=True, verbose=True): 
    322338        """ 
    323339        Create a new connector. 
     
    331347        """ 
    332348        # needs extending for dynamic synapses. 
    333         Connector.__init__(self, 0., common.get_min_delay()) 
     349        Connector.__init__(self, 0., common.get_min_delay(), safe=safe, verbose=verbose) 
    334350        self.conn_list = conn_list         
    335351         
     
    337353        """Connect-up a Projection.""" 
    338354        # slow: should maybe sort by pre 
    339         for i in xrange(len(self.conn_list)): 
     355        self.progressbar(len(self.conn_list)) 
     356        for count, i in enumerate(xrange(len(self.conn_list))): 
    340357            src, tgt, weight, delay = self.conn_list[i][:] 
    341358            src = projection.pre[tuple(src)]            
    342359            tgt = projection.post[tuple(tgt)] 
    343360            projection.connection_manager.connect(src, [tgt], weight, delay) 
    344  
     361            self.progression(count) 
     362             
    345363 
    346364class FromFileConnector(FromListConnector): 
     
    349367    """ 
    350368     
    351     def __init__(self, filename, distributed=False): 
     369    def __init__(self, filename, distributed=False, safe=True, verbose=True): 
    352370        """ 
    353371        Create a new connector. 
     
    360378                         distributed simulations. 
    361379        """ 
    362         Connector.__init__(self, 0., common.get_min_delay()) 
     380        Connector.__init__(self, 0., common.get_min_delay(), safe=safe, verbose=verbose) 
    363381        self.filename = filename 
    364382        self.distributed = distributed 
     
    397415    """ 
    398416     
    399     def __init__(self, n, allow_self_connections=True, weights=0.0, delays=None, space=Space(), safe=True): 
     417    def __init__(self, n, allow_self_connections=True, weights=0.0, delays=None, space=Space(), safe=True, verbose=True): 
    400418        """ 
    401419        Create a new connector. 
     
    415433                     to the global minimum delay. 
    416434        """ 
    417         Connector.__init__(self, weights, delays, space, safe) 
     435        Connector.__init__(self, weights, delays, space, safe, verbose) 
    418436        assert isinstance(allow_self_connections, bool) 
    419437        self.allow_self_connections = allow_self_connections 
     
    433451        weights_generator = WeightGenerator(self.weights, local, projection, self.safe) 
    434452        delays_generator  = DelayGenerator(self.delays, local, self.safe) 
    435         distance_matrix   = DistanceMatrix(projection.post.positions, self.space, numpy.arange(len(projection.post))) 
     453        distance_matrix   = DistanceMatrix(projection.post.positions, self.space) 
    436454        candidates        = projection.post.all_cells.flatten()             
     455        self.progressbar(len(projection.pre))         
    437456         
    438457        if isinstance(projection.rng, random.NativeRNG): 
    439458            raise Exception("Use of NativeRNG not implemented.")         
    440459         
    441         for src in projection.pre.all(): 
     460        for count, src in enumerate(projection.pre.all()): 
    442461            # pick n neurons at random 
    443462            if hasattr(self, 'rand_distr'): 
     
    463482            if len(targets) > 0: 
    464483                projection.connection_manager.connect(src, targets.tolist(), weights, delays) 
    465                      
     484             
     485            self.progression(count) 
     486             
    466487 
    467488class FixedNumberPreConnector(Connector): 
     
    477498    """ 
    478499     
    479     def __init__(self, n, allow_self_connections=True, weights=0.0, delays=None, space=Space(), safe=True): 
     500    def __init__(self, n, allow_self_connections=True, weights=0.0, delays=None, space=Space(), safe=True, verbose=True): 
    480501        """ 
    481502        Create a new connector. 
     
    510531    def connect(self, projection): 
    511532        """Connect-up a Projection.""" 
    512         local             = numpy.arange(len(projection.post))         
     533        local             = projection.pre._mask_local.flatten() 
    513534        weights_generator = WeightGenerator(self.weights, local, projection, self.safe) 
    514535        delays_generator  = DelayGenerator(self.delays, local, self.safe) 
    515536        distance_matrix   = DistanceMatrix(projection.pre.positions, self.space) 
    516537        candidates        = projection.pre.all_cells.flatten()                         
     538        self.progressbar(len(projection.pre))                 
    517539         
    518540        if isinstance(projection.rng, random.NativeRNG): 
    519541            raise Exception("Warning: use of NativeRNG not implemented.") 
    520542             
    521         for tgt in projection.post.local_cells.flat: 
     543        for count, tgt in enumerate(projection.post.local_cells.flat): 
    522544            # pick n neurons at random 
    523545            if hasattr(self, 'rand_distr'): 
     
    543565            for src, w, d in zip(sources, weights, delays): 
    544566                projection.connection_manager.connect(src, [tgt], w, d) 
    545                      
     567             
     568            self.progression(count) 
     569             
    546570 
    547571class OneToOneConnector(Connector): 
     
    557581     
    558582     
    559     def __init__(self, weights=0.0, delays=None, space=Space()): 
     583    def __init__(self, weights=0.0, delays=None, space=Space(), safe=True, verbose=True): 
    560584        """ 
    561585        Create a new connector. 
     
    567591                     to the global minimum delay. 
    568592        """ 
    569         Connector.__init__(self, weights, delays, space) 
     593        Connector.__init__(self, weights, delays, space, verbose) 
     594        self.space = space 
     595        self.safe  = safe 
    570596     
    571597    def connect(self, projection): 
     
    574600            N                 = projection.post.size 
    575601            local             = projection.post._mask_local.flatten() 
    576             weights_generator = WeightGenerator(self.weights, local, projection) 
    577             delays_generator  = DelayGenerator(self.delays, local)                 
     602            weights_generator = WeightGenerator(self.weights, local, projection, self.safe) 
     603            delays_generator  = DelayGenerator(self.delays, local, self.safe)                 
    578604            weights           = weights_generator.get(N) 
    579605            delays            = delays_generator.get(N) 
     606            self.progressbar(len(projection.post.local_cells))                         
     607            count             = 0 
    580608             
    581609            for tgt, w, d in zip(projection.post.local_cells, weights, delays): 
     
    584612                # the float is in case the values are of type numpy.float64, which NEST chokes on 
    585613                projection.connection_manager.connect(src, [tgt], float(w), float(d)) 
     614                self.progression(count) 
     615                count += 1 
    586616        else: 
    587617            raise errors.InvalidDimensionsError("OneToOneConnector does not support presynaptic and postsynaptic Populations of different sizes.")