Changeset 712 for trunk/src/common.py

Show
Ignore:
Timestamp:
02/16/10 12:33:37 (2 years ago)
Author:
apdavison
Message:

Moved the Space class out of common into its own module

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/src/common.py

    r711 r712  
    133133        raise errors.ConnectionError("delay (%s) is out of range [%s,%s]" % (delay, get_min_delay(), get_max_delay())) 
    134134    return delay 
    135  
    136 def distance(src, tgt, mask=None, scale_factor=1.0, offset=0.0, 
    137              periodic_boundaries=None): # may need to add an offset parameter 
    138     """ 
    139     Return the Euclidian distance between two cells. 
    140     `mask` allows only certain dimensions to be considered, e.g.:: 
    141       * to ignore the z-dimension, use `mask=array([0,1])` 
    142       * to ignore y, `mask=array([0,2])` 
    143       * to just consider z-distance, `mask=array([2])` 
    144     `scale_factor` allows for different units in the pre- and post- position 
    145     (the post-synaptic position is multipied by this quantity). 
    146     """ 
    147     d = src.position - scale_factor*(tgt.position + offset) 
    148      
    149     if not periodic_boundaries == None: 
    150         d = numpy.minimum(abs(d), periodic_boundaries-abs(d)) 
    151     if mask is not None: 
    152         d = d[mask] 
    153     return numpy.sqrt(numpy.dot(d, d)) 
    154  
    155  
    156 class Space(object): 
    157      
    158     AXES = {'x' : [0],    'y': [1],    'z': [2], 
    159             'xy': [0,1], 'yz': [1,2], 'xz': [0,2], 'xyz': range(3), None: range(3)} 
    160      
    161     def __init__(self, axes=None, scale_factor=1.0, offset=0.0, 
    162                  periodic_boundaries=None): 
    163         """ 
    164         axes -- if not supplied, then the 3D distance is calculated. If supplied, 
    165             axes should be a string containing the axes to be used, e.g. 'x', or 
    166             'yz'. axes='xyz' is the same as axes=None. 
    167         scale_factor -- it may be that the pre and post populations use 
    168             different units for position, e.g. degrees and µm. In this case, 
    169             `scale_factor` can be specified, which is applied to the positions 
    170             in the post-synaptic population. 
    171         offset -- if the origins of the coordinate systems of the pre- and post- 
    172             synaptic populations are different, `offset` can be used to adjust 
    173             for this difference. The offset is applied before any scaling. 
    174         periodic_boundaries -- either `None`, or a tuple giving the boundaries 
    175             for each dimension, e.g. `((x_min, x_max), None, (z_min, z_max))`. 
    176         """ 
    177         self.periodic_boundaries = periodic_boundaries 
    178         self.axes = numpy.array(Space.AXES[axes]) 
    179         self.scale_factor = scale_factor 
    180         self.offset = offset 
    181          
    182     def distances(self, A, B): 
    183         """ 
    184         Calculate the distance matrix between two sets of coordinates, given 
    185         the topology of the current space. 
    186         From http://projects.scipy.org/pipermail/numpy-discussion/2007-April/027203.html 
    187         """ 
    188         if len(A.shape) == 1: 
    189             A = A.reshape(3, 1) 
    190         if len(B.shape) == 1: 
    191             B = B.reshape(3, 1) 
    192         B = self.scale_factor*(B + self.offset) 
    193         d = numpy.zeros((A.shape[1], B.shape[1]), dtype=A.dtype) 
    194         for axis in self.axes: 
    195             diff2 = A[axis,:,None] - B[axis,:] 
    196             if self.periodic_boundaries is not None: 
    197                 boundaries = self.periodic_boundaries[axis] 
    198                 if boundaries is not None: 
    199                     range = boundaries[1]-boundaries[0] 
    200                     ad2 = abs(diff2) 
    201                     diff2 = numpy.minimum(ad2, range-ad2) 
    202             diff2 **= 2 
    203             d += diff2 
    204         numpy.sqrt(d, d) 
    205         return d 
    206135 
    207136