source: sasview/src/sans/guiframe/local_perspectives/plotting/boxSum.py @ 8f52edd

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 8f52edd was 5777106, checked in by Mathieu Doucet <doucetm@…>, 11 years ago

Moving things around. Will definitely not build.

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