source: sasview/src/sas/guiframe/local_perspectives/plotting/boxMask.py @ b699768

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 b699768 was b699768, checked in by Piotr Rozyczko <piotr.rozyczko@…>, 8 years ago

Initial commit of the refactored SasCalc? module.

  • Property mode set to 100644
File size: 9.1 KB
RevLine 
[c5874f2]1import math
2from BaseInteractor import _BaseInteractor
[32c0841]3from boxSum import PointInteractor
4from boxSum import VerticalDoubleLine
5from boxSum import HorizontalDoubleLine
[c5874f2]6
7
8class BoxMask(_BaseInteractor):
9    """
[83f4445]10    BoxMask Class: determine 2 rectangular area to find the pixel of
[b5de88e]11    a Data inside of box.
12
[83f4445]13    Uses PointerInteractor , VerticalDoubleLine,HorizontalDoubleLine.
[b5de88e]14
[83f4445]15    :param zorder:  Artists with lower zorder values are drawn first.
16    :param x_min: the minimum value of the x coordinate
17    :param x_max: the maximum value of the x coordinate
18    :param y_min: the minimum value of the y coordinate
19    :param y_max: the maximum value of the y coordinate
[c5874f2]20
21    """
[b5de88e]22    def __init__(self, base, axes, color='black', zorder=3, side=None,
23                 x_min=0.008, x_max=0.008, y_min=0.0025, y_max=0.0025):
[32c0841]24        """
25        """
[c5874f2]26        _BaseInteractor.__init__(self, base, axes, color=color)
[b5de88e]27        # # class initialization
28        # # list of Boxmask markers
[c5874f2]29        self.markers = []
30        self.axes = axes
[3fc01c5]31        self.mask = None
[c5874f2]32        self.is_inside = side
[b5de88e]33        # # connect the artist for the motion
[c5874f2]34        self.connect = self.base.connect
[b5de88e]35        # # when qmax is reached the selected line is reset
36        # the its previous value
[c5874f2]37        self.qmax = min(self.base.data.xmax, self.base.data.xmin)
[b5de88e]38        # # Define the box limits
[32c0841]39        self.xmin = -1 * 0.5 * min(math.fabs(self.base.data.xmax),
[b5de88e]40                                   math.fabs(self.base.data.xmin))
[32c0841]41        self.ymin = -1 * 0.5 * min(math.fabs(self.base.data.xmax),
42                                   math.fabs(self.base.data.xmin))
43        self.xmax = 0.5 * min(math.fabs(self.base.data.xmax),
44                              math.fabs(self.base.data.xmin))
[b5de88e]45        self.ymax = 0.5 * min(math.fabs(self.base.data.xmax),
46                              math.fabs(self.base.data.xmin))
47        # # center of the box
[32c0841]48        self.center_x = 0.0002
49        self.center_y = 0.0003
[b5de88e]50        # # Number of points on the plot
[c5874f2]51        self.nbins = 20
[b5de88e]52        # # Define initial result the summation
[32c0841]53        self.count = 0
54        self.error = 0
[c5874f2]55        self.data = self.base.data
[b5de88e]56        # # Flag to determine if the current figure has moved
57        # # set to False == no motion , set to True== motion
[32c0841]58        self.has_move = False
[b5de88e]59        # # Create Box edges
[32c0841]60        self.horizontal_lines = HorizontalDoubleLine(self,
61                                                     self.base.subplot,
62                                                     color='blue',
[b5de88e]63                                                     zorder=zorder,
64                                                     y=self.ymax,
65                                                     x=self.xmax,
66                                                     center_x=self.center_x,
67                                                     center_y=self.center_y)
[c5874f2]68        self.horizontal_lines.qmax = self.qmax
[b5de88e]69
[32c0841]70        self.vertical_lines = VerticalDoubleLine(self,
[b5de88e]71                                                 self.base.subplot,
72                                                 color='grey',
73                                                 zorder=zorder,
74                                                 y=self.ymax,
75                                                 x=self.xmax,
76                                                 center_x=self.center_x,
77                                                 center_y=self.center_y)
[c5874f2]78        self.vertical_lines.qmax = self.qmax
[b5de88e]79
[32c0841]80        self.center = PointInteractor(self,
[b5de88e]81                                      self.base.subplot, color='grey',
82                                      zorder=zorder,
83                                      center_x=self.center_x,
84                                      center_y=self.center_y)
85        # # Save the name of the slicer panel associate with this slicer
86        self.panel_name = ""
87        # # Update and post slicer parameters
[c5874f2]88        self.update()
89        self._post_data()
[b5de88e]90
[c5874f2]91    def clear(self):
92        """
[83f4445]93        Clear the slicer and all connected events related to this slicer
[c5874f2]94        """
95        self.clear_markers()
96        self.horizontal_lines.clear()
97        self.vertical_lines.clear()
98        self.center.clear()
99        self.base.connect.clearall()
[b5de88e]100
[c5874f2]101    def update(self):
102        """
[83f4445]103        Respond to changes in the model by recalculating the profiles and
104        resetting the widgets.
[c5874f2]105        """
[b5de88e]106        # check if the center point has moved and update the figure accordingly
[c5874f2]107        if self.center.has_move:
108            self.center.update()
[32c0841]109            self.horizontal_lines.update(center=self.center)
110            self.vertical_lines.update(center=self.center)
[b5de88e]111        # # check if the horizontal lines have moved and update
112        # the figure accordingly
[c5874f2]113        if self.horizontal_lines.has_move:
114            self.horizontal_lines.update()
115            self.vertical_lines.update(y1=self.horizontal_lines.y1,
116                                       y2=self.horizontal_lines.y2,
[32c0841]117                                       height=self.horizontal_lines.half_height)
[b5de88e]118        # # check if the vertical lines have moved and update
119        # the figure accordingly
[c5874f2]120        if self.vertical_lines.has_move:
121            self.vertical_lines.update()
122            self.horizontal_lines.update(x1=self.vertical_lines.x1,
123                                         x2=self.vertical_lines.x2,
124                                         width=self.vertical_lines.half_width)
[b5de88e]125        # if self.is_inside != None:
[c5874f2]126        out = self._post_data()
127        return out
[b5de88e]128
[c5874f2]129    def save(self, ev):
130        """
131        Remember the roughness for this layer and the next so that we
132        can restore on Esc.
133        """
134        self.base.freeze_axes()
135        self.horizontal_lines.save(ev)
136        self.vertical_lines.save(ev)
137        self.center.save(ev)
[b5de88e]138
[c5874f2]139    def _post_data(self):
140        """
[83f4445]141        Get the limits of the boxsum and compute the sum of the pixel
142        contained in that region and the error on that sum
[c5874f2]143        """
[b699768]144        from sas.sascalc.dataloader.manipulations import Boxcut
[b5de88e]145        # # Data 2D for which the pixel will be summed
[c5874f2]146        data = self.base.data
147        mask = data.mask
[b5de88e]148        # # the region of the summation
149        x_min = self.horizontal_lines.x2
150        x_max = self.horizontal_lines.x1
[32c0841]151        y_min = self.vertical_lines.y2
152        y_max = self.vertical_lines.y1
[c5874f2]153        mask = Boxcut(x_min=x_min, x_max=x_max, y_min=y_min, y_max=y_max)
154
155        if self.is_inside:
[32c0841]156            out = (mask(data) == False)
[c5874f2]157        else:
158            out = (mask(data))
[b5de88e]159        # self.base.data.mask=out
[3fc01c5]160        self.mask = mask
[b5de88e]161        return out
162
[c5874f2]163    def moveend(self, ev):
164        """
[83f4445]165        After a dragging motion this function is called to compute
[b5de88e]166        the error and the sum of pixel of a given data 2D
[c5874f2]167        """
168        self.base.thaw_axes()
[b5de88e]169        # # post
[c5874f2]170        self._post_data()
[b5de88e]171
[c5874f2]172    def restore(self):
173        """
174        Restore the roughness for this layer.
175        """
176        self.horizontal_lines.restore()
177        self.vertical_lines.restore()
178        self.center.restore()
[b5de88e]179
[c5874f2]180    def move(self, x, y, ev):
181        """
182        Process move to a new position, making sure that the move is allowed.
183        """
184        pass
[b5de88e]185
[c5874f2]186    def set_cursor(self, x, y):
187        pass
[b5de88e]188
[c5874f2]189    def get_params(self):
190        """
[83f4445]191        Store a copy of values of parameters of the slicer into a dictionary.
[b5de88e]192
[83f4445]193        :return params: the dictionary created
[b5de88e]194
[c5874f2]195        """
196        params = {}
[32c0841]197        params["Width"] = math.fabs(self.vertical_lines.half_width) * 2
[b5de88e]198        params["Height"] = math.fabs(self.horizontal_lines.half_height) * 2
[c5874f2]199        params["center_x"] = self.center.x
[32c0841]200        params["center_y"] = self.center.y
[c5874f2]201        return params
[b5de88e]202
[c5874f2]203    def get_mask(self):
204        """
[83f4445]205        return mask as a result of boxcut
[c5874f2]206        """
207        mask = self.mask
208        return mask
[b5de88e]209
[c5874f2]210    def set_params(self, params):
211        """
[b5de88e]212        Receive a dictionary and reset the slicer with values contained
[83f4445]213        in the values of the dictionary.
[b5de88e]214
215        :param params: a dictionary containing name of slicer parameters and
[83f4445]216           values the user assigned to the slicer.
[c5874f2]217        """
[b5de88e]218        x_max = math.fabs(params["Width"]) / 2
219        y_max = math.fabs(params["Height"]) / 2
220
221        self.center_x = params["center_x"]
[32c0841]222        self.center_y = params["center_y"]
[b5de88e]223        # update the slicer given values of params
[32c0841]224        self.center.update(center_x=self.center_x, center_y=self.center_y)
[b5de88e]225        self.horizontal_lines.update(center=self.center, width=x_max, height=y_max)
226        self.vertical_lines.update(center=self.center, width=x_max, height=y_max)
227        # compute the new error and sum given values of params
[c5874f2]228        self._post_data()
[b5de88e]229
[c5874f2]230    def freeze_axes(self):
231        self.base.freeze_axes()
[b5de88e]232
[c5874f2]233    def thaw_axes(self):
234        self.base.thaw_axes()
235
236    def draw(self):
237        self.base.update()
238
[b5de88e]239class inner_BoxMask(BoxMask):
240    def __call__(self):
241        self.base.data.mask = (self._post_data() == False)
Note: See TracBrowser for help on using the repository browser.