This file is indexed.

/usr/share/pyshared/dipy/reconst/maskedview.py is in python-dipy 0.5.0-3.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
""" Class to allow masked view of data array """
import numpy as np
from operator import mul
from copy import copy

def _makearray(a):
    new = np.asarray(a)
    wrap = getattr(a, "__array_wrap__", new.__array_wrap__)
    return new, wrap

def _filled(a, *args, **kargs):
    if hasattr(a, 'filled'):
        return a.filled(*args, **kargs)
    else:
        return a

class MaskedView(object):
    """
    An interface to allow the user to interact with a data array as if it is a
    container with the same shape as mask. The contents of data are mapped to
    the nonzero elements of mask, where mask is zero fill_value is used.

    Examples
    -----------
    >>> mask = np.array([[True, False, True],[False, True, False]])
    >>> data = np.arange(2*3*4)
    >>> data.shape = (2, 3, 4)
    >>> mv = MaskedView(mask, data[mask], fill_value=10)
    >>> mv.shape
    (2, 3, 4)
    >>> data[0, 0, :]
    array([0, 1, 2, 3])
    >>> mv[0, 1]
    array([10, 10, 10, 10])
    >>> mv[:,:,0]
    array([[ 0, 10,  8],
           [10, 16, 10]])
    
    """

    def __init__(self, mask, data, fill_value=None):
        """
        Creates a MaskedView of data.

        Parameters
        ------------
        mask : ndarray of bools
            mask indicating where the data belongs
        data : ndarray, ndim >= mask.ndim
            the first dimension of data should have size equal to the number of
            nonzero elements in mask
        fill_value : optional
            fill_value is returned when MaskedView is indexed and mask is zero,
            also fill_value is used to fill out an array when the filled method
            is called. By defult is NaN or 0 depending on the dtype of data.
        
        """

        mask = mask.astype('bool')
        if len(data) != mask.sum():
            raise ValueError('the number of data elements does not match mask') 
        self._data = data
        try:
            self.fill_value = np.array(fill_value, dtype=data.dtype)
        except TypeError:
            if fill_value is None:
                self.fill_value = np.array(0, dtype=data.dtype)
            else:
                raise
        self.base = None
        self._imask = np.empty(mask.shape, 'int')
        self._imask.fill(-1)
        self._imask[mask] = np.arange(len(data))
    
    @property
    def mask(self):
        return self._imask >= 0

    @property
    def dtype(self):
        #the data type of a masked view is the same as the _data array
        return self._data.dtype

    @property
    def ndim(self):
        return self._data.ndim + self._imask.ndim - 1

    def filled(self, fill_value=None):
        """
        Returns an ndarray copy of itself. Where mask is zero, fill_value is used 
        (self.fill_value defult).

        Parameters
        ------------
        fill_value :
            Value to be used in place of data where mask is 0.
        """
        if fill_value is None:
            fill_value = self.fill_value
        out_arr = np.empty(self.shape, self.dtype)
        out_arr[:] = fill_value
        out_arr[self.mask] = self.__array__()
        return out_arr

    def _get_shape_contents(self):
        return self._data.shape[1:]

    def _set_shape_contents(self, shape):
        self._data.shape = self._data.shape[0:1] + shape

    def _get_shape_mask(self):
        return self._imask.shape

    def _set_shape_mask(self, shape):
        self._imask.shape = shape

    def _get_shape(self):
        return self.shape_mask + self.shape_contents

    def _set_shape(self, shape):
        try:
            shape[1]
        except (TypeError, IndexError):
            raise ValueError("a 2d shape is required such that the size of " +
                             "mask is unchanged")

        where_missing = [ii < 0 for ii in shape]
        count_missing = sum(where_missing)
        if count_missing == 1:
            ind = where_missing.index(True)
            tot_sz = reduce(mul, self.shape)
            other_sz = reduce(mul, shape[:ind] + shape[ind+1:])
            if tot_sz % other_sz != 0:
                raise ValueError("total size of new array must be unchanged")
            missing = tot_sz / other_sz
            shape = shape[:ind] + (missing,) + shape[ind+1:]
        elif count_missing > 1:
            raise ValueError("can only specify one unknown dimension")
        elif reduce(mul, shape) != reduce(mul, self.shape):
            raise ValueError("total size of new array must be unchanged")
        
        first_n = 1
        for ind, dim_i in enumerate(shape):
            first_n = dim_i*first_n
            if first_n == self._imask.size:
                self.shape_mask = shape[:ind+1]
                self.shape_contents = shape[ind+1:]
                break
            elif first_n > self._imask.size:
                raise ValueError("total size of mask must be unchanged")

    shape_contents = property(_get_shape_contents, _set_shape_contents,
                              "Tuple of contents dimensions")
    shape_mask = property(_get_shape_mask, _set_shape_mask,
                          "Tuple of mask dimensions")
    shape = property(_get_shape, _set_shape, "Tuple of array dimensions")

    def get_size(self):
        """
        Returns the number of non-empty values in MaskedView, ie where
        mask > 0.
        """

        return self.mask.sum()

    def copy(self):
        """
        Returns a copy of the MaskedView. Copies the underlying data array.
        """
        data = self._data[self._imask[self.mask]]
        return MaskedView(self.mask, data, self.fill_value)

    def __getitem__(self, index):
        """
        Indexes the MaskedView without copying the underlying data.
        """

        if type(index) is not tuple:
            index = (index,)
        #replace first Ellipsis with slices
        for ii, slc in enumerate(index):
            if slc is Ellipsis:
                n_ellipsis = len(self.shape) - len(index) + 1
                index = index[:ii] + n_ellipsis*(slice(None),) + index[ii+1:]
                break

        ndim_mask = self._imask.ndim
        if len(index) > ndim_mask:
            index_mask = index[:ndim_mask]
            index_cont = index[ndim_mask:]
        else:
            index_mask = index
            index_cont = (slice(None),)

        imask = self._imask[index_mask]
        if isinstance(imask, int):
            if imask >= 0:
                return self._data[(imask,)+index_cont]
            else:
                result = np.empty(self.shape_contents, self.dtype)
                result[:] = self.fill_value
                return result[index_cont]
        else:
            new_mp = copy(self)
            new_mp._imask = imask
            if self.base is None:
                new_mp.base = self
            data = self._data[(slice(None),) + index_cont]
            new_mp._data = data
            if data.ndim < 2:
                return new_mp.filled()
            else:
                return new_mp
    
    def __setitem__(self, index, values):
        """
        Sets part of the maskedview

        is this useful?
        """

        imask = self._imask[index]
        if isinstance(imask, int):
            if imask >= 0:
                self._data[imask] = values
            else:
                self._imask[index] = len(self._data)
                self._data = np.r_[self._data, values[np.newaxis]]
        else:
            self._data[imask[imask >= 0]] = values
    
    def __array__(self, dtype=None):
        """
        Returns the underlying data
        
        """

        #to save time only index _data when base is not None
        if self.base is None:
            data = self._data
        else:
            data = self._data[self._imask[self.mask]]

        #only makes a copy of data when dtype does not match self.dtype
        if dtype is None or np.dtype(dtype) == self.dtype:
            return data
        else:
            return data.astype(dtype)

    def __array_wrap__(self, array, context=None):
        #fill_value is not updated
        #ie if new = old + 1 new.fill_value == old.fil_value. Fixing this might
        #be a useful feature to implement at some point for numeric fill_values
        new_container = MaskedView(self.mask, array, self.fill_value)
        return new_container