source: sasview/guiframe/local_perspectives/plotting/boxSum.py @ fcc5680

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalccostrafo411magnetic_scattrelease-4.1.1release-4.1.2release-4.2.2release_4.0.1ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since fcc5680 was 55a0dc1, checked in by Gervaise Alina <gervyh@…>, 14 years ago

remove reference to guicomm in guiframe

  • Property mode set to 100644
File size: 31.3 KB
RevLine 
[78ed1ad]1
2
3
4import math
5import wx
[eba08f1a]6from copy import deepcopy
7from BaseInteractor import _BaseInteractor
[55a0dc1]8from sans.guiframe.events import SlicerParamUpdateEvent
9from sans.guiframe.events import EVT_SLICER_PARS
10from sans.guiframe.events import StatusEvent
[eba08f1a]11
12
[78ed1ad]13class BoxSum(_BaseInteractor):
14    """
[32c0841]15        Boxsum Class: determine 2 rectangular area to compute
16        the sum of pixel of a Data.
[eba08f1a]17        Uses PointerInteractor , VerticalDoubleLine,HorizontalDoubleLine.
18        @param zorder:  Artists with lower zorder values are drawn first.
19        @param x_min: the minimum value of the x coordinate
20        @param x_max: the maximum value of the x coordinate
21        @param y_min: the minimum value of the y coordinate
22        @param y_max: the maximum value of the y coordinate
23
[78ed1ad]24    """
[32c0841]25    def __init__(self, base, axes, color='black', zorder=3, x_min=0.008,
[eba08f1a]26                  x_max=0.008, y_min=0.0025, y_max=0.0025):
[32c0841]27        """
28        """
[78ed1ad]29        _BaseInteractor.__init__(self, base, axes, color=color)
[eba08f1a]30        ## class initialization
31        ## list of Boxsmun markers
[78ed1ad]32        self.markers = []
33        self.axes = axes
[eba08f1a]34        ## connect the artist for the motion
[78ed1ad]35        self.connect = self.base.connect
[eba08f1a]36        ## when qmax is reached the selected line is reset the its previous value
37        self.qmax = min(self.base.data2D.xmax, self.base.data2D.xmin)
38        ## Define the boxsum limits
[32c0841]39        self.xmin = -1 * 0.5 * min(math.fabs(self.base.data2D.xmax),
40                                  math.fabs(self.base.data2D.xmin))
41        self.ymin = -1 * 0.5 * min(math.fabs(self.base.data2D.xmax),
[614ce1b1]42                                  math.fabs(self.base.data2D.xmin))
[32c0841]43        self.xmax = 0.5 * min(math.fabs(self.base.data2D.xmax),
44                              math.fabs(self.base.data2D.xmin))
45        self.ymax = 0.5 * min(math.fabs(self.base.data2D.xmax),
46                              math.fabs(self.base.data2D.xmin))
[eba08f1a]47        ## center of the boxSum
[32c0841]48        self.center_x = 0.0002
49        self.center_y = 0.0003
[78ed1ad]50        ## Number of points on the plot
51        self.nbins = 20
[eba08f1a]52        ## Define initial result the summation
[32c0841]53        self.count = 0
54        self.error = 0
[eba08f1a]55        ## Flag to determine if the current figure has moved
56        ## set to False == no motion , set to True== motion
[32c0841]57        self.has_move = False
[eba08f1a]58        ## Create Boxsum edges
[32c0841]59        self.horizontal_lines= HorizontalDoubleLine(self,
60                                                    self.base.subplot,
61                                                    color='blue',
[2a3a890]62                                                      zorder=zorder,
[32c0841]63                                                      y=self.ymax,
64                                                      x=self.xmax,
65                                                      center_x=self.center_x,
66                                                      center_y=self.center_y)
[2a3a890]67        self.horizontal_lines.qmax = self.qmax
[78ed1ad]68       
[32c0841]69        self.vertical_lines= VerticalDoubleLine(self,
70                                                self.base.subplot,
71                                                color='black',
72                                                zorder=zorder,
73                                                y=self.ymax,
74                                                x=self.xmax,
75                                                center_x=self.center_x,
76                                                center_y=self.center_y)
[2a3a890]77        self.vertical_lines.qmax = self.qmax
[eba08f1a]78       
[32c0841]79        self.center= PointInteractor(self,
80                                     self.base.subplot,color='grey',
81                                    zorder=zorder,
[2a3a890]82                                    center_x= self.center_x,
83                                    center_y= self.center_y)
[eba08f1a]84        ## Save the name of the slicer panel associate with this slicer
[32c0841]85        self.panel_name = ""   
[eba08f1a]86        ## Update and post slicer parameters 
[78ed1ad]87        self.update()
[92c2345]88        self._post_data()
[eba08f1a]89        ## Bind to slice parameter events
[18eba35]90        self.base.Bind(EVT_SLICER_PARS, self._onEVT_SLICER_PARS)
[6d920cd]91       
[0bd2cd8]92    def set_panel_name(self, name):
[eba08f1a]93        """
94            Store the name of the panel associated to this slicer
95            @param name: the name of this panel
96        """
[32c0841]97        self.panel_name = name
[6d920cd]98       
[78ed1ad]99    def _onEVT_SLICER_PARS(self, event):
[eba08f1a]100        """
101            receive an event containing parameters values to reset the slicer
102            @param event: event of type SlicerParameterEvent with params as
103            attribute
104        """
105        ## Post e message to declare what kind of event has being received
[32c0841]106        wx.PostEvent(self.base.parent,
107                     StatusEvent(status="Boxsum._onEVT_SLICER_PARS"))
[78ed1ad]108        event.Skip()
[eba08f1a]109        ## reset the slicer with the values contains the event.params dictionary
[78ed1ad]110        if event.type == self.__class__.__name__:
[92c2345]111            self.set_params(event.params)
[78ed1ad]112            self.base.update()
113
114    def set_layer(self, n):
[eba08f1a]115        """
[32c0841]116        Allow adding plot to the same panel
117        :param n: the number of layer
[eba08f1a]118        """
[78ed1ad]119        self.layernum = n
120        self.update()
121       
122    def clear(self):
[eba08f1a]123        """
[32c0841]124        Clear the slicer and all connected events related to this slicer
[eba08f1a]125        """
[78ed1ad]126        self.clear_markers()
[2a3a890]127        self.horizontal_lines.clear()
128        self.vertical_lines.clear()
129        self.center.clear()
[18eba35]130        self.base.connect.clearall()
131        self.base.Unbind(EVT_SLICER_PARS)
[78ed1ad]132       
133    def update(self):
134        """
[32c0841]135        Respond to changes in the model by recalculating the profiles and
136        resetting the widgets.
[78ed1ad]137        """
[eba08f1a]138        ## check if the center point has moved and update the figure accordingly
[2a3a890]139        if self.center.has_move:
140            self.center.update()
141            self.horizontal_lines.update( center= self.center)
142            self.vertical_lines.update( center= self.center)
[32c0841]143        ## check if the horizontal lines have moved and
144        #update the figure accordingly   
[2a3a890]145        if self.horizontal_lines.has_move:
146            self.horizontal_lines.update()
147            self.vertical_lines.update(y1=self.horizontal_lines.y1,
148                                       y2=self.horizontal_lines.y2,
[32c0841]149                                       height=self.horizontal_lines.half_height)
150        ## check if the vertical lines have moved and
151        #update the figure accordingly   
[2a3a890]152        if self.vertical_lines.has_move:
153            self.vertical_lines.update()
154            self.horizontal_lines.update(x1=self.vertical_lines.x1,
155                                         x2=self.vertical_lines.x2,
156                                         width=self.vertical_lines.half_width)
[78ed1ad]157           
158    def save(self, ev):
159        """
160        Remember the roughness for this layer and the next so that we
161        can restore on Esc.
162        """
163        self.base.freeze_axes()
[2a3a890]164        self.horizontal_lines.save(ev)
165        self.vertical_lines.save(ev)
166        self.center.save(ev)
167       
[78ed1ad]168    def _post_data(self):
[eba08f1a]169        """
[32c0841]170        Get the limits of the boxsum and compute the sum of the pixel
171        contained in that region and the error on that sum
[eba08f1a]172        """
173        ## Data 2D for which the pixel will be summed
[78ed1ad]174        data = self.base.data2D
[eba08f1a]175        ## the region of the summation
[32c0841]176        x_min = self.horizontal_lines.x2
177        x_max = self.horizontal_lines.x1
178        y_min = self.vertical_lines.y2
179        y_max = self.vertical_lines.y1
[eba08f1a]180        ##computation of the sum and its error
[32c0841]181        from DataLoader.manipulations import Boxavg
182        box =  Boxavg(x_min=x_min, x_max=x_max, y_min=y_min, y_max=y_max)
[92c2345]183        self.count, self.error = box(self.base.data2D)
[32c0841]184       
[78ed1ad]185    def moveend(self, ev):
[eba08f1a]186        """
187            After a dragging motion this function is called to compute
188            the error and the sum of pixel of a given data 2D
189        """
[78ed1ad]190        self.base.thaw_axes()
[eba08f1a]191        ## compute error an d sum of data's pixel
[54cc36a]192        self._post_data()
[eba08f1a]193        ## Create and event ( posted to guiframe)that  set the
194        ##current slicer parameter to a panel of name self.panel_name
[32c0841]195        self.type = self.__class__.__name__
196        params = self.get_params()
197        event = SlicerParamUpdateEvent(type=self.type,
198                                       params=params,
199                                       panel_name=self.panel_name)
[0bd2cd8]200        wx.PostEvent(self.base.parent, event)
[92c2345]201       
[78ed1ad]202    def restore(self):
203        """
204        Restore the roughness for this layer.
205        """
[2a3a890]206        self.horizontal_lines.restore()
207        self.vertical_lines.restore()
208        self.center.restore()
[eba08f1a]209       
[78ed1ad]210    def move(self, x, y, ev):
211        """
212        Process move to a new position, making sure that the move is allowed.
213        """
[2a3a890]214        pass
215   
[78ed1ad]216    def set_cursor(self, x, y):
[32c0841]217        """
218        """
[78ed1ad]219        pass
220       
221    def get_params(self):
[eba08f1a]222        """
[32c0841]223        Store a copy of values of parameters of the slicer into a dictionary.
224        :return params: the dictionary created
[eba08f1a]225        """
[78ed1ad]226        params = {}
[32c0841]227        params["Width"] = math.fabs(self.vertical_lines.half_width) * 2
228        params["Height"] = math.fabs(self.horizontal_lines.half_height) * 2 
[2a3a890]229        params["center_x"] = self.center.x
[32c0841]230        params["center_y"] = self.center.y
[0f6d05f8]231        params["count"] = self.count
[32c0841]232        params["errors"] = self.error
[78ed1ad]233        return params
234   
[92c2345]235    def get_result(self):
236        """
237            return the result of box summation
238        """
[32c0841]239        result = {}
[92c2345]240        result["count"] = self.count
241        result["error"] = self.error
242        return result
243       
[78ed1ad]244    def set_params(self, params):
[eba08f1a]245        """
[32c0841]246        Receive a dictionary and reset the slicer with values contained
247        in the values of the dictionary.
248        :param params: a dictionary containing name of slicer parameters and
[eba08f1a]249            values the user assigned to the slicer.
250        """
[ee69839]251        x_max = math.fabs(params["Width"] )/2
252        y_max = math.fabs(params["Height"] )/2
[78ed1ad]253       
[32c0841]254        self.center_x = params["center_x"] 
255        self.center_y = params["center_y"]
[eba08f1a]256        #update the slicer given values of params
[32c0841]257        self.center.update(center_x=self.center_x, center_y=self.center_y)
258        self.horizontal_lines.update(center=self.center,
259                                     width=x_max, height=y_max)
260        self.vertical_lines.update(center=self.center,
261                                    width=x_max, height=y_max)
[eba08f1a]262        #compute the new error and sum given values of params
[78ed1ad]263        self._post_data()
[2a3a890]264       
[78ed1ad]265    def freeze_axes(self):
[32c0841]266        """
267        """
[78ed1ad]268        self.base.freeze_axes()
269       
270    def thaw_axes(self):
[32c0841]271        """
272        """
[78ed1ad]273        self.base.thaw_axes()
274
275    def draw(self):
[32c0841]276        """
277        """
[78ed1ad]278        self.base.draw()
[eba08f1a]279       
280       
281       
[2a3a890]282class PointInteractor(_BaseInteractor):
[78ed1ad]283    """
[32c0841]284    Draw a point that can be dragged with the marker.
285    this class controls the motion the center of the BoxSum
[78ed1ad]286    """
[32c0841]287    def __init__(self, base, axes, color='black', zorder=5, center_x=0.0,
288                 center_y=0.0):
289        """
290        """
[78ed1ad]291        _BaseInteractor.__init__(self, base, axes, color=color)
[eba08f1a]292        ## Initialization the class
[78ed1ad]293        self.markers = []
294        self.axes = axes
[eba08f1a]295        # center coordinates
[2a3a890]296        self.x = center_x
297        self.y = center_y
[eba08f1a]298        ## saved value of the center coordinates
[2a3a890]299        self.save_x = center_x
300        self.save_y = center_y
[eba08f1a]301        ## Create a marker
[2a3a890]302        try:
303            self.center_marker = self.axes.plot([self.x],[self.y], linestyle='',
304                                          marker='s', markersize=10,
305                                          color=self.color, alpha=0.6,
306                                          pickradius=5, label="pick", 
[32c0841]307                                          # Prefer this to other lines
308                                          zorder=zorder, 
[2a3a890]309                                          visible=True)[0]
310        except:
311            self.center_marker = self.axes.plot([self.x],[self.y], linestyle='',
312                                          marker='s', markersize=10,
313                                          color=self.color, alpha=0.6,
314                                          label="pick", 
315                                          visible=True)[0]
[32c0841]316            message  = "\nTHIS PROTOTYPE NEEDS THE LATEST VERSION"
317            message += " OF MATPLOTLIB.\n Get the SVN version that is "
318            message += "at least as recent as June 1, 2007"
319            owner = self.base.base.parent
320            wx.PostEvent(owner,
321                         StatusEvent(status="AnnulusSlicer: %s" % message))
[eba08f1a]322        ## Draw a point
[32c0841]323        self.center = self.axes.plot([self.x], [self.y],
[78ed1ad]324                                      linestyle='-', marker='',
325                                      color=self.color,
326                                      visible=True)[0]
[eba08f1a]327        ## Flag to determine the motion this point
[32c0841]328        self.has_move = False   
[eba08f1a]329        ## connecting the marker to allow them to move
[2a3a890]330        self.connect_markers([self.center_marker])
[eba08f1a]331        ## Update the figure
[78ed1ad]332        self.update()
[54cc36a]333   
[78ed1ad]334    def set_layer(self, n):
[eba08f1a]335        """
336            Allow adding plot to the same panel
337            @param n: the number of layer
338        """
[78ed1ad]339        self.layernum = n
340        self.update()
341       
342    def clear(self):
[eba08f1a]343        """
344            Clear this figure and its markers
345        """
[78ed1ad]346        self.clear_markers()
347        try:
[2a3a890]348            self.center.remove()
[54cc36a]349            self.center_marker.remove()
[78ed1ad]350        except:
351            # Old version of matplotlib
352            for item in range(len(self.axes.lines)):
353                del self.axes.lines[0]
[eba08f1a]354 
[2a3a890]355    def update(self, center_x=None,center_y=None):
[78ed1ad]356        """
[eba08f1a]357            Draw the new roughness on the graph.
[78ed1ad]358        """
[32c0841]359        if center_x != None:
360            self.x = center_x
361        if center_y != None:
362            self.y = center_y
[2a3a890]363        self.center_marker.set(xdata=[self.x], ydata=[self.y])
364        self.center.set(xdata=[self.x], ydata=[self.y])
365       
[78ed1ad]366    def save(self, ev):
367        """
368        Remember the roughness for this layer and the next so that we
369        can restore on Esc.
370        """
[32c0841]371        self.save_x = self.x
372        self.save_y = self.y
[78ed1ad]373        self.base.freeze_axes()
374       
[32c0841]375    def moveend(self, ev):
376        """
377        """
[78ed1ad]378        self.has_move=False
379        self.base.moveend(ev)
380           
381    def restore(self):
382        """
383        Restore the roughness for this layer.
384        """
[32c0841]385        self.y = self.save_y
386        self.x = self.save_x
387   
[78ed1ad]388    def move(self, x, y, ev):
389        """
390        Process move to a new position, making sure that the move is allowed.
391        """
[32c0841]392        self.x = x
393        self.y = y
394        self.has_move = True
[78ed1ad]395        self.base.base.update()
396       
397    def set_cursor(self, x, y):
[32c0841]398        """
399        """
[78ed1ad]400        self.move(x, y, None)
401        self.update()
[32c0841]402   
[78ed1ad]403    def get_params(self):
[32c0841]404        """
405        """
[78ed1ad]406        params = {}
[2a3a890]407        params["x"] = self.x
408        params["y"] = self.y
[78ed1ad]409        return params
410   
411    def set_params(self, params):
[32c0841]412        """
413        """
[2a3a890]414        center_x = params["x"] 
415        center_y = params["y"] 
[32c0841]416        self.update(center_x=center_x, center_y=center_y)
[2a3a890]417       
[78ed1ad]418       
[eba08f1a]419class VerticalDoubleLine(_BaseInteractor):
[78ed1ad]420    """
[eba08f1a]421         Draw 2 vertical lines moving in opposite direction and centered on
422         a point (PointInteractor)
[78ed1ad]423    """
[32c0841]424    def __init__(self, base, axes, color='black', zorder=5, x=0.5,y=0.5,
425                 center_x=0.0, center_y=0.0):
426        """
427        """
[78ed1ad]428        _BaseInteractor.__init__(self, base, axes, color=color)
[eba08f1a]429        ## Initialization the class
[78ed1ad]430        self.markers = []
431        self.axes = axes
[eba08f1a]432        ## Center coordinates
[2a3a890]433        self.center_x = center_x
434        self.center_y = center_y
[eba08f1a]435        ## defined end points vertical lignes and their saved values
[32c0841]436        self.y1 = y + self.center_y
[2a3a890]437        self.save_y1= self.y1
438       
[32c0841]439        delta = self.y1 - self.center_y
440        self.y2 = self.center_y - delta
441        self.save_y2 = self.y2
[2a3a890]442       
[32c0841]443        self.x1 = x + self.center_x
[2a3a890]444        self.save_x1 = self.x1
445         
[32c0841]446        delta = self.x1 - self.center_x
447        self.x2 = self.center_x - delta
[2a3a890]448        self.save_x2 = self.x2
[eba08f1a]449        ## save the color of the line
450        self.color = color
451        ## the height of the rectangle
[32c0841]452        self.half_height = math.fabs(y)
453        self.save_half_height = math.fabs(y)
[eba08f1a]454        ## the with of the rectangle
[32c0841]455        self.half_width = math.fabs(self.x1- self.x2)/2
456        self.save_half_width = math.fabs(self.x1- self.x2)/2
[eba08f1a]457        ## Create marker
[2a3a890]458        try:
459            self.right_marker = self.axes.plot([self.x1],[0], linestyle='',
460                                          marker='s', markersize=10,
461                                          color=self.color, alpha=0.6,
462                                          pickradius=5, label="pick", 
[32c0841]463                                          # Prefer this to other lines
464                                          zorder=zorder, visible=True)[0]
[2a3a890]465        except:
466            self.right_marker = self.axes.plot([self.x1],[0], linestyle='',
467                                          marker='s', markersize=10,
468                                          color=self.color, alpha=0.6,
[32c0841]469                                          label="pick", visible=True)[0]
470            message  = "\nTHIS PROTOTYPE NEEDS THE LATEST "
471            message += "VERSION OF MATPLOTLIB\n Get the SVN version that"
472            message += " is at least as recent as June 1, 2007"
473            owner = self.base.base.parent
474            wx.PostEvent(owner,
475                         StatusEvent(status="AnnulusSlicer: %s" % message))
[2a3a890]476           
[eba08f1a]477        ## define the left and right lines of the rectangle
[32c0841]478        self.right_line = self.axes.plot([self.x1, self.x1], [self.y1, self.y2],
[78ed1ad]479                                      linestyle='-', marker='',
[32c0841]480                                      color=self.color, visible=True)[0]
481        self.left_line = self.axes.plot([self.x2, self.x2], [self.y1, self.y2],
[2a3a890]482                                      linestyle='-', marker='',
[32c0841]483                                      color=self.color, visible=True)[0]
[eba08f1a]484        ## Flag to determine if the lines have moved
[32c0841]485        self.has_move = False 
[eba08f1a]486        ## connection the marker and draw the pictures 
[2a3a890]487        self.connect_markers([self.right_marker])
[78ed1ad]488        self.update()
489
490    def set_layer(self, n):
[eba08f1a]491        """
[32c0841]492        Allow adding plot to the same panel
493        :param n: the number of layer
[eba08f1a]494        """
[78ed1ad]495        self.layernum = n
496        self.update()
497       
498    def clear(self):
[eba08f1a]499        """
[32c0841]500        Clear this slicer  and its markers
[eba08f1a]501        """
[78ed1ad]502        self.clear_markers()
503        try:
[54cc36a]504            self.right_marker.remove()
[2a3a890]505            self.right_line.remove()
506            self.left_line.remove()
[78ed1ad]507        except:
508            # Old version of matplotlib
509            for item in range(len(self.axes.lines)):
510                del self.axes.lines[0]
[eba08f1a]511   
[32c0841]512    def update(self, x1=None, x2=None, y1=None, y2=None,width=None,
513                height=None, center=None):
514        """
515        Draw the new roughness on the graph.
516        :param x1: new maximum value of x coordinates
517        :param x2: new minimum value of x coordinates
518        :param y1: new maximum value of y coordinates
519        :param y2: new minimum value of y coordinates
520        :param width: is the width of the new rectangle
521        :param height: is the height of the new rectangle
522        :param center: provided x, y  coordinates of the center point
[78ed1ad]523        """
[eba08f1a]524        ## save the new height, witdh of the rectangle if given as a param
[32c0841]525        if width != None:
526            self.half_width = width
527        if height != None:
528            self.half_height = height
[eba08f1a]529        ## If new  center coordinates are given draw the rectangle
530        ##given these value
[32c0841]531        if center != None:
532            self.center_x = center.x
533            self.center_y = center.y
[2a3a890]534            self.x1 = self.half_width + self.center_x
535            self.x2= -self.half_width + self.center_x
536            self.y1 = self.half_height + self.center_y
537            self.y2= -self.half_height + self.center_y
538         
[32c0841]539            self.right_marker.set(xdata=[self.x1], ydata=[self.center_y])
540            self.right_line.set(xdata=[self.x1, self.x1], 
541                                ydata=[self.y1, self.y2])
542            self.left_line.set(xdata=[self.x2, self.x2],
543                               ydata=[self.y1, self.y2])
[2a3a890]544            return 
[eba08f1a]545        ## if x1, y1, y2, y3 are given draw the rectangle with this value
[32c0841]546        if x1 != None: 
547            self.x1 = x1
548        if x2 != None: 
549            self.x2 = x2
550        if y1 != None: 
551            self.y1 = y1
552        if y2 != None: 
553            self.y2 = y2
[eba08f1a]554        ## Draw 2 vertical lines and a marker
[32c0841]555        self.right_marker.set(xdata=[self.x1], ydata=[self.center_y])
556        self.right_line.set(xdata=[self.x1, self.x1], ydata=[self.y1, self.y2])
557        self.left_line.set(xdata=[self.x2, self.x2], ydata=[self.y1, self.y2])
[78ed1ad]558       
559    def save(self, ev):
560        """
561        Remember the roughness for this layer and the next so that we
562        can restore on Esc.
563        """
[32c0841]564        self.save_x2 = self.x2
565        self.save_y2 = self.y2
566        self.save_x1 = self.x1
567        self.save_y1 = self.y1
568        self.save_half_height = self.half_height
[ee69839]569        self.save_half_width = self.half_width
[78ed1ad]570        self.base.freeze_axes()
571
572    def moveend(self, ev):
[eba08f1a]573        """
574            After a dragging motion reset the flag self.has_move to False
575        """
[32c0841]576        self.has_move = False
[78ed1ad]577        self.base.moveend(ev)
578           
579    def restore(self):
580        """
581        Restore the roughness for this layer.
582        """
[32c0841]583        self.y2 = self.save_y2
584        self.x2 = self.save_x2
585        self.y1 = self.save_y1
586        self.x1 = self.save_x1
587        self.half_height = self.save_half_height
588        self.half_width = self.save_half_width
[eba08f1a]589       
[78ed1ad]590    def move(self, x, y, ev):
591        """
592        Process move to a new position, making sure that the move is allowed.
593        """
[32c0841]594        self.x1 = x
595        delta = self.x1 - self.center_x
596        self.x2 = self.center_x - delta
597        self.half_width = math.fabs(self.x1 - self.x2)/2
598        self.has_move = True
[78ed1ad]599        self.base.base.update()
600       
601    def set_cursor(self, x, y):
[eba08f1a]602        """
603            Update the figure given x and y
604        """
[78ed1ad]605        self.move(x, y, None)
606        self.update()
607       
608    def get_params(self):
[eba08f1a]609        """
610            Store a copy of values of parameters of the slicer into a dictionary.
611            @return params: the dictionary created
612        """
[78ed1ad]613        params = {}
[2a3a890]614        params["x"] = self.x1
615        params["y"] = self.y1
[78ed1ad]616        return params
617   
618    def set_params(self, params):
[eba08f1a]619        """
620            Receive a dictionary and reset the slicer with values contained
621            in the values of the dictionary.
622            @param params: a dictionary containing name of slicer parameters and
623            values the user assigned to the slicer.
624        """
[2a3a890]625        x = params["x"] 
626        y = params["y"] 
[32c0841]627        self.update(x=x, y=y, center_x=None, center_y=None)
[2a3a890]628
[eba08f1a]629
630class HorizontalDoubleLine(_BaseInteractor):
[2a3a890]631    """
632         Select an annulus through a 2D plot
633    """
[32c0841]634    def __init__(self, base, axes, color='black', zorder=5, x=0.5, y=0.5,
635                 center_x=0.0, center_y=0.0):
[2a3a890]636       
637        _BaseInteractor.__init__(self, base, axes, color=color)
[eba08f1a]638        ## Initialization the class
[2a3a890]639        self.markers = []
640        self.axes = axes
[eba08f1a]641        ## Center coordinates
[2a3a890]642        self.center_x = center_x
643        self.center_y = center_y
[32c0841]644        self.y1 = y + self.center_y
645        self.save_y1 = self.y1
646        delta = self.y1 - self.center_y
647        self.y2 = self.center_y - delta
648        self.save_y2 = self.y2
649        self.x1 = x + self.center_x
[2a3a890]650        self.save_x1 = self.x1
[32c0841]651        delta = self.x1 - self.center_x
652        self.x2 = self.center_x - delta
[2a3a890]653        self.save_x2 = self.x2
[32c0841]654        self.color = color
[2a3a890]655        self.half_height= math.fabs(y)
[32c0841]656        self.save_half_height = math.fabs(y)
657        self.half_width = math.fabs(x)
658        self.save_half_width = math.fabs(x)
[2a3a890]659        try:
[32c0841]660            self.top_marker = self.axes.plot([0], [self.y1], linestyle='',
[2a3a890]661                                          marker='s', markersize=10,
662                                          color=self.color, alpha=0.6,
[32c0841]663                                          pickradius=5, label="pick",
664                                          # Prefer this to other lines
665                                          zorder=zorder, visible=True)[0]
[2a3a890]666        except:
[32c0841]667            self.top_marker = self.axes.plot([0], [self.y1], linestyle='',
[2a3a890]668                                          marker='s', markersize=10,
669                                          color=self.color, alpha=0.6,
[32c0841]670                                          label="pick", visible=True)[0]
671            message  = "\nTHIS PROTOTYPE NEEDS THE LATEST VERSION "
672            message += "OF MATPLOTLIB\n Get the SVN version "
673            message += "that is at least as recent as June 1, 2007"
674            owner = self.base.base.parent
675            wx.PostEvent(owner,
676                         StatusEvent(status="AnnulusSlicer: %s" % message))
[2a3a890]677           
[eba08f1a]678        # Define 2 horizotnal lines
[32c0841]679        self.top_line = self.axes.plot([self.x1, -self.x1], [self.y1, self.y1],
[2a3a890]680                                      linestyle='-', marker='',
[32c0841]681                                      color=self.color, visible=True)[0]
682        self.bottom_line = self.axes.plot([self.x1, -self.x1], 
683                                          [self.y2, self.y2],
[2a3a890]684                                      linestyle='-', marker='',
[32c0841]685                                      color=self.color, visible=True)[0]
[eba08f1a]686        ## Flag to determine if the lines have moved
[32c0841]687        self.has_move = False   
[eba08f1a]688        ## connection the marker and draw the pictures
[2a3a890]689        self.connect_markers([self.top_marker])
690        self.update()
691
692    def set_layer(self, n):
[eba08f1a]693        """
694            Allow adding plot to the same panel
695            @param n: the number of layer
696        """
[2a3a890]697        self.layernum = n
698        self.update()
699       
700    def clear(self):
[eba08f1a]701        """
702            Clear this figure and its markers
703        """
[2a3a890]704        self.clear_markers()
705        try:
[54cc36a]706            self.top_marker.remove()
[2a3a890]707            self.bottom_line.remove()
708            self.top_line.remove()
709        except:
710            # Old version of matplotlib
711            for item in range(len(self.axes.lines)):
712                del self.axes.lines[0]
[eba08f1a]713   
[32c0841]714    def update(self, x1=None, x2=None, y1=None, y2=None,
715               width=None, height=None, center=None):
716        """
717        Draw the new roughness on the graph.
718        :param x1: new maximum value of x coordinates
719        :param x2: new minimum value of x coordinates
720        :param y1: new maximum value of y coordinates
721        :param y2: new minimum value of y coordinates
722        :param width: is the width of the new rectangle
723        :param height: is the height of the new rectangle
724        :param center: provided x, y  coordinates of the center point
[eba08f1a]725        """
726        ## save the new height, witdh of the rectangle if given as a param
727        if width != None:
728            self.half_width = width
729        if height!= None:
[32c0841]730            self.half_height = height
[eba08f1a]731        ## If new  center coordinates are given draw the rectangle
732        ##given these value
[32c0841]733        if center != None:
734            self.center_x = center.x
735            self.center_y = center.y
[2a3a890]736            self.x1 = self.half_width + self.center_x
[32c0841]737            self.x2 = -self.half_width + self.center_x
[2a3a890]738           
739            self.y1 = self.half_height + self.center_y
[32c0841]740            self.y2 = -self.half_height + self.center_y
[2a3a890]741           
[32c0841]742            self.top_marker.set(xdata=[self.center_x], ydata=[self.y1])
743            self.top_line.set(xdata=[self.x1, self.x2],
744                              ydata=[self.y1, self.y1])
745            self.bottom_line.set(xdata=[self.x1, self.x2],
746                                 ydata=[self.y2, self.y2])
[2a3a890]747            return 
[eba08f1a]748        ## if x1, y1, y2, y3 are given draw the rectangle with this value
[32c0841]749        if x1 != None: 
750            self.x1 = x1
751        if x2 != None: 
752            self.x2 = x2
753        if y1 != None: 
754            self.y1 = y1
755        if y2 != None: 
756            self.y2 = y2
[eba08f1a]757        ## Draw 2 vertical lines and a marker
[32c0841]758        self.top_marker.set(xdata=[self.center_x], ydata=[self.y1])
759        self.top_line.set(xdata=[self.x1, self.x2], ydata=[self.y1, self.y1])
760        self.bottom_line.set(xdata=[self.x1, self.x2], ydata=[self.y2, self.y2])
[2a3a890]761       
762    def save(self, ev):
763        """
764        Remember the roughness for this layer and the next so that we
765        can restore on Esc.
766        """
[32c0841]767        self.save_x2 = self.x2
768        self.save_y2 = self.y2
769        self.save_x1 = self.x1
770        self.save_y1 = self.y1
771        self.save_half_height = self.half_height
[2a3a890]772        self.save_half_width =  self.half_width
773        self.base.freeze_axes()
[32c0841]774       
[2a3a890]775    def moveend(self, ev):
[eba08f1a]776        """
[32c0841]777        After a dragging motion reset the flag self.has_move to False
[eba08f1a]778        """
[32c0841]779        self.has_move = False
[2a3a890]780        self.base.moveend(ev)
[eba08f1a]781           
[2a3a890]782    def restore(self):
783        """
784        Restore the roughness for this layer.
785        """
[32c0841]786        self.y2 = self.save_y2
787        self.x2 = self.save_x2
788        self.y1 = self.save_y1
789        self.x1 = self.save_x1
790        self.half_height = self.save_half_height
791        self.half_width = self.save_half_width
[eba08f1a]792       
[2a3a890]793    def move(self, x, y, ev):
794        """
795        Process move to a new position, making sure that the move is allowed.
796        """
[32c0841]797        self.y1 = y
798        delta = self.y1 - self.center_y
799        self.y2 =  self.center_y - delta
800        self.half_height = math.fabs(self.y1) - self.center_y
801        self.has_move = True
[2a3a890]802        self.base.base.update()
[32c0841]803   
[2a3a890]804    def set_cursor(self, x, y):
[eba08f1a]805        """
806            Update the figure given x and y
807        """
[2a3a890]808        self.move(x, y, None)
809        self.update()
810       
811    def get_params(self):
[eba08f1a]812        """
[32c0841]813        Store a copy of values of parameters of the slicer into a dictionary.
814        :return params: the dictionary created
[eba08f1a]815        """
[2a3a890]816        params = {}
817        params["x"] = self.x
818        params["y"] = self.y
819        return params
820   
821    def set_params(self, params):
[eba08f1a]822        """
[32c0841]823        Receive a dictionary and reset the slicer with values contained
824        in the values of the dictionary.
825        :param params: a dictionary containing name of slicer parameters and
[eba08f1a]826            values the user assigned to the slicer.
827        """
[2a3a890]828        x = params["x"] 
829        y = params["y"] 
830        self.update(x=x, y=y, center_x=None,center_y=None)
[eba08f1a]831         
832         
[78ed1ad]833         
Note: See TracBrowser for help on using the repository browser.