source: sasview/src/sas/sasgui/guiframe/local_perspectives/plotting/boxSum.py @ 3bdbfcc

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalc
Last change on this file since 3bdbfcc was 3bdbfcc, checked in by Piotr Rozyczko <rozyczko@…>, 7 years ago

Reimplementation of the slicer functionality

  • Property mode set to 100644
File size: 26.6 KB
RevLine 
[51f14603]1"""
[3bdbfcc]2Boxsum Class: determine 2 rectangular area to compute
3the sum of pixel of a Data.
[51f14603]4"""
[3bdbfcc]5import numpy
6from PyQt4 import QtGui
7from PyQt4 import QtCore
8from sas.qtgui.GuiUtils import formatNumber
9
[51f14603]10from BaseInteractor import _BaseInteractor
[3bdbfcc]11from sas.sascalc.dataloader.manipulations import Boxavg
12from sas.sascalc.dataloader.manipulations import Boxsum
[51f14603]13
[3bdbfcc]14from sas.qtgui.SlicerModel import SlicerModel
[51f14603]15
[3bdbfcc]16
17class BoxSumCalculator(_BaseInteractor):
[51f14603]18    """
[3bdbfcc]19    Boxsum Class: determine 2 rectangular area to compute
20    the sum of pixel of a Data.
21    Uses PointerInteractor , VerticalDoubleLine,HorizontalDoubleLine.
22    @param zorder:  Artists with lower zorder values are drawn first.
23    @param x_min: the minimum value of the x coordinate
24    @param x_max: the maximum value of the x coordinate
25    @param y_min: the minimum value of the y coordinate
26    @param y_max: the maximum value of the y coordinate
[51f14603]27
28    """
[3bdbfcc]29    def __init__(self, base, axes, color='black', zorder=3):
[51f14603]30        _BaseInteractor.__init__(self, base, axes, color=color)
[3bdbfcc]31
32        # list of Boxsmun markers
[51f14603]33        self.markers = []
34        self.axes = axes
[3bdbfcc]35        self._model = None
36        self.update_model = False
37
38        # connect the artist for the motion
[51f14603]39        self.connect = self.base.connect
[3bdbfcc]40
41        # when qmax is reached the selected line is reset the its previous value
42        self.qmax = min(self.base.data.xmax, self.base.data.xmin)
43
44        # Define the boxsum limits
45        self.xmin = -1 * 0.5 * min(numpy.fabs(self.base.data.xmax),
46                                   numpy.fabs(self.base.data.xmin))
47        self.ymin = -1 * 0.5 * min(numpy.fabs(self.base.data.xmax),
48                                   numpy.fabs(self.base.data.xmin))
49        self.xmax = 0.5 * min(numpy.fabs(self.base.data.xmax),
50                              numpy.fabs(self.base.data.xmin))
51        self.ymax = 0.5 * min(numpy.fabs(self.base.data.xmax),
52                              numpy.fabs(self.base.data.xmin))
53        # center of the boxSum
[51f14603]54        self.center_x = 0.0002
55        self.center_y = 0.0003
[3bdbfcc]56        # Number of points on the plot
[51f14603]57        self.nbins = 20
[3bdbfcc]58        # Define initial result the summation
[51f14603]59        self.count = 0
60        self.error = 0
61        self.total = 0
62        self.totalerror = 0
63        self.points = 0
[3bdbfcc]64        # Flag to determine if the current figure has moved
65        # set to False == no motion , set to True== motion
[51f14603]66        self.has_move = False
[3bdbfcc]67        # Create Boxsum edges
[51f14603]68        self.horizontal_lines = HorizontalDoubleLine(self,
[3bdbfcc]69                                                     self.axes,
[b5de88e]70                                                     color='blue',
71                                                     zorder=zorder,
72                                                     y=self.ymax,
73                                                     x=self.xmax,
74                                                     center_x=self.center_x,
75                                                     center_y=self.center_y)
[51f14603]76        self.horizontal_lines.qmax = self.qmax
[b5de88e]77
[51f14603]78        self.vertical_lines = VerticalDoubleLine(self,
[3bdbfcc]79                                                 self.axes,
[b5de88e]80                                                 color='black',
81                                                 zorder=zorder,
82                                                 y=self.ymax,
83                                                 x=self.xmax,
84                                                 center_x=self.center_x,
85                                                 center_y=self.center_y)
[51f14603]86        self.vertical_lines.qmax = self.qmax
[b5de88e]87
[51f14603]88        self.center = PointInteractor(self,
[3bdbfcc]89                                      self.axes, color='grey',
[b5de88e]90                                      zorder=zorder,
91                                      center_x=self.center_x,
92                                      center_y=self.center_y)
[3bdbfcc]93        # Save the name of the slicer panel associate with this slicer
[b5de88e]94        self.panel_name = ""
[3bdbfcc]95        # Update and post slicer parameters
96        self.update_model = False
[51f14603]97        self.update()
[3bdbfcc]98        self.postData()
99
100        # set up the model
101        self._model = QtGui.QStandardItemModel(1, 9)
102        self.setModelFromParams()
103        self.update_model = True
104        self._model.itemChanged.connect(self.setParamsFromModel)
[b5de88e]105
[3bdbfcc]106    def setModelFromParams(self):
[51f14603]107        """
[3bdbfcc]108        Set up the Qt model for data handling between controls
[51f14603]109        """
[3bdbfcc]110        parameters = self.getParams()
111        # Crete/overwrite model items
112        self._model.setData(self._model.index(0, 0),
113                    QtCore.QVariant(formatNumber(parameters['Height'])))
114        self._model.setData(self._model.index(0, 1),
115                    QtCore.QVariant(formatNumber(parameters['Width'])))
116        self._model.setData(self._model.index(0, 2),
117                    QtCore.QVariant(formatNumber(parameters['center_x'])))
118        self._model.setData(self._model.index(0, 3),
119                    QtCore.QVariant(formatNumber(parameters['center_y'])))
120
121        self.setReadOnlyParametersFromModel()
122
123    def model(self):
124        ''' model accessor '''
125        return self._model
126
127    def setReadOnlyParametersFromModel(self):
128        """
129        Cast model content onto "read-only" subset of parameters
130        """
131        parameters = self.getParams()
132        self._model.setData(self._model.index(0, 4),
133                    QtCore.QVariant(formatNumber(parameters['avg'])))
134        self._model.setData(self._model.index(0, 5),
135                    QtCore.QVariant(formatNumber(parameters['avg_error'])))
136        self._model.setData(self._model.index(0, 6),
137                    QtCore.QVariant(formatNumber(parameters['sum'])))
138        self._model.setData(self._model.index(0, 7),
139                    QtCore.QVariant(formatNumber(parameters['sum_error'])))
140        self._model.setData(self._model.index(0, 8),
141                    QtCore.QVariant(formatNumber(parameters['num_points'])))
[b5de88e]142
[3bdbfcc]143    def setParamsFromModel(self):
[51f14603]144        """
[3bdbfcc]145        Cast model content onto params dict
[51f14603]146        """
[3bdbfcc]147        params = {}
148        params["Height"] = float(self.model().item(0, 0).text())
149        params["Width"] = float(self.model().item(0, 1).text())
150        params["center_x"] = float(self.model().item(0, 2).text())
151        params["center_y"] = float(self.model().item(0, 3).text())
152        self.update_model = False
153        self.setParams(params)
154        self.setReadOnlyParametersFromModel()
155        self.update_model = True
156
157    def setPanelName(self, name):
158        """
159        Store the name of the panel associated to this slicer
160        @param name: the name of this panel
161        """
162        self.panel_name = name
[51f14603]163
[3bdbfcc]164    def setLayer(self, n):
[51f14603]165        """
166        Allow adding plot to the same panel
167        :param n: the number of layer
168        """
169        self.layernum = n
170        self.update()
[b5de88e]171
[51f14603]172    def clear(self):
173        """
174        Clear the slicer and all connected events related to this slicer
175        """
176        self.clear_markers()
177        self.horizontal_lines.clear()
178        self.vertical_lines.clear()
179        self.center.clear()
180        self.base.connect.clearall()
[b5de88e]181
[51f14603]182    def update(self):
183        """
184        Respond to changes in the model by recalculating the profiles and
185        resetting the widgets.
186        """
[3bdbfcc]187        # check if the center point has moved and update the figure accordingly
[51f14603]188        if self.center.has_move:
189            self.center.update()
[b5de88e]190            self.horizontal_lines.update(center=self.center)
191            self.vertical_lines.update(center=self.center)
[3bdbfcc]192        # check if the horizontal lines have moved and
[b5de88e]193        # update the figure accordingly
[51f14603]194        if self.horizontal_lines.has_move:
195            self.horizontal_lines.update()
196            self.vertical_lines.update(y1=self.horizontal_lines.y1,
197                                       y2=self.horizontal_lines.y2,
198                                       height=self.horizontal_lines.half_height)
[3bdbfcc]199        # check if the vertical lines have moved and
[b5de88e]200        # update the figure accordingly
[51f14603]201        if self.vertical_lines.has_move:
202            self.vertical_lines.update()
203            self.horizontal_lines.update(x1=self.vertical_lines.x1,
204                                         x2=self.vertical_lines.x2,
205                                         width=self.vertical_lines.half_width)
[b5de88e]206
[51f14603]207    def save(self, ev):
208        """
209        Remember the roughness for this layer and the next so that we
210        can restore on Esc.
211        """
212        self.horizontal_lines.save(ev)
213        self.vertical_lines.save(ev)
214        self.center.save(ev)
[b5de88e]215
[3bdbfcc]216    def postData(self):
[51f14603]217        """
218        Get the limits of the boxsum and compute the sum of the pixel
219        contained in that region and the error on that sum
220        """
[3bdbfcc]221        # the region of the summation
[b5de88e]222        x_min = self.horizontal_lines.x2
223        x_max = self.horizontal_lines.x1
[51f14603]224        y_min = self.vertical_lines.y2
225        y_max = self.vertical_lines.y1
[3bdbfcc]226        #computation of the sum and its error
[b5de88e]227        box = Boxavg(x_min=x_min, x_max=x_max, y_min=y_min, y_max=y_max)
[3bdbfcc]228        self.count, self.error = box(self.base.data)
[51f14603]229        # Dig out number of points summed, SMK & PDB, 04/03/2013
[b5de88e]230        boxtotal = Boxsum(x_min=x_min, x_max=x_max, y_min=y_min, y_max=y_max)
[3bdbfcc]231        self.total, self.totalerror, self.points = boxtotal(self.base.data)
232        if self.update_model:
233            self.setModelFromParams()
234        self.draw()
[b5de88e]235
[51f14603]236    def moveend(self, ev):
237        """
[3bdbfcc]238        After a dragging motion this function is called to compute
239        the error and the sum of pixel of a given data 2D
240        """
241        # compute error an d sum of data's pixel
242        self.postData()
[b5de88e]243
[51f14603]244    def restore(self):
245        """
246        Restore the roughness for this layer.
247        """
248        self.horizontal_lines.restore()
249        self.vertical_lines.restore()
250        self.center.restore()
[b5de88e]251
[3bdbfcc]252    def getParams(self):
[51f14603]253        """
254        Store a copy of values of parameters of the slicer into a dictionary.
255        :return params: the dictionary created
256        """
257        params = {}
[3bdbfcc]258        params["Width"] = numpy.fabs(self.vertical_lines.half_width) * 2
259        params["Height"] = numpy.fabs(self.horizontal_lines.half_height) * 2
[51f14603]260        params["center_x"] = self.center.x
261        params["center_y"] = self.center.y
262        params["num_points"] = self.points
263        params["avg"] = self.count
264        params["avg_error"] = self.error
265        params["sum"] = self.total
266        params["sum_error"] = self.totalerror
267        return params
[b5de88e]268
[3bdbfcc]269    def getResult(self):
[51f14603]270        """
[3bdbfcc]271        Return the result of box summation
[51f14603]272        """
273        result = {}
274        result["num_points"] = self.points
275        result["avg"] = self.count
276        result["avg_error"] = self.error
[b5de88e]277        result["sum"] = self.total
278        result["sum_error"] = self.totalerror
[51f14603]279        return result
[b5de88e]280
[3bdbfcc]281    def setParams(self, params):
[51f14603]282        """
[b5de88e]283        Receive a dictionary and reset the slicer with values contained
[51f14603]284        in the values of the dictionary.
[3bdbfcc]285        :param params: a dictionary containing name of slicer parameters
286        and values the user assigned to the slicer.
[51f14603]287        """
[3bdbfcc]288        x_max = numpy.fabs(params["Width"]) / 2
289        y_max = numpy.fabs(params["Height"]) / 2
[b5de88e]290
291        self.center_x = params["center_x"]
[51f14603]292        self.center_y = params["center_y"]
[b5de88e]293        # update the slicer given values of params
[51f14603]294        self.center.update(center_x=self.center_x, center_y=self.center_y)
295        self.horizontal_lines.update(center=self.center,
296                                     width=x_max, height=y_max)
297        self.vertical_lines.update(center=self.center,
[b5de88e]298                                   width=x_max, height=y_max)
299        # compute the new error and sum given values of params
[3bdbfcc]300        self.postData()
[51f14603]301
302    def draw(self):
[3bdbfcc]303        """ Redraw canvas"""
[51f14603]304        self.base.draw()
[b5de88e]305
306
307
[51f14603]308class PointInteractor(_BaseInteractor):
309    """
310    Draw a point that can be dragged with the marker.
[b5de88e]311    this class controls the motion the center of the BoxSum
[51f14603]312    """
313    def __init__(self, base, axes, color='black', zorder=5, center_x=0.0,
314                 center_y=0.0):
315        _BaseInteractor.__init__(self, base, axes, color=color)
[3bdbfcc]316        # Initialization the class
[51f14603]317        self.markers = []
318        self.axes = axes
319        # center coordinates
320        self.x = center_x
321        self.y = center_y
[3bdbfcc]322        # saved value of the center coordinates
[51f14603]323        self.save_x = center_x
324        self.save_y = center_y
[3bdbfcc]325        # Create a marker
[b5de88e]326        self.center_marker = self.axes.plot([self.x], [self.y], linestyle='',
327                                            marker='s', markersize=10,
328                                            color=self.color, alpha=0.6,
329                                            pickradius=5, label="pick",
330                                            zorder=zorder,
331                                            visible=True)[0]
[3bdbfcc]332        # Draw a point
[51f14603]333        self.center = self.axes.plot([self.x], [self.y],
[b5de88e]334                                     linestyle='-', marker='',
335                                     color=self.color,
336                                     visible=True)[0]
[3bdbfcc]337        # Flag to determine the motion this point
[b5de88e]338        self.has_move = False
[3bdbfcc]339        # connecting the marker to allow them to move
[51f14603]340        self.connect_markers([self.center_marker])
[3bdbfcc]341        # Update the figure
[51f14603]342        self.update()
[b5de88e]343
[3bdbfcc]344    def setLayer(self, n):
[51f14603]345        """
[3bdbfcc]346        Allow adding plot to the same panel
347        @param n: the number of layer
[51f14603]348        """
349        self.layernum = n
350        self.update()
[b5de88e]351
[51f14603]352    def clear(self):
353        """
[3bdbfcc]354        Clear this figure and its markers
[51f14603]355        """
356        self.clear_markers()
[3bdbfcc]357        self.center.remove()
358        self.center_marker.remove()
[b5de88e]359
360    def update(self, center_x=None, center_y=None):
[51f14603]361        """
[3bdbfcc]362        Draw the new roughness on the graph.
[51f14603]363        """
364        if center_x != None:
365            self.x = center_x
366        if center_y != None:
367            self.y = center_y
368        self.center_marker.set(xdata=[self.x], ydata=[self.y])
369        self.center.set(xdata=[self.x], ydata=[self.y])
[b5de88e]370
[51f14603]371    def save(self, ev):
372        """
373        Remember the roughness for this layer and the next so that we
374        can restore on Esc.
375        """
376        self.save_x = self.x
377        self.save_y = self.y
[b5de88e]378
[51f14603]379    def moveend(self, ev):
380        """
381        """
[b5de88e]382        self.has_move = False
[51f14603]383        self.base.moveend(ev)
[b5de88e]384
[51f14603]385    def restore(self):
386        """
387        Restore the roughness for this layer.
388        """
389        self.y = self.save_y
390        self.x = self.save_x
[b5de88e]391
[51f14603]392    def move(self, x, y, ev):
393        """
394        Process move to a new position, making sure that the move is allowed.
395        """
396        self.x = x
397        self.y = y
398        self.has_move = True
399        self.base.base.update()
[b5de88e]400
[3bdbfcc]401    def setCursor(self, x, y):
[51f14603]402        """
403        """
404        self.move(x, y, None)
405        self.update()
[b5de88e]406
[51f14603]407class VerticalDoubleLine(_BaseInteractor):
408    """
[3bdbfcc]409    Draw 2 vertical lines moving in opposite direction and centered on
410    a point (PointInteractor)
[51f14603]411    """
[b5de88e]412    def __init__(self, base, axes, color='black', zorder=5, x=0.5, y=0.5,
[51f14603]413                 center_x=0.0, center_y=0.0):
414        _BaseInteractor.__init__(self, base, axes, color=color)
[3bdbfcc]415        # Initialization the class
[51f14603]416        self.markers = []
417        self.axes = axes
[3bdbfcc]418        # Center coordinates
[51f14603]419        self.center_x = center_x
420        self.center_y = center_y
[3bdbfcc]421        # defined end points vertical lignes and their saved values
[51f14603]422        self.y1 = y + self.center_y
[b5de88e]423        self.save_y1 = self.y1
424
[51f14603]425        delta = self.y1 - self.center_y
426        self.y2 = self.center_y - delta
427        self.save_y2 = self.y2
[b5de88e]428
[51f14603]429        self.x1 = x + self.center_x
430        self.save_x1 = self.x1
[b5de88e]431
[51f14603]432        delta = self.x1 - self.center_x
433        self.x2 = self.center_x - delta
434        self.save_x2 = self.x2
[b5de88e]435        # # save the color of the line
[51f14603]436        self.color = color
[3bdbfcc]437        # the height of the rectangle
438        self.half_height = numpy.fabs(y)
439        self.save_half_height = numpy.fabs(y)
440        # the with of the rectangle
441        self.half_width = numpy.fabs(self.x1 - self.x2) / 2
442        self.save_half_width = numpy.fabs(self.x1 - self.x2) / 2
443        # Create marker
[b5de88e]444        self.right_marker = self.axes.plot([self.x1], [0], linestyle='',
445                                           marker='s', markersize=10,
446                                           color=self.color, alpha=0.6,
447                                           pickradius=5, label="pick",
448                                           zorder=zorder, visible=True)[0]
449
[3bdbfcc]450        # Define the left and right lines of the rectangle
[51f14603]451        self.right_line = self.axes.plot([self.x1, self.x1], [self.y1, self.y2],
[b5de88e]452                                         linestyle='-', marker='',
453                                         color=self.color, visible=True)[0]
[51f14603]454        self.left_line = self.axes.plot([self.x2, self.x2], [self.y1, self.y2],
[b5de88e]455                                        linestyle='-', marker='',
456                                        color=self.color, visible=True)[0]
[3bdbfcc]457        # Flag to determine if the lines have moved
[b5de88e]458        self.has_move = False
[3bdbfcc]459        # Connection the marker and draw the pictures
[51f14603]460        self.connect_markers([self.right_marker])
461        self.update()
462
[3bdbfcc]463    def setLayer(self, n):
[51f14603]464        """
465        Allow adding plot to the same panel
466        :param n: the number of layer
467        """
468        self.layernum = n
469        self.update()
[b5de88e]470
[51f14603]471    def clear(self):
472        """
473        Clear this slicer  and its markers
474        """
475        self.clear_markers()
[3bdbfcc]476        self.right_marker.remove()
477        self.right_line.remove()
478        self.left_line.remove()
[b5de88e]479
480    def update(self, x1=None, x2=None, y1=None, y2=None, width=None,
481               height=None, center=None):
[51f14603]482        """
483        Draw the new roughness on the graph.
484        :param x1: new maximum value of x coordinates
485        :param x2: new minimum value of x coordinates
486        :param y1: new maximum value of y coordinates
487        :param y2: new minimum value of y coordinates
488        :param width: is the width of the new rectangle
489        :param height: is the height of the new rectangle
490        :param center: provided x, y  coordinates of the center point
491        """
[3bdbfcc]492        # Save the new height, witdh of the rectangle if given as a param
493        if width is not None:
[51f14603]494            self.half_width = width
[3bdbfcc]495        if height is not None:
[51f14603]496            self.half_height = height
[3bdbfcc]497        # If new  center coordinates are given draw the rectangle
498        # given these value
499        if center is not None:
[51f14603]500            self.center_x = center.x
501            self.center_y = center.y
502            self.x1 = self.half_width + self.center_x
[b5de88e]503            self.x2 = -self.half_width + self.center_x
[51f14603]504            self.y1 = self.half_height + self.center_y
[b5de88e]505            self.y2 = -self.half_height + self.center_y
506
[51f14603]507            self.right_marker.set(xdata=[self.x1], ydata=[self.center_y])
[b5de88e]508            self.right_line.set(xdata=[self.x1, self.x1],
[51f14603]509                                ydata=[self.y1, self.y2])
510            self.left_line.set(xdata=[self.x2, self.x2],
511                               ydata=[self.y1, self.y2])
[b5de88e]512            return
[3bdbfcc]513        # if x1, y1, y2, y3 are given draw the rectangle with this value
514        if x1 is not None:
[51f14603]515            self.x1 = x1
[3bdbfcc]516        if x2 is not None:
[51f14603]517            self.x2 = x2
[3bdbfcc]518        if y1 is not None:
[51f14603]519            self.y1 = y1
[3bdbfcc]520        if y2 is not None:
[51f14603]521            self.y2 = y2
[3bdbfcc]522        # Draw 2 vertical lines and a marker
[51f14603]523        self.right_marker.set(xdata=[self.x1], ydata=[self.center_y])
524        self.right_line.set(xdata=[self.x1, self.x1], ydata=[self.y1, self.y2])
525        self.left_line.set(xdata=[self.x2, self.x2], ydata=[self.y1, self.y2])
[b5de88e]526
[51f14603]527    def save(self, ev):
528        """
529        Remember the roughness for this layer and the next so that we
530        can restore on Esc.
531        """
532        self.save_x2 = self.x2
533        self.save_y2 = self.y2
534        self.save_x1 = self.x1
535        self.save_y1 = self.y1
536        self.save_half_height = self.half_height
537        self.save_half_width = self.half_width
538
539    def moveend(self, ev):
540        """
[3bdbfcc]541        After a dragging motion reset the flag self.has_move to False
[51f14603]542        """
543        self.has_move = False
544        self.base.moveend(ev)
[b5de88e]545
[51f14603]546    def restore(self):
547        """
548        Restore the roughness for this layer.
549        """
550        self.y2 = self.save_y2
551        self.x2 = self.save_x2
552        self.y1 = self.save_y1
553        self.x1 = self.save_x1
554        self.half_height = self.save_half_height
555        self.half_width = self.save_half_width
[b5de88e]556
[51f14603]557    def move(self, x, y, ev):
558        """
559        Process move to a new position, making sure that the move is allowed.
560        """
561        self.x1 = x
562        delta = self.x1 - self.center_x
563        self.x2 = self.center_x - delta
[3bdbfcc]564        self.half_width = numpy.fabs(self.x1 - self.x2) / 2
[51f14603]565        self.has_move = True
566        self.base.base.update()
[b5de88e]567
[3bdbfcc]568    def setCursor(self, x, y):
[51f14603]569        """
[3bdbfcc]570        Update the figure given x and y
[51f14603]571        """
572        self.move(x, y, None)
573        self.update()
[b5de88e]574
[51f14603]575class HorizontalDoubleLine(_BaseInteractor):
576    """
[3bdbfcc]577    Select an annulus through a 2D plot
[51f14603]578    """
579    def __init__(self, base, axes, color='black', zorder=5, x=0.5, y=0.5,
580                 center_x=0.0, center_y=0.0):
[b5de88e]581
[51f14603]582        _BaseInteractor.__init__(self, base, axes, color=color)
[3bdbfcc]583        # Initialization the class
[51f14603]584        self.markers = []
585        self.axes = axes
[3bdbfcc]586        # Center coordinates
[51f14603]587        self.center_x = center_x
588        self.center_y = center_y
589        self.y1 = y + self.center_y
590        self.save_y1 = self.y1
591        delta = self.y1 - self.center_y
592        self.y2 = self.center_y - delta
593        self.save_y2 = self.y2
594        self.x1 = x + self.center_x
595        self.save_x1 = self.x1
596        delta = self.x1 - self.center_x
597        self.x2 = self.center_x - delta
598        self.save_x2 = self.x2
599        self.color = color
[3bdbfcc]600        self.half_height = numpy.fabs(y)
601        self.save_half_height = numpy.fabs(y)
602        self.half_width = numpy.fabs(x)
603        self.save_half_width = numpy.fabs(x)
[b5de88e]604        self.top_marker = self.axes.plot([0], [self.y1], linestyle='',
605                                         marker='s', markersize=10,
606                                         color=self.color, alpha=0.6,
607                                         pickradius=5, label="pick",
608                                         zorder=zorder, visible=True)[0]
609
[51f14603]610        # Define 2 horizotnal lines
611        self.top_line = self.axes.plot([self.x1, -self.x1], [self.y1, self.y1],
[b5de88e]612                                       linestyle='-', marker='',
613                                       color=self.color, visible=True)[0]
614        self.bottom_line = self.axes.plot([self.x1, -self.x1],
[51f14603]615                                          [self.y2, self.y2],
[b5de88e]616                                          linestyle='-', marker='',
617                                          color=self.color, visible=True)[0]
[3bdbfcc]618        # Flag to determine if the lines have moved
[b5de88e]619        self.has_move = False
[3bdbfcc]620        # connection the marker and draw the pictures
[51f14603]621        self.connect_markers([self.top_marker])
622        self.update()
623
[3bdbfcc]624    def setLayer(self, n):
[51f14603]625        """
[3bdbfcc]626        Allow adding plot to the same panel
627        @param n: the number of layer
[51f14603]628        """
629        self.layernum = n
630        self.update()
[b5de88e]631
[51f14603]632    def clear(self):
633        """
[3bdbfcc]634        Clear this figure and its markers
[51f14603]635        """
636        self.clear_markers()
[3bdbfcc]637        self.top_marker.remove()
638        self.bottom_line.remove()
639        self.top_line.remove()
[b5de88e]640
[51f14603]641    def update(self, x1=None, x2=None, y1=None, y2=None,
642               width=None, height=None, center=None):
643        """
644        Draw the new roughness on the graph.
645        :param x1: new maximum value of x coordinates
646        :param x2: new minimum value of x coordinates
647        :param y1: new maximum value of y coordinates
648        :param y2: new minimum value of y coordinates
649        :param width: is the width of the new rectangle
650        :param height: is the height of the new rectangle
651        :param center: provided x, y  coordinates of the center point
652        """
[3bdbfcc]653        # Save the new height, witdh of the rectangle if given as a param
654        if width is not None:
[51f14603]655            self.half_width = width
[3bdbfcc]656        if height is not None:
[51f14603]657            self.half_height = height
[3bdbfcc]658        # If new  center coordinates are given draw the rectangle
659        # given these value
660        if center is not None:
[51f14603]661            self.center_x = center.x
662            self.center_y = center.y
663            self.x1 = self.half_width + self.center_x
664            self.x2 = -self.half_width + self.center_x
[b5de88e]665
[51f14603]666            self.y1 = self.half_height + self.center_y
667            self.y2 = -self.half_height + self.center_y
[b5de88e]668
[51f14603]669            self.top_marker.set(xdata=[self.center_x], ydata=[self.y1])
670            self.top_line.set(xdata=[self.x1, self.x2],
671                              ydata=[self.y1, self.y1])
672            self.bottom_line.set(xdata=[self.x1, self.x2],
673                                 ydata=[self.y2, self.y2])
[b5de88e]674            return
[3bdbfcc]675        # if x1, y1, y2, y3 are given draw the rectangle with this value
676        if x1 is not None:
[51f14603]677            self.x1 = x1
[3bdbfcc]678        if x2 is not None:
[51f14603]679            self.x2 = x2
[3bdbfcc]680        if y1 is not None:
[51f14603]681            self.y1 = y1
[3bdbfcc]682        if y2 is not None:
[51f14603]683            self.y2 = y2
[3bdbfcc]684        # Draw 2 vertical lines and a marker
[51f14603]685        self.top_marker.set(xdata=[self.center_x], ydata=[self.y1])
686        self.top_line.set(xdata=[self.x1, self.x2], ydata=[self.y1, self.y1])
687        self.bottom_line.set(xdata=[self.x1, self.x2], ydata=[self.y2, self.y2])
[b5de88e]688
[51f14603]689    def save(self, ev):
690        """
691        Remember the roughness for this layer and the next so that we
692        can restore on Esc.
693        """
694        self.save_x2 = self.x2
695        self.save_y2 = self.y2
696        self.save_x1 = self.x1
697        self.save_y1 = self.y1
698        self.save_half_height = self.half_height
[b5de88e]699        self.save_half_width = self.half_width
700
[51f14603]701    def moveend(self, ev):
702        """
703        After a dragging motion reset the flag self.has_move to False
704        """
705        self.has_move = False
706        self.base.moveend(ev)
[b5de88e]707
[51f14603]708    def restore(self):
709        """
710        Restore the roughness for this layer.
711        """
712        self.y2 = self.save_y2
713        self.x2 = self.save_x2
714        self.y1 = self.save_y1
715        self.x1 = self.save_x1
716        self.half_height = self.save_half_height
717        self.half_width = self.save_half_width
[b5de88e]718
[51f14603]719    def move(self, x, y, ev):
720        """
721        Process move to a new position, making sure that the move is allowed.
722        """
723        self.y1 = y
724        delta = self.y1 - self.center_y
[b5de88e]725        self.y2 = self.center_y - delta
[3bdbfcc]726        self.half_height = numpy.fabs(self.y1) - self.center_y
[51f14603]727        self.has_move = True
728        self.base.base.update()
[b5de88e]729
[3bdbfcc]730    def setCursor(self, x, y):
[51f14603]731        """
[3bdbfcc]732        Update the figure given x and y
[51f14603]733        """
734        self.move(x, y, None)
735        self.update()
Note: See TracBrowser for help on using the repository browser.