Exemple #1
0
def reloadAll(prefix=None, debug=False):
    """Automatically reload everything whose __file__ begins with prefix.
    - Skips reload if the file has not been updated (if .pyc is newer than .py)
    - if prefix is None, checks all loaded modules
    """
    for modName, mod in sys.modules.items():  ## don't use iteritems; size may change during reload
        if not inspect.ismodule(mod):
            continue
        if modName == '__main__':
            continue
        
        ## Ignore if the file name does not start with prefix
        if not hasattr(mod, '__file__') or os.path.splitext(mod.__file__)[1] not in ['.py', '.pyc']:
            continue
        if prefix is not None and mod.__file__[:len(prefix)] != prefix:
            continue
        
        ## ignore if the .pyc is newer than the .py (or if there is no pyc or py)
        py = os.path.splitext(mod.__file__)[0] + '.py'
        pyc = py + 'c'
        if os.path.isfile(pyc) and os.path.isfile(py) and os.stat(pyc).st_mtime >= os.stat(py).st_mtime:
            #if debug:
                #print "Ignoring module %s; unchanged" % str(mod)
            continue
        
        try:
            reload(mod, debug=debug)
        except:
            printExc("Error while reloading module %s, skipping\n" % mod)
Exemple #2
0
def makeARGB(data, lut=None, levels=None, useRGBA=False):
    """
    Convert a 2D or 3D array into an ARGB array suitable for building QImages
    Will optionally do scaling and/or table lookups to determine final colors.
    
    Returns the ARGB array (values 0-255) and a boolean indicating whether there is alpha channel data.
    
    Arguments:
        data  - 2D or 3D numpy array of int/float types
        
                For 2D arrays (x, y):
                  * The color will be determined using a lookup table (see argument 'lut').
                  * If levels are given, the data is rescaled and converted to int
                    before using the lookup table.
                 
                For 3D arrays (x, y, rgba):
                  * The third axis must have length 3 or 4 and will be interpreted as RGBA.
                  * The 'lut' argument is not allowed.
                 
        lut   - Lookup table for 2D data. May be 1D or 2D (N,rgba) and must have dtype=ubyte.
                Values in data will be converted to color by indexing directly from lut.
                Lookup tables can be built using GradientWidget.
        levels - List [min, max]; optionally rescale data before converting through the
                lookup table.   rescaled = (data-min) * len(lut) / (max-min)
        useRGBA - If True, the data is returned in RGBA order. The default is 
                  False, which returns in BGRA order for use with QImage.
                
    """
    prof = debug.Profiler('functions.makeARGB', disabled=True)

    ## sanity checks
    if data.ndim == 3:
        if data.shape[2] not in (3, 4):
            raise Exception("data.shape[2] must be 3 or 4")
        #if lut is not None:
        #raise Exception("can not use lookup table with 3D data")
    elif data.ndim != 2:
        raise Exception("data must be 2D or 3D")

    if lut is not None:
        if lut.ndim == 2:
            if lut.shape[1] not in (3, 4):
                raise Exception("lut.shape[1] must be 3 or 4")
        elif lut.ndim != 1:
            raise Exception("lut must be 1D or 2D")
        if lut.dtype != np.ubyte:
            raise Exception(
                'lookup table must have dtype=ubyte (got %s instead)' %
                str(lut.dtype))

    if levels is not None:
        levels = np.array(levels)
        if levels.shape == (2, ):
            pass
        elif levels.shape in [(3, 2), (4, 2)]:
            if data.ndim == 3:
                raise Exception("Can not use 2D levels with 3D data.")
            if lut is not None:
                raise Exception(
                    'Can not use 2D levels and lookup table together.')
        else:
            raise Exception("Levels must have shape (2,) or (3,2) or (4,2)")

    prof.mark('1')

    if lut is not None:
        lutLength = lut.shape[0]
    else:
        lutLength = 256

    ## weave requires contiguous arrays
    global USE_WEAVE
    if (levels is not None or lut is not None) and USE_WEAVE:
        data = np.ascontiguousarray(data)

    ## Apply levels if given
    if levels is not None:

        try:  ## use weave to speed up scaling
            if not USE_WEAVE:
                raise Exception(
                    'Weave is disabled; falling back to slower version.')
            if levels.ndim == 1:
                scale = float(lutLength) / (levels[1] - levels[0])
                offset = float(levels[0])
                data = rescaleData(data, scale, offset)
            else:
                if data.ndim == 2:
                    newData = np.empty(data.shape + (levels.shape[0], ),
                                       dtype=np.uint32)
                    for i in xrange(levels.shape[0]):
                        scale = float(lutLength /
                                      (levels[i, 1] - levels[i, 0]))
                        offset = float(levels[i, 0])
                        newData[..., i] = rescaleData(data, scale, offset)
                elif data.ndim == 3:
                    newData = np.empty(data.shape, dtype=np.uint32)
                    for i in xrange(data.shape[2]):
                        scale = float(lutLength /
                                      (levels[i, 1] - levels[i, 0]))
                        offset = float(levels[i, 0])
                        #print scale, offset, data.shape, newData.shape, levels.shape
                        newData[..., i] = rescaleData(data[..., i], scale,
                                                      offset)
                data = newData
        except:
            if USE_WEAVE:
                debug.printExc("Error; disabling weave.")
                USE_WEAVE = False

            if levels.ndim == 1:
                if data.ndim == 2:
                    levels = levels[np.newaxis, np.newaxis, :]
                else:
                    levels = levels[np.newaxis, np.newaxis, np.newaxis, :]
            else:
                levels = levels[np.newaxis, np.newaxis, ...]
                if data.ndim == 2:
                    data = data[..., np.newaxis]
            data = ((data - levels[..., 0]) * lutLength) / (levels[..., 1] -
                                                            levels[..., 0])

    prof.mark('2')

    ## apply LUT if given
    if lut is not None and data.ndim == 2:

        if data.dtype.kind not in ('i', 'u'):
            data = data.astype(int)

        data = np.clip(data, 0, lutLength - 1)
        try:
            if not USE_WEAVE:
                raise Exception(
                    'Weave is disabled; falling back to slower version.')

            newData = np.empty((data.size, ) + lut.shape[1:], dtype=np.uint8)
            flat = data.reshape(data.size)
            size = data.size
            ncol = lut.shape[1]
            newStride = newData.strides[0]
            newColStride = newData.strides[1]
            lutStride = lut.strides[0]
            lutColStride = lut.strides[1]
            flatStride = flat.strides[0] / flat.dtype.itemsize

            #print "newData:", newData.shape, newData.dtype
            #print "flat:", flat.shape, flat.dtype, flat.min(), flat.max()
            #print "lut:", lut.shape, lut.dtype
            #print "size:", size, "ncols:", ncol
            #print "strides:", newStride, newColStride, lutStride, lutColStride, flatStride

            code = """
            
            for( int i=0; i<size; i++ ) {
                for( int j=0; j<ncol; j++ ) {
                    newData[i*newStride + j*newColStride] = lut[flat[i*flatStride]*lutStride + j*lutColStride];
                }
            }
            """
            scipy.weave.inline(code, [
                'flat', 'lut', 'newData', 'size', 'ncol', 'newStride',
                'lutStride', 'flatStride', 'newColStride', 'lutColStride'
            ])
            data = newData.reshape(data.shape + lut.shape[1:])
        except:
            if USE_WEAVE:
                debug.printExc("Error; disabling weave.")
                USE_WEAVE = False
            data = lut[data]
    else:
        if data.dtype is not np.ubyte:
            data = np.clip(data, 0, 255).astype(np.ubyte)

    prof.mark('3')

    ## copy data into ARGB ordered array
    imgData = np.empty(data.shape[:2] + (4, ), dtype=np.ubyte)
    if data.ndim == 2:
        data = data[..., np.newaxis]

    prof.mark('4')

    if useRGBA:
        order = [0, 1, 2, 3]  ## array comes out RGBA
    else:
        order = [
            2, 1, 0, 3
        ]  ## for some reason, the colors line up as BGR in the final image.

    if data.shape[2] == 1:
        for i in xrange(3):
            imgData[..., order[i]] = data[..., 0]
    else:
        for i in xrange(0, data.shape[2]):
            imgData[..., order[i]] = data[..., i]

    prof.mark('5')

    if data.shape[2] == 4:
        alpha = True
    else:
        alpha = False
        imgData[..., 3] = 255

    prof.mark('6')

    prof.finish()
    return imgData, alpha
def makeARGB(data, lut=None, levels=None, useRGBA=False): 
    """
    Convert a 2D or 3D array into an ARGB array suitable for building QImages
    Will optionally do scaling and/or table lookups to determine final colors.
    
    Returns the ARGB array (values 0-255) and a boolean indicating whether there is alpha channel data.
    
    Arguments:
        data  - 2D or 3D numpy array of int/float types
        
                For 2D arrays (x, y):
                  * The color will be determined using a lookup table (see argument 'lut').
                  * If levels are given, the data is rescaled and converted to int
                    before using the lookup table.
                 
                For 3D arrays (x, y, rgba):
                  * The third axis must have length 3 or 4 and will be interpreted as RGBA.
                  * The 'lut' argument is not allowed.
                 
        lut   - Lookup table for 2D data. May be 1D or 2D (N,rgba) and must have dtype=ubyte.
                Values in data will be converted to color by indexing directly from lut.
                Lookup tables can be built using GradientWidget.
        levels - List [min, max]; optionally rescale data before converting through the
                lookup table.   rescaled = (data-min) * len(lut) / (max-min)
        useRGBA - If True, the data is returned in RGBA order. The default is 
                  False, which returns in BGRA order for use with QImage.
                
    """    
    prof = debug.Profiler('functions.makeARGB', disabled=True)
    
    ## sanity checks
    if data.ndim == 3:
        if data.shape[2] not in (3,4):
            raise Exception("data.shape[2] must be 3 or 4")
        #if lut is not None:
            #raise Exception("can not use lookup table with 3D data")
    elif data.ndim != 2:
        raise Exception("data must be 2D or 3D")
        
    if lut is not None:
        if lut.ndim == 2:
            if lut.shape[1] not in (3,4):
                raise Exception("lut.shape[1] must be 3 or 4")
        elif lut.ndim != 1:
            raise Exception("lut must be 1D or 2D")
        if lut.dtype != np.ubyte:
            raise Exception('lookup table must have dtype=ubyte (got %s instead)' % str(lut.dtype))

    if levels is not None:
        levels = np.array(levels)
        if levels.shape == (2,):
            pass
        elif levels.shape in [(3,2), (4,2)]:
            if data.ndim == 3:
                raise Exception("Can not use 2D levels with 3D data.")
            if lut is not None:
                raise Exception('Can not use 2D levels and lookup table together.')
        else:
            raise Exception("Levels must have shape (2,) or (3,2) or (4,2)")
        
    prof.mark('1')

    if lut is not None:
        lutLength = lut.shape[0]
    else:
        lutLength = 256

    ## weave requires contiguous arrays
    global USE_WEAVE
    if (levels is not None or lut is not None) and USE_WEAVE:
        data = np.ascontiguousarray(data)

    ## Apply levels if given
    if levels is not None:
        
        try:  ## use weave to speed up scaling
            if not USE_WEAVE:
                raise Exception('Weave is disabled; falling back to slower version.')
            if levels.ndim == 1:
                scale = float(lutLength) / (levels[1]-levels[0])
                offset = float(levels[0])
                data = rescaleData(data, scale, offset)
            else:
                if data.ndim == 2:
                    newData = np.empty(data.shape+(levels.shape[0],), dtype=np.uint32)
                    for i in xrange(levels.shape[0]):
                        scale = float(lutLength / (levels[i,1]-levels[i,0]))
                        offset = float(levels[i,0])
                        newData[...,i] = rescaleData(data, scale, offset)
                elif data.ndim == 3:
                    newData = np.empty(data.shape, dtype=np.uint32)
                    for i in xrange(data.shape[2]):
                        scale = float(lutLength / (levels[i,1]-levels[i,0]))
                        offset = float(levels[i,0])
                        #print scale, offset, data.shape, newData.shape, levels.shape
                        newData[...,i] = rescaleData(data[...,i], scale, offset)
                data = newData
        except:
            if USE_WEAVE:
                debug.printExc("Error; disabling weave.")
                USE_WEAVE = False
            
            if levels.ndim == 1:
                if data.ndim == 2:
                    levels = levels[np.newaxis, np.newaxis, :]
                else:
                    levels = levels[np.newaxis, np.newaxis, np.newaxis, :]
            else:
                levels = levels[np.newaxis, np.newaxis, ...]
                if data.ndim == 2:
                    data = data[..., np.newaxis]
            data = ((data-levels[...,0]) * lutLength) / (levels[...,1]-levels[...,0])
        
    prof.mark('2')


    ## apply LUT if given
    if lut is not None and data.ndim == 2:
        
        if data.dtype.kind not in ('i', 'u'):
            data = data.astype(int)
            
        data = np.clip(data, 0, lutLength-1)
        try:
            if not USE_WEAVE:
                raise Exception('Weave is disabled; falling back to slower version.')
            
            newData = np.empty((data.size,) + lut.shape[1:], dtype=np.uint8)
            flat = data.reshape(data.size)
            size = data.size
            ncol = lut.shape[1]
            newStride = newData.strides[0]
            newColStride = newData.strides[1]
            lutStride = lut.strides[0]
            lutColStride = lut.strides[1]
            flatStride = flat.strides[0] / flat.dtype.itemsize
            
            #print "newData:", newData.shape, newData.dtype
            #print "flat:", flat.shape, flat.dtype, flat.min(), flat.max()
            #print "lut:", lut.shape, lut.dtype
            #print "size:", size, "ncols:", ncol
            #print "strides:", newStride, newColStride, lutStride, lutColStride, flatStride
            
            code = """
            
            for( int i=0; i<size; i++ ) {
                for( int j=0; j<ncol; j++ ) {
                    newData[i*newStride + j*newColStride] = lut[flat[i*flatStride]*lutStride + j*lutColStride];
                }
            }
            """
            scipy.weave.inline(code, ['flat', 'lut', 'newData', 'size', 'ncol', 'newStride', 'lutStride', 'flatStride', 'newColStride', 'lutColStride'])
            data = newData.reshape(data.shape + lut.shape[1:])
        except:
            if USE_WEAVE:
                debug.printExc("Error; disabling weave.")
                USE_WEAVE = False
            data = lut[data]
    else:
        if data.dtype is not np.ubyte:
            data = np.clip(data, 0, 255).astype(np.ubyte)

    prof.mark('3')


    ## copy data into ARGB ordered array
    imgData = np.empty(data.shape[:2]+(4,), dtype=np.ubyte)
    if data.ndim == 2:
        data = data[..., np.newaxis]

    prof.mark('4')

    if useRGBA:
        order = [0,1,2,3] ## array comes out RGBA
    else:
        order = [2,1,0,3] ## for some reason, the colors line up as BGR in the final image.
        
    if data.shape[2] == 1:
        for i in xrange(3):
            imgData[..., order[i]] = data[..., 0]    
    else:
        for i in xrange(0, data.shape[2]):
            imgData[..., order[i]] = data[..., i]    
        
    prof.mark('5')
        
    if data.shape[2] == 4:
        alpha = True
    else:
        alpha = False
        imgData[..., 3] = 255
        
    prof.mark('6')
        
    prof.finish()
    return imgData, alpha