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)
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