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): """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 __init__(self, point1=None, point2=None, slab=None): # Huaicai 4/23/05: added some comments below to help understand the code. if slab: # convert from 2d (x, y) coordinates into its 3d world (x, y, 0) #coordinates(the lower-left and upper-right corner). #In another word, the 3d coordinates minus the z offset of the plane x = dot(A(point1), A(point2)) # Get the vector from upper-right point to the lower-left point dx = subtract.reduce(x) # Get the upper-left and lower right corner points oc = x[1] + V(point2[0] * dot(dx, point2[0]), point2[1] * dot(dx, point2[1])) # Get the four 3d cooridinates on the bottom crystal-cutting plane sq1 = cat(x, oc) + slab.normal * dot(slab.point, slab.normal) # transfer the above 4 3d coordinates in parallel to get that on #the top plane, put them together sq1 = cat(sq1, sq1 + slab.thickness * slab.normal) self.data = V(maximum.reduce(sq1), minimum.reduce(sq1)) elif point2: # just 2 3d points self.data = V(maximum(point1, point2), minimum(point1, point2)) elif point1: # list of points: could be 2d or 3d? +/- 1.8 to make the bounding #box enclose the vDw ball of an atom? self.data = V( maximum.reduce(point1) + BBOX_MARGIN, minimum.reduce(point1) - BBOX_MARGIN) else: # a null bbox self.data = None
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 Map(values, colorMap, mini=None, maxi=None): """Get colors corresponding to values in a colormap""" values = Numeric.array(values) if len(values.shape)==2 and values.shape[1]==1: values.shape = ( values.shape[0], ) elif len(values.shape) > 1: print 'ERROR: values array has bad shape' return None cmap = Numeric.array(colorMap) if len(cmap.shape) !=2 or cmap.shape[1] not in (3,4): print 'ERROR: colorMap array has bad shape' return None if mini is None: mini = min(values) else: values = Numeric.maximum(values, mini) if maxi is None: maxi = max(values) else: values = Numeric.minimum(values, maxi) valrange = maxi-mini if valrange < 0.0001: ind = Numeric.ones( values.shape ) else: colrange = cmap.shape[0]-1 ind = ((values-mini) * colrange) / valrange col = Numeric.take(colorMap, ind.astype(viewerConst.IPRECISION)) return col
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 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 __init__(self, point1 = None, point2 = None, slab = None): # Huaicai 4/23/05: added some comments below to help understand the code. if slab: # convert from 2d (x, y) coordinates into its 3d world (x, y, 0) #coordinates(the lower-left and upper-right corner). #In another word, the 3d coordinates minus the z offset of the plane x = dot(A(point1), A(point2)) # Get the vector from upper-right point to the lower-left point dx = subtract.reduce(x) # Get the upper-left and lower right corner points oc = x[1] + V(point2[0]*dot(dx,point2[0]), point2[1]*dot(dx,point2[1])) # Get the four 3d cooridinates on the bottom crystal-cutting plane sq1 = cat(x,oc) + slab.normal*dot(slab.point, slab.normal) # transfer the above 4 3d coordinates in parallel to get that on #the top plane, put them together sq1 = cat(sq1, sq1+slab.thickness*slab.normal) self.data = V(maximum.reduce(sq1), minimum.reduce(sq1)) elif point2: # just 2 3d points self.data = V(maximum(point1, point2), minimum(point1, point2)) elif point1: # list of points: could be 2d or 3d? +/- 1.8 to make the bounding #box enclose the vDw ball of an atom? self.data = V(maximum.reduce(point1) + BBOX_MARGIN, minimum.reduce(point1) - BBOX_MARGIN) else: # a null bbox self.data = None
def Map(self, values, mini='not passed', maxi='not passed'): """Get colors corresponding to values in a colormap. if mini or maxi are provided, self.mini and self.maxi are not used and stay inchanged. if mini or maxi are not provided or set to None, self.mini and self.maxi are used instead. if mini or maxi are set to None, self.mini and self.maxi are ignored """ #print "Map", mini, maxi, self.mini, self.maxi, values values = Numeric.array(values) if len(values.shape)==2 and values.shape[1]==1: values.shape = ( values.shape[0], ) elif len(values.shape) > 1: raise ValueError('ERROR! values array has bad shape') ramp = Numeric.array(self.ramp) if len(ramp.shape) !=2 or ramp.shape[1] not in (3,4): raise ValueError('ERROR! colormap array has bad shape') if mini == 'not passed': mini = self.mini if maxi == 'not passed': maxi = self.maxi if mini is None: mini = min(values) else: # All the values < mini will be set to mini values = Numeric.maximum(values, mini) if maxi is None: maxi = max(values) else: values = Numeric.minimum(values, maxi) # mini and maxi are now set if mini >= maxi: txt = 'mini:%f must be < maxi:%f'%(mini, maxi) warnings.warn( txt ) valrange = maxi - mini if valrange < 0.0001: ind = Numeric.ones( values.shape ) else: colrange = ramp.shape[0] ind = (values - mini) * (colrange/float(valrange)) ind = ind.astype(viewerConst.IPRECISION) ind = Numeric.minimum(ind, colrange - 1) col = Numeric.take(self.ramp, ind ) self.lastMini = mini self.lastMaxi = maxi return col
def Map(self, values, mini='not passed', maxi='not passed'): """Get colors corresponding to values in a colormap. if mini or maxi are provided, self.mini and self.maxi are not used and stay inchanged. if mini or maxi are not provided or set to None, self.mini and self.maxi are used instead. if mini or maxi are set to None, self.mini and self.maxi are ignored """ #print "Map", mini, maxi, self.mini, self.maxi, values values = Numeric.array(values) if len(values.shape) == 2 and values.shape[1] == 1: values.shape = (values.shape[0], ) elif len(values.shape) > 1: raise ValueError('ERROR! values array has bad shape') ramp = Numeric.array(self.ramp) if len(ramp.shape) != 2 or ramp.shape[1] not in (3, 4): raise ValueError('ERROR! colormap array has bad shape') if mini == 'not passed': mini = self.mini if maxi == 'not passed': maxi = self.maxi if mini is None: mini = min(values) else: # All the values < mini will be set to mini values = Numeric.maximum(values, mini) if maxi is None: maxi = max(values) else: values = Numeric.minimum(values, maxi) # mini and maxi are now set if mini >= maxi: txt = 'mini:%f must be < maxi:%f' % (mini, maxi) warnings.warn(txt) valrange = maxi - mini if valrange < 0.0001: ind = Numeric.ones(values.shape) else: colrange = ramp.shape[0] ind = (values - mini) * (colrange / float(valrange)) ind = ind.astype(viewerConst.IPRECISION) ind = Numeric.minimum(ind, colrange - 1) col = Numeric.take(self.ramp, ind) self.lastMini = mini self.lastMaxi = maxi return col
def smooth_rectangle(x, y, rec_w, rec_h, gaussian_width_x, gaussian_width_y): """ Rectangle with a solid central region, then Gaussian fall-off at the edges. """ gaussian_x_coord = abs(x) - rec_w / 2.0 gaussian_y_coord = abs(y) - rec_h / 2.0 box_x = less(gaussian_x_coord, 0.0) box_y = less(gaussian_y_coord, 0.0) sigmasq_x = gaussian_width_x * gaussian_width_x sigmasq_y = gaussian_width_y * gaussian_width_y with float_error_ignore(): falloff_x=x*0.0 if sigmasq_x==0.0 else \ exp(divide(-gaussian_x_coord*gaussian_x_coord,2*sigmasq_x)) falloff_y=y*0.0 if sigmasq_y==0.0 else \ exp(divide(-gaussian_y_coord*gaussian_y_coord,2*sigmasq_y)) return minimum(maximum(box_x, falloff_x), maximum(box_y, falloff_y))
def smooth_rectangle(x, y, rec_w, rec_h, gaussian_width_x, gaussian_width_y): """ Rectangle with a solid central region, then Gaussian fall-off at the edges. """ gaussian_x_coord = abs(x)-rec_w/2.0 gaussian_y_coord = abs(y)-rec_h/2.0 box_x=less(gaussian_x_coord,0.0) box_y=less(gaussian_y_coord,0.0) sigmasq_x=gaussian_width_x*gaussian_width_x sigmasq_y=gaussian_width_y*gaussian_width_y with float_error_ignore(): falloff_x=x*0.0 if sigmasq_x==0.0 else \ exp(divide(-gaussian_x_coord*gaussian_x_coord,2*sigmasq_x)) falloff_y=y*0.0 if sigmasq_y==0.0 else \ exp(divide(-gaussian_y_coord*gaussian_y_coord,2*sigmasq_y)) return minimum(maximum(box_x,falloff_x), maximum(box_y,falloff_y))
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 _point2ClientCoord(self, corner1, corner2): """Converts user point coords to client screen int coords x,y,width,height""" c1= _Numeric.array(corner1) c2= _Numeric.array(corner2) # convert to screen coords pt1= c1*self._pointScale+self._pointShift pt2= c2*self._pointScale+self._pointShift # make height and width positive pul= _Numeric.minimum(pt1,pt2) # Upper left corner plr= _Numeric.maximum(pt1,pt2) # Lower right corner rectWidth, rectHeight= plr-pul ptx,pty= pul return ptx, pty, rectWidth, rectHeight
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 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 OnMouseLeftUp(self, event): if self._zoomEnabled: if self._hasDragged == True: self._drawRubberBand(self._zoomCorner1, self._zoomCorner2) # remove old self._zoomCorner2[0], self._zoomCorner2[1]= self._getXY(event) self._hasDragged = False # reset flag minX, minY= _Numeric.minimum( self._zoomCorner1, self._zoomCorner2) maxX, maxY= _Numeric.maximum( self._zoomCorner1, self._zoomCorner2) self.last_PointLabel = None #reset pointLabel if self.last_draw != None: self._Draw(self.last_draw[0], xAxis = (minX,maxX), yAxis = (minY,maxY), dc = None) #else: # A box has not been drawn, zoom in on a point ## this interfered with the double click, so I've disables it. # X,Y = self._getXY(event) # self.Zoom( (X,Y), (self._zoomInFactor,self._zoomInFactor) ) if self._dragEnabled: self.SetCursor(self.HandCursor) if self.canvas.HasCapture(): self.canvas.ReleaseMouse()
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 _legendWH(self, dc, graphics): """Returns the size in screen units for legend box""" if self._legendEnabled != True: legendBoxWH= symExt= txtExt= (0,0) else: # find max symbol size symExt= graphics.getSymExtent(self.printerScale) # find max legend text extent dc.SetFont(self._getFont(self._fontSizeLegend)) txtList= graphics.getLegendNames() txtExt= dc.GetTextExtent(txtList[0]) for txt in graphics.getLegendNames()[1:]: txtExt= _Numeric.maximum(txtExt,dc.GetTextExtent(txt)) maxW= symExt[0]+txtExt[0] maxH= max(symExt[1],txtExt[1]) # padding .1 for lhs of legend box and space between lines maxW= maxW* 1.1 maxH= maxH* 1.1 * len(txtList) dc.SetFont(self._getFont(self._fontSizeAxis)) legendBoxWH= (maxW,maxH) return (legendBoxWH, symExt, txtExt)
def isin(self, pt): return (minimum(pt,self.data[1]) == self.data[1] and maximum(pt,self.data[0]) == self.data[0])
def isin(self, pt): return (minimum(pt, self.data[1]) == self.data[1] and maximum(pt, self.data[0]) == self.data[0])