def concentricrings(x, y, white_thickness, gaussian_width, spacing): """ Concetric rings with the solid ring-shaped region, then Gaussian fall-off at the edges. """ # To have zero value in middle point this pattern calculates zero-value rings instead of # the one-value ones. But to be consistent with the rest of functions the parameters # are connected to one-value rings - like half_thickness is now recalculated for zero-value ring: half_thickness = ((spacing-white_thickness)/2.0)*greater_equal(spacing-white_thickness,0.0) distance_from_origin = sqrt(x**2+y**2) distance_from_ring_middle = fmod(distance_from_origin,spacing) distance_from_ring_middle = minimum(distance_from_ring_middle,spacing - distance_from_ring_middle) distance_from_ring = distance_from_ring_middle - half_thickness ring = 0.0 + greater_equal(distance_from_ring,0.0) sigmasq = gaussian_width*gaussian_width with float_error_ignore(): falloff = exp(divide(-distance_from_ring*distance_from_ring, 2.0*sigmasq)) return maximum(falloff,ring)
def ring(x, y, height, thickness, gaussian_width): """ Circular ring (annulus) with Gaussian fall-off after the solid ring-shaped region. """ radius = height / 2.0 half_thickness = thickness / 2.0 distance_from_origin = sqrt(x**2 + y**2) distance_outside_outer_disk = distance_from_origin - radius - half_thickness distance_inside_inner_disk = radius - half_thickness - distance_from_origin ring = 1.0 - bitwise_xor(greater_equal(distance_inside_inner_disk, 0.0), greater_equal(distance_outside_outer_disk, 0.0)) sigmasq = gaussian_width * gaussian_width if sigmasq == 0.0: inner_falloff = x * 0.0 outer_falloff = x * 0.0 else: with float_error_ignore(): inner_falloff = exp( divide( -distance_inside_inner_disk * distance_inside_inner_disk, 2.0 * sigmasq)) outer_falloff = exp( divide( -distance_outside_outer_disk * distance_outside_outer_disk, 2.0 * sigmasq)) return maximum(inner_falloff, maximum(outer_falloff, ring))
def arc_by_radian(x, y, height, radian_range, thickness, gaussian_width): """ Radial arc with Gaussian fall-off after the solid ring-shaped region with the given thickness, with shape specified by the (start,end) radian_range. """ # Create a circular ring (copied from the ring function) radius = height/2.0 half_thickness = thickness/2.0 distance_from_origin = sqrt(x**2+y**2) distance_outside_outer_disk = distance_from_origin - radius - half_thickness distance_inside_inner_disk = radius - half_thickness - distance_from_origin ring = 1.0-bitwise_xor(greater_equal(distance_inside_inner_disk,0.0),greater_equal(distance_outside_outer_disk,0.0)) sigmasq = gaussian_width*gaussian_width if sigmasq==0.0: inner_falloff = x*0.0 outer_falloff = x*0.0 else: with float_error_ignore(): inner_falloff = exp(divide(-distance_inside_inner_disk*distance_inside_inner_disk, 2.0*sigmasq)) outer_falloff = exp(divide(-distance_outside_outer_disk*distance_outside_outer_disk, 2.0*sigmasq)) output_ring = maximum(inner_falloff,maximum(outer_falloff,ring)) # Calculate radians (in 4 phases) and cut according to the set range) # RZHACKALERT: # Function float_error_ignore() cannot catch the exception when # both dividend and divisor are 0.0, and when only divisor is 0.0 # it returns 'Inf' rather than 0.0. In x, y and # distance_from_origin, only one point in distance_from_origin can # be 0.0 (circle center) and in this point x and y must be 0.0 as # well. So here is a hack to avoid the 'invalid value encountered # in divide' error by turning 0.0 to 1e-5 in distance_from_origin. distance_from_origin += where(distance_from_origin == 0.0, 1e-5, 0) with float_error_ignore(): sines = divide(y, distance_from_origin) cosines = divide(x, distance_from_origin) arcsines = arcsin(sines) phase_1 = where(logical_and(sines >= 0, cosines >= 0), 2*pi-arcsines, 0) phase_2 = where(logical_and(sines >= 0, cosines < 0), pi+arcsines, 0) phase_3 = where(logical_and(sines < 0, cosines < 0), pi+arcsines, 0) phase_4 = where(logical_and(sines < 0, cosines >= 0), -arcsines, 0) arcsines = phase_1 + phase_2 + phase_3 + phase_4 if radian_range[0] <= radian_range[1]: return where(logical_and(arcsines >= radian_range[0], arcsines <= radian_range[1]), output_ring, 0.0) else: return where(logical_or(arcsines >= radian_range[0], arcsines <= radian_range[1]), output_ring, 0.0)
def function(self,params): """Concentric rings.""" aspect_ratio = params['aspect_ratio'] x = self.pattern_x/aspect_ratio y = self.pattern_y thickness = params['thickness'] gaussian_width = params['smoothing'] size = params['size'] half_thickness = thickness / 2.0 distance_from_origin = sqrt(x**2+y**2) distance_from_ring_middle = fmod(distance_from_origin,size) distance_from_ring_middle = minimum(distance_from_ring_middle,size - distance_from_ring_middle) distance_from_ring = distance_from_ring_middle - half_thickness ring = 1.0 - greater_equal(distance_from_ring,0.0) sigmasq = gaussian_width*gaussian_width with float_error_ignore(): falloff = exp(divide(-distance_from_ring*distance_from_ring, 2.0*sigmasq)) return maximum(falloff, ring)
def histogram(data, nbins, range=None): """ Comes from Konrad Hinsen: Scientific Python """ data = Numeric.array(data, Numeric.Float) if range is None: min = Numeric.minimum.reduce(data) max = Numeric.maximum.reduce(data) else: min, max = range data = Numeric.repeat( data, Numeric.logical_and(Numeric.less_equal(data, max), Numeric.greater_equal(data, min))) # end if bin_width = (max - min) / nbins data = Numeric.floor((data - min) / bin_width).astype(Numeric.Int) histo = Numeric.add.reduce( Numeric.equal(Numeric.arange(nbins)[:, Numeric.NewAxis], data), -1) histo[-1] = histo[-1] + Numeric.add.reduce(Numeric.equal(nbins, data)) bins = min + bin_width * (Numeric.arange(nbins) + 0.5) return Numeric.transpose(Numeric.array([bins, histo]))
def getBuriedSurfaceTriangles(self, atomIndices=None, component=0, selnum=1, negate=0): """vfloat, vint, tri = getBuriedSurfaceTriangles(atomIndices=None, component=0, selnum=1, negate=0) Return the triangles of the specified SES component for which at least 'selnum' vertices are either buried (if negate=0) or not burried (if negate=1). 0 < selnum < 4. vfloat and vint hold the data for all vertices of the surface. tri contains the subset of the triangles that are buried. """ assert selnum in (1, 2, 3) vfloat, vint, tri = self.getTriangles(atomIndices, component=component) buriedFlag = vint[:, 2] if negate: buriedFlag = Numeric.logical_not(buriedFlag) #triBuried = Numeric.choose(tri[:,:3], buriedFlag) triBuried = Numeric.take(buriedFlag, tri[:, :3]) sum = Numeric.sum(triBuried, 1) faceInd = Numeric.nonzero(Numeric.greater_equal(sum, selnum)) faces = Numeric.take(tri, faceInd) return vfloat, vint, faces
def histogram(data, nbins, range = None): """ Create a histogram. Comes from Konrad Hinsen: Scientific Python @param data: data list or array @type data: [any] @param nbins: number of bins @type nbins: int @param range: data range to create histogram from (min val, max val) @type range: (float, float) OR None @return: array (2 x len(data) ) with start of bin and witdh of bin. @rtype: array """ data = Numeric.array(data, Numeric.Float) if range is None: min = Numeric.minimum.reduce(data) max = Numeric.maximum.reduce(data) else: min, max = range data = Numeric.repeat(data, Numeric.logical_and(Numeric.less_equal(data, max), Numeric.greater_equal(data, min))) bin_width = (max-min)/nbins data = Numeric.floor((data - min)/bin_width).astype(Numeric.Int) histo = Numeric.add.reduce(Numeric.equal( Numeric.arange(nbins)[:,Numeric.NewAxis], data), -1) histo[-1] = histo[-1] + Numeric.add.reduce(Numeric.equal(nbins, data)) bins = min + bin_width*(Numeric.arange(nbins)+0.5) return Numeric.transpose(Numeric.array([bins, histo]))
def function(self,params): """Archemidean spiral function.""" aspect_ratio = params['aspect_ratio'] x = self.pattern_x/aspect_ratio y = self.pattern_y thickness = params['thickness'] gaussian_width = params['smoothing'] size = params['size'] half_thickness = thickness/2.0 spacing = size*2*pi distance_from_origin = sqrt(x**2+y**2) distance_from_spiral_middle = fmod(spacing + distance_from_origin - size*arctan2(y,x),spacing) distance_from_spiral_middle = minimum(distance_from_spiral_middle,spacing - distance_from_spiral_middle) distance_from_spiral = distance_from_spiral_middle - half_thickness spiral = 1.0 - greater_equal(distance_from_spiral,0.0) sigmasq = gaussian_width*gaussian_width with float_error_ignore(): falloff = exp(divide(-distance_from_spiral*distance_from_spiral, 2.0*sigmasq)) return maximum(falloff, spiral)
def histogram(data, nbins, range = None): """ Comes from Konrad Hinsen: Scientific Python """ data = Numeric.array(data, Numeric.Float) if range is None: min = Numeric.minimum.reduce(data) max = Numeric.maximum.reduce(data) else: min, max = range data = Numeric.repeat(data, Numeric.logical_and(Numeric.less_equal(data, max), Numeric.greater_equal(data, min))) # end if bin_width = (max-min)/nbins data = Numeric.floor((data - min)/bin_width).astype(Numeric.Int) histo = Numeric.add.reduce(Numeric.equal( Numeric.arange(nbins)[:,Numeric.NewAxis], data), -1) histo[-1] = histo[-1] + Numeric.add.reduce(Numeric.equal(nbins, data)) bins = min + bin_width*(Numeric.arange(nbins)+0.5) return Numeric.transpose(Numeric.array([bins, histo]))
def function(self,params): """Hyperbolic function.""" aspect_ratio = params['aspect_ratio'] x = self.pattern_x/aspect_ratio y = self.pattern_y thickness = params['thickness'] gaussian_width = params['smoothing'] size = params['size'] half_thickness = thickness / 2.0 distance_from_vertex_middle = fmod(sqrt(absolute(x**2 - y**2)),size) distance_from_vertex_middle = minimum(distance_from_vertex_middle,size - distance_from_vertex_middle) distance_from_vertex = distance_from_vertex_middle - half_thickness hyperbola = 1.0 - greater_equal(distance_from_vertex,0.0) sigmasq = gaussian_width*gaussian_width with float_error_ignore(): falloff = exp(divide(-distance_from_vertex*distance_from_vertex, 2.0*sigmasq)) return maximum(falloff, hyperbola)
def histogram(data, nbins, range=None): """ Create a histogram. Comes from Konrad Hinsen: Scientific Python @param data: data list or array @type data: [any] @param nbins: number of bins @type nbins: int @param range: data range to create histogram from (min val, max val) @type range: (float, float) OR None @return: array (2 x len(data) ) with start of bin and witdh of bin. @rtype: array """ data = Numeric.array(data, Numeric.Float) if range is None: min = Numeric.minimum.reduce(data) max = Numeric.maximum.reduce(data) else: min, max = range data = Numeric.repeat( data, Numeric.logical_and(Numeric.less_equal(data, max), Numeric.greater_equal(data, min))) bin_width = (max - min) / nbins data = Numeric.floor((data - min) / bin_width).astype(Numeric.Int) histo = Numeric.add.reduce( Numeric.equal(Numeric.arange(nbins)[:, Numeric.NewAxis], data), -1) histo[-1] = histo[-1] + Numeric.add.reduce(Numeric.equal(nbins, data)) bins = min + bin_width * (Numeric.arange(nbins) + 0.5) return Numeric.transpose(Numeric.array([bins, histo]))
def hyperbola(x, y, thickness, gaussian_width, axis): """ Two conjugate hyperbolas with Gaussian fall-off which share the same asymptotes. abs(x^2/a^2 - y^2/b^2) = 1 As a = b = axis, these hyperbolas are rectangular. """ difference = absolute(x**2 - y**2) hyperbola = 1.0 - bitwise_xor(greater_equal(axis**2,difference),greater_equal(difference,(axis + thickness)**2)) distance_inside_hyperbola = sqrt(difference) - axis distance_outside_hyperbola = sqrt(difference) - axis - thickness sigmasq = gaussian_width*gaussian_width with float_error_ignore(): inner_falloff = exp(divide(-distance_inside_hyperbola*distance_inside_hyperbola, 2.0*sigmasq)) outer_falloff = exp(divide(-distance_outside_hyperbola*distance_outside_hyperbola, 2.0*sigmasq)) return maximum(hyperbola,maximum(inner_falloff,outer_falloff))
def ring(x, y, height, thickness, gaussian_width): """ Circular ring (annulus) with Gaussian fall-off after the solid ring-shaped region. """ radius = height/2.0 half_thickness = thickness/2.0 distance_from_origin = sqrt(x**2+y**2) distance_outside_outer_disk = distance_from_origin - radius - half_thickness distance_inside_inner_disk = radius - half_thickness - distance_from_origin ring = 1.0-bitwise_xor(greater_equal(distance_inside_inner_disk,0.0),greater_equal(distance_outside_outer_disk,0.0)) sigmasq = gaussian_width*gaussian_width if sigmasq==0.0: inner_falloff = x*0.0 outer_falloff = x*0.0 else: with float_error_ignore(): inner_falloff = exp(divide(-distance_inside_inner_disk*distance_inside_inner_disk, 2.0*sigmasq)) outer_falloff = exp(divide(-distance_outside_outer_disk*distance_outside_outer_disk, 2.0*sigmasq)) return maximum(inner_falloff,maximum(outer_falloff,ring))
def area(curve, start=0.0, stop=1.0): """ Numerically add up the area under the given curve. The curve is a 2-D array or list of tupples. The x-axis is the first column of this array (curve[:,0]). (originally taken from Biskit.Statistics.ROCalyzer) @param curve: a list of x,y coordinates @type curve: [ (y,x), ] or N.array @param start: lower boundary (in x) (default: 0.0) @type start: float @param stop: upper boundary (in x) (default: 1.0) @type stop: float @return: the area underneath the curve between start and stop. @rtype: float """ ## convert and swap axes curve = N.array(curve) c = N.zeros(N.shape(curve), curve.dtype) c[:, 0] = curve[:, 1] c[:, 1] = curve[:, 0] assert len(N.shape(c)) == 2 ## apply boundaries ## here we have a problem with flat curves mask = N.greater_equal(c[:, 1], start) mask *= N.less_equal(c[:, 1], stop) c = N.compress(mask, c, axis=0) ## fill to boundaries -- not absolutely accurate: we actually should ## interpolate to the neighboring points instead c = N.concatenate((N.array([ [c[0, 0], start], ]), c, N.array([ [c[-1, 0], stop], ]))) x = c[:, 1] y = c[:, 0] dx = x[1:] - x[:-1] # distance on x between points dy = y[1:] - y[:-1] # distance on y between points areas1 = y[:-1] * dx # the rectangles between all points areas2 = dx * dy / 2.0 # the triangles between all points return N.sum(areas1) + N.sum(areas2)
def radial(x, y, wide, gaussian_width): """ Radial grating - A sector of a circle with Gaussian fall-off. Parameter wide determines in wide of sector in radians. """ angle = absolute(arctan2(y,x)) half_wide = wide/2 radius = 1.0 - greater_equal(angle,half_wide) distance = angle - half_wide sigmasq = gaussian_width*gaussian_width with float_error_ignore(): falloff = exp(divide(-distance*distance, 2.0*sigmasq)) return maximum(radius,falloff)
def drawLines(self): # angle has to be provided in radians angle = self.angle self.circlePtsAngles = self.circlePtsAngles+angle self.circlePtsAngles = Numeric.remainder(self.circlePtsAngles, 2*math.pi) xcoords = Numeric.cos(self.circlePtsAngles) xsin = Numeric.sin(self.circlePtsAngles) if self.orient=='horizontal': w = self.innerbox[2] - self.innerbox[0] r = w/2 c = self.innerbox[0] + r y1 = self.innerbox[1] y2 = self.innerbox[3] else: w = self.innerbox[3] - self.innerbox[1] r = w/2 c = self.innerbox[1] + r y1 = self.innerbox[0] y2 = self.innerbox[2] cl = self.canvas.create_line setCoords = self.canvas.coords setOpt = self.canvas.itemconfigure pi2 = math.pi/2. drawLines = 0 co = Numeric.take(xcoords, Numeric.nonzero(Numeric.greater_equal(xsin, 0.0))) co = Numeric.sort(co) co = [-1]+list(co) for i in range(len(co)): x = c - int(co[i]*r) if self.orient=='horizontal': setCoords(self.linesIds[i], x, y1, x, y2) else: setCoords(self.linesIds[i], y1, x, y2, x) shopt = self.shadowLinesOptions[i] x = x + shopt[0] if self.orient=='horizontal': setCoords(self.shLinesIds[i], x, y1, x, y2) else: setCoords(self.shLinesIds[i], y1, x, y2, x) setOpt(self.shLinesIds[i], fill = shopt[1], width=shopt[2])
def drawLines(self): # angle has to be provided in radians angle = self.angle self.circlePtsAngles = self.circlePtsAngles + angle self.circlePtsAngles = Numeric.remainder(self.circlePtsAngles, 2 * math.pi) xcoords = Numeric.cos(self.circlePtsAngles) xsin = Numeric.sin(self.circlePtsAngles) if self.orient == 'horizontal': w = self.innerbox[2] - self.innerbox[0] r = w / 2 c = self.innerbox[0] + r y1 = self.innerbox[1] y2 = self.innerbox[3] else: w = self.innerbox[3] - self.innerbox[1] r = w / 2 c = self.innerbox[1] + r y1 = self.innerbox[0] y2 = self.innerbox[2] cl = self.canvas.create_line setCoords = self.canvas.coords setOpt = self.canvas.itemconfigure pi2 = math.pi / 2. drawLines = 0 co = Numeric.take(xcoords, Numeric.nonzero(Numeric.greater_equal(xsin, 0.0))) co = Numeric.sort(co) co = [-1] + list(co) for i in range(len(co)): x = c - int(co[i] * r) if self.orient == 'horizontal': setCoords(self.linesIds[i], x, y1, x, y2) else: setCoords(self.linesIds[i], y1, x, y2, x) shopt = self.shadowLinesOptions[i] x = x + shopt[0] if self.orient == 'horizontal': setCoords(self.shLinesIds[i], x, y1, x, y2) else: setCoords(self.shLinesIds[i], y1, x, y2, x) setOpt(self.shLinesIds[i], fill=shopt[1], width=shopt[2])
def area(curve, start=0.0, stop=1.0 ): """ Numerically add up the area under the given curve. The curve is a 2-D array or list of tupples. The x-axis is the first column of this array (curve[:,0]). (originally taken from Biskit.Statistics.ROCalyzer) @param curve: a list of x,y coordinates @type curve: [ (y,x), ] or N.array @param start: lower boundary (in x) (default: 0.0) @type start: float @param stop: upper boundary (in x) (default: 1.0) @type stop: float @return: the area underneath the curve between start and stop. @rtype: float """ ## convert and swap axes curve = N.array( curve ) c = N.zeros( N.shape(curve), curve.dtype ) c[:,0] = curve[:,1] c[:,1] = curve[:,0] assert len( N.shape( c ) ) == 2 ## apply boundaries ## here we have a problem with flat curves mask = N.greater_equal( c[:,1], start ) mask *= N.less_equal( c[:,1], stop ) c = N.compress( mask, c, axis=0 ) ## fill to boundaries -- not absolutely accurate: we actually should ## interpolate to the neighboring points instead c = N.concatenate((N.array([[c[0,0], start],]), c, N.array([[c[-1,0],stop ],])) ) x = c[:,1] y = c[:,0] dx = x[1:] - x[:-1] # distance on x between points dy = y[1:] - y[:-1] # distance on y between points areas1 = y[:-1] * dx # the rectangles between all points areas2 = dx * dy / 2.0 # the triangles between all points return N.sum(areas1) + N.sum(areas2)
def filterRange(self, key, vLow, vHigh): """ Get indices of items where vLow <= item[ key ] <= vHigh. @param key: item attribute @type key: any @param vLow: lower bound @type vLow: any @param vHigh: upper bound @type vHigh: any @return: array of int @rtype: array """ vLst = self.valuesOf(key) maskL = N.greater_equal(vLst, vLow) maskH = N.less_equal(vLst, vHigh) return N.nonzero(maskL * maskH)
def function(self,params): """Radial function.""" aspect_ratio = params['aspect_ratio'] x = self.pattern_x/aspect_ratio y = self.pattern_y gaussian_width = params['smoothing'] angle = absolute(arctan2(y,x)) half_length = params['arc_length']/2 radius = 1.0 - greater_equal(angle,half_length) distance = angle - half_length sigmasq = gaussian_width*gaussian_width with float_error_ignore(): falloff = exp(divide(-distance*distance, 2.0*sigmasq)) return maximum(radius, falloff)
def spiral(x, y, thickness, gaussian_width, density): """ Archemidean spiral with Gaussian fall-off outside the spiral curve. """ half_thickness = thickness/2.0 spacing = density*2*pi distance_from_origin = sqrt(x**2+y**2) distance_from_spiral_middle = fmod(spacing + distance_from_origin - density*arctan2(y,x),spacing) distance_from_spiral_middle = minimum(distance_from_spiral_middle,spacing - distance_from_spiral_middle) distance_from_spiral = distance_from_spiral_middle - half_thickness spiral = 1.0 - greater_equal(distance_from_spiral,0.0) sigmasq = gaussian_width*gaussian_width with float_error_ignore(): falloff = exp(divide(-distance_from_spiral*distance_from_spiral, 2.0*sigmasq)) return maximum(falloff,spiral)
def getBuriedSurfaceTriangles(self, atomIndices=None, component=0, selnum=1, negate=0): """vfloat, vint, tri = getBuriedSurfaceTriangles(atomIndices=None, component=0, selnum=1, negate=0) Return the triangles of the specified SES component for which at least 'selnum' vertices are either buried (if negate=0) or not burried (if negate=1). 0 < selnum < 4. vfloat and vint hold the data for all vertices of the surface. tri contains the subset of the triangles that are buried. """ assert selnum in (1,2,3) vfloat, vint, tri = self.getTriangles(atomIndices, component=component) buriedFlag = vint[:,2] if negate: buriedFlag = Numeric.logical_not(buriedFlag) triBuried = Numeric.choose(tri[:,:3], buriedFlag) sum = Numeric.sum(triBuried, 1) faceInd = Numeric.nonzero( Numeric.greater_equal(sum, selnum) ) faces = Numeric.take(tri, faceInd) return vfloat, vint, faces
def confidenceInterval(self, level): """ confidenceInterval(self, level) @param level: confidence level (e.g. 0.68 for stdev interval) @type level: float @return: start and end of the confidence interval containing |level|*100 % of the probability @rtype: float, float """ order = N.argsort(self.p).tolist() cumulative = N.add.accumulate(N.take(self.p, order)) * self.delta_x ind = N.nonzero(N.greater_equal(cumulative, 1. - level)) sub_set = order[ind[0]:] intervals = self.__find_intervals(sub_set) boundaries = [(self.x[i[0]], self.x[i[-1]]) for i in intervals] return tuple(boundaries)
def filterRange( self, infoKey, vLow, vHigh ): """ Get indices of Complexes where vLow <= c.info[ infoKey ] <= vHigh. Use:: filterRange( str_infoKey, vLow, vHigh ) @param infoKey: key for info dict @type infoKey: str @param vLow: upper value limit @type vLow: float @param vHigh: lower value limit @type vHigh: float @return: array of int @rtype: [int] """ vLst = self.valuesOf( infoKey ) maskL = N.greater_equal( vLst, vLow ) maskH = N.less_equal( vLst, vHigh ) return N.nonzero( maskL * maskH )
def findConfidenceInterval(self, x): """ findConfidenceInterval(self, x) Find the smallest possible density interval that still includes x. @param x: value @type x: float @return: convidence level, interval start and end @rtype: float, (float,float) """ closest = N.argmin(abs(self.x - x)) ind = N.nonzero(N.greater_equal(self.p, self.p[closest])).tolist() intervals = self.__find_intervals(ind) ## lens = N.array([len(i) for i in intervals]) levels = [N.sum(N.take(self.p, i)) for i in intervals] level = N.sum(levels) * self.delta_x boundaries = [(self.x[i[0]], self.x[i[-1]]) for i in intervals] return level, tuple(boundaries)
def __call__(self, data, data_min=None, data_max=None, val_min=None, val_max=None, map_type='linear', powerOf2=0): """ (data, data_min=None, data_max=None, val_min=None, val_max=None, map_type = 'linear', powerOf2=0) Maps an array of floats to integer values. data -- 3D numeric array; data_min, data_max -- min and max data values(other than actual array minimum/maximum) to map to integer values - val_min and val_max - in range (0 ... int_limit); map_type -- can be 'linear' or 'log'; powerOf2 -- if set to 1, then if the data array dimensions are not power of 2 - the returned array will be padded with zeros so that its dims are power of 2. """ # if data_min/max and val_min/max specified then the mapping # will proceed as follows: # [arr_min, data_min] is mapped to [int_min, val_min], # [data_min, data_max] is maped to [val_min, val_max], # [data_max, arr_max] is mapped to [val_max, int_limit]. int_limit = self.int_limit int_min = self.int_min shape = data.shape assert len(shape)==3 nx, ny, nz = shape arrsize = nx*ny*nz #arr_max = Numeric.maximum.reduce(data.ravel()) #arr_min = Numeric.minimum.reduce(data.ravel()) maxif = Numeric.maximum.reduce arr_max = maxif(maxif(maxif(data))) minif = Numeric.minimum.reduce arr_min = minif(minif(minif(data))) #print "min(arr)=%f" % arr_min #print "max(arr)=%f" % arr_max if val_min != None: assert val_min >= 0 and val_min < int_limit else: val_min = int_min if val_max != None: assert val_max <= int_limit and val_max > 0 else: val_max = int_limit if data_min != None: if data_min < arr_min: data_min = arr_min else: data_min = arr_min if data_max != None: if data_max > arr_max: data_max = arr_max else: data_max = arr_max print "mapping data_min %4f to val_min %d, data_max %4f to val_max %d"\ % (data_min, val_min, data_max, val_max) if map_type == 'linear': k2,c2 = self.ScaleMap((val_min, val_max), (data_min, data_max)) n_intervals = 3 if abs(data_min-arr_min) < 0.00001: # data_min==arr_min k1,c1 = k2, c2 n_intervals = n_intervals-1 else : k1, c1 = self.ScaleMap((int_min, val_min), (arr_min, data_min)) if abs(data_max-arr_max) < 0.00001: # data_max == arr_max k3, c3 = k2, c2 n_intervals = n_intervals-1 else: k3, c3 = self.ScaleMap((val_max, int_limit), (data_max, arr_max)) t1 = time() #print "n_intervals = ", n_intervals if n_intervals == 2: if data_max == arr_max: #print "data_max == arr_max" new_arr = Numeric.where(Numeric.less(data, data_min), k1*data+c1, k2*data+c2 ) elif data_min == arr_min: #print "data_min == arr_min" new_arr = Numeric.where(Numeric.greater_equal(data, data_max), k3*data+c3, k2*data+c2) elif n_intervals == 3: new_arr1 = Numeric.where(Numeric.less(data, data_min), k1*data+c1, k2*data+c2) new_arr = Numeric.where(Numeric.greater_equal(data, data_max), k3*data+c3, new_arr1) del(new_arr1) else : new_arr = k2*data+c2 arr = Numeric.transpose(new_arr).astype(self.int_type) del(new_arr) t2 = time() print "time to map : ", t2-t1 elif map_type == 'log': if arr_min < 0: diff = abs(arr_min)+1.0 elif arr_min >= 0 and arr_min < 1.0: diff = 1.0 elif arr_min >= 1.0: diff=0 k1, c1 = self.ScaleMap( (int_min, int_limit), (log(arr_min+diff), log(arr_max+diff)) ) arr=Numeric.transpose(k1*Numeric.log10(data+diff)+c1).astype(self.int_type) self.data_min = data_min self.data_max = data_max self.val_min = val_min self.val_max = val_max if powerOf2: nx1, ny1, nz1 = nx, ny, nz res, power = isPowerOf2(nx) if not res: nx1 = 2**power res, power = isPowerOf2(ny) if not res: ny1 = 2**power res, power = isPowerOf2(nz) if not res: nz1 = 2**power dx, dy, dz = 0, 0, 0 if nx1 != nx or ny1 != ny or nz1 != nz: #print "new data size: ", nx1,ny1,nz1 dx = (nx1-nx)/2. ; dy = (ny1-ny)/2. ; dz = (nz1-nz)/2. #narr = Numeric.zeros((nx1,ny1,nz1), self.int_type) #narr[:nx,:ny,:nz] = arr[:,:,:] narr = Numeric.zeros((nz1,ny1,nx1), self.int_type) narr[:nz,:ny,:nx] = arr[:,:,:] self.arr = narr #arr = Numeric.zeros((nx1,ny1,nz1), self.int_type) #arr[:nx,:ny,:nz] = new_arr[:,:,:] #arr = Numeric.transpose(arr).astype(self.int_type) #self.arr = arr return narr self.arr = arr return arr
def deNAN(a, value=0.0): nans = Numeric.logical_not( Numeric.less(a, 0.0) + Numeric.greater_equal(a, 0.0)) return Numeric.where(nans, value, a)