Package mvpa :: Package mappers :: Module metric
[hide private]
[frames] | no frames]

Source Code for Module mvpa.mappers.metric

  1  #emacs: -*- mode: python-mode; py-indent-offset: 4; indent-tabs-mode: nil -*- 
  2  #ex: set sts=4 ts=4 sw=4 et: 
  3  ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ## 
  4  # 
  5  #   See COPYING file distributed along with the PyMVPA package for the 
  6  #   copyright and license terms. 
  7  # 
  8  ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ## 
  9  """Classes and functions to provide sense of distances between sample points""" 
 10   
 11  __docformat__ = 'restructuredtext' 
 12   
 13  import numpy as N 
 14   
 15  from mvpa.clfs.distance import cartesianDistance 
 16   
17 -class Metric(object):
18 """Abstract class for any finder. 19 20 Classes subclasses from this class show know about structure of 21 the data and thus be able to provide information about the 22 neighbors. 23 At least one of the methods (getNeighbors, getNeighbor) has to be 24 overriden in the derived class. 25 NOTE: derived #2 from derived class #1 has to override all methods 26 which were overrident in class #1 27 """ 28
29 - def getNeighbors(self, *args, **kwargs):
30 """Return the list of coordinates for the neighbors. 31 32 By default it simply constracts the list based on 33 the generator getNeighbor 34 """ 35 return [ x for x in self.getNeighbor(*args, **kwargs) ]
36 37
38 - def getNeighbor(self, *args, **kwargs):
39 """Generator to return coordinate of the neighbor. 40 41 Base class contains the simplest implementation, assuming that 42 getNeighbors returns iterative structure to spit out neighbors 43 1-by-1 44 """ 45 for neighbor in self.getNeighbors(*args, **kwargs): 46 yield neighbor
47 48 49
50 -class DescreteMetric(Metric):
51 """Find neighboring points in descretized space 52 53 If input space is descretized and all points fill in 54 N-dimensional cube, this finder returns list of neighboring 55 points for a given distance. 56 57 As input points it operates on discretized values, not absolute 58 coordinates (which are e.g. in mm) 59 """ 60
61 - def __init__(self, 62 elementsize=1, 63 distance_function=cartesianDistance):
64 """ 65 Initialize the class provided @elementsize and @distance_function 66 """ 67 Metric.__init__(self) 68 self.__filter_radius = None 69 self.__filter_coord = None 70 self.__distance_function = distance_function 71 72 # XXX might not need assume compatible spacemetric 73 self.__elementsize = N.array(elementsize, ndmin=1) 74 self.__Ndims = len(self.__elementsize)
75 76
77 - def _computeFilter(self, radius):
78 """ (Re)Computer filter_coord based on given radius 79 """ 80 # compute radius in units of elementsize per axis 81 elementradius_per_axis = float(radius) / self.__elementsize 82 83 # build prototype search space 84 filter_radiuses = N.array([int(N.ceil(abs(x))) 85 for x in elementradius_per_axis]) 86 filter_center = filter_radiuses 87 filter_mask = N.ones( ( filter_radiuses * 2 ) + 1 ) 88 89 # now zero out all too distant elements 90 f_coords = N.transpose( filter_mask.nonzero() ) 91 92 # check all filter element 93 for coord in f_coords: 94 dist = self.__distance_function(coord*self.__elementsize, 95 filter_center*self.__elementsize) 96 # compare with radius 97 if radius < dist: 98 # zero too distant 99 filter_mask[N.array(coord, ndmin=2).T.tolist()] = 0 100 101 self.__filter_coord = N.array( filter_mask.nonzero() ).T \ 102 - filter_center 103 self.__filter_radius = radius
104 105
106 - def getNeighbors(self, origin, radius=0):
107 """Returns coordinates of the neighbors which are within 108 distance from coord 109 110 XXX radius might need to be not a scalar but a vector of 111 scalars to specify search distance in different dimensions 112 differently... but then may be it has to be a tensor to 113 specify orientation etc? :-) so it might not be necessary for 114 now 115 """ 116 if len(origin) != self.__Ndims: 117 raise ValueError("Obtained coordinates [%s] which have different" 118 + " number of dimensions (%d) from known " 119 + " elementsize" % (`origin`, self.__Ndims)) 120 if radius != self.__filter_radius: 121 self._computeFilter(radius) 122 123 # for the ease of future references, it is better to transform 124 # coordinates into tuples 125 return origin + self.__filter_coord
126 127
128 - def _setFilter(self, filter_coord):
129 """Lets allow to specify some custom filter to use 130 """ 131 self.__filter_coord = filter_coord
132 133
134 - def _getFilter(self):
135 """Lets allow to specify some custom filter to use 136 """ 137 return self.__filter_coord
138 139 filter_coord = property(fget=_getFilter, fset=_setFilter) 140 elementsize = property(fget=lambda self: self.__elementsize)
141 142 # Template for future classes 143 # 144 # class MeshMetric(Metric): 145 # """Return list of neighboring points on a mesh 146 # """ 147 # def getNeighbors(self, origin, distance=0): 148 # """Return neighbors""" 149 # raise NotImplementedError 150