source: sasview/src/sas/sasgui/guiframe/local_perspectives/plotting/boxMask.py @ 5251ec6

magnetic_scattrelease-4.2.2ticket-1009ticket-1249
Last change on this file since 5251ec6 was 5251ec6, checked in by Paul Kienzle <pkienzle@…>, 13 months ago

improved support for py37 in sasgui

  • Property mode set to 100644
File size: 8.9 KB
Line 
1import math
2from .BaseInteractor import _BaseInteractor
3from .boxSum import PointInteractor
4from .boxSum import VerticalDoubleLine
5from .boxSum import HorizontalDoubleLine
6
7
8class BoxMask(_BaseInteractor):
9    """
10    BoxMask Class: determine 2 rectangular area to find the pixel of
11    a Data inside of box.
12
13    Uses PointerInteractor , VerticalDoubleLine,HorizontalDoubleLine.
14
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
20
21    """
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):
24        """
25        """
26        _BaseInteractor.__init__(self, base, axes, color=color)
27        # # class initialization
28        # # list of Boxmask markers
29        self.markers = []
30        self.axes = axes
31        self.mask = None
32        self.is_inside = side
33        # # connect the artist for the motion
34        self.connect = self.base.connect
35        # # when qmax is reached the selected line is reset
36        # the its previous value
37        self.qmax = min(self.base.data.xmax, self.base.data.xmin)
38        # # Define the box limits
39        self.xmin = -1 * 0.5 * min(math.fabs(self.base.data.xmax),
40                                   math.fabs(self.base.data.xmin))
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))
45        self.ymax = 0.5 * min(math.fabs(self.base.data.xmax),
46                              math.fabs(self.base.data.xmin))
47        # # center of the box
48        self.center_x = 0.0002
49        self.center_y = 0.0003
50        # # Number of points on the plot
51        self.nbins = 20
52        # # Define initial result the summation
53        self.count = 0
54        self.error = 0
55        self.data = self.base.data
56        # # Flag to determine if the current figure has moved
57        # # set to False == no motion , set to True== motion
58        self.has_move = False
59        # # Create Box edges
60        self.horizontal_lines = HorizontalDoubleLine(self,
61                                                     self.base.subplot,
62                                                     color='blue',
63                                                     zorder=zorder,
64                                                     y=self.ymax,
65                                                     x=self.xmax,
66                                                     center_x=self.center_x,
67                                                     center_y=self.center_y)
68        self.horizontal_lines.qmax = self.qmax
69
70        self.vertical_lines = VerticalDoubleLine(self,
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)
78        self.vertical_lines.qmax = self.qmax
79
80        self.center = PointInteractor(self,
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
88        self.update()
89        self._post_data()
90
91    def clear(self):
92        """
93        Clear the slicer and all connected events related to this slicer
94        """
95        self.clear_markers()
96        self.horizontal_lines.clear()
97        self.vertical_lines.clear()
98        self.center.clear()
99        self.base.connect.clearall()
100
101    def update(self):
102        """
103        Respond to changes in the model by recalculating the profiles and
104        resetting the widgets.
105        """
106        # check if the center point has moved and update the figure accordingly
107        if self.center.has_move:
108            self.center.update()
109            self.horizontal_lines.update(center=self.center)
110            self.vertical_lines.update(center=self.center)
111        # # check if the horizontal lines have moved and update
112        # the figure accordingly
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,
117                                       height=self.horizontal_lines.half_height)
118        # # check if the vertical lines have moved and update
119        # the figure accordingly
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)
125        # if self.is_inside is not None:
126        out = self._post_data()
127        return out
128
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)
138
139    def _post_data(self):
140        """
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
143        """
144        from sas.sascalc.dataloader.manipulations import Boxcut
145        # # Data 2D for which the pixel will be summed
146        data = self.base.data
147        mask = data.mask
148        # # the region of the summation
149        x_min = self.horizontal_lines.x2
150        x_max = self.horizontal_lines.x1
151        y_min = self.vertical_lines.y2
152        y_max = self.vertical_lines.y1
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:
156            out = (mask(data) == False)
157        else:
158            out = (mask(data))
159        # self.base.data.mask=out
160        self.mask = mask
161        return out
162
163    def moveend(self, ev):
164        """
165        After a dragging motion this function is called to compute
166        the error and the sum of pixel of a given data 2D
167        """
168        self.base.thaw_axes()
169        # # post
170        self._post_data()
171
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()
179
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
185
186    def set_cursor(self, x, y):
187        pass
188
189    def get_params(self):
190        """
191        Store a copy of values of parameters of the slicer into a dictionary.
192
193        :return params: the dictionary created
194
195        """
196        params = {}
197        params["Width"] = math.fabs(self.vertical_lines.half_width) * 2
198        params["Height"] = math.fabs(self.horizontal_lines.half_height) * 2
199        params["center_x"] = self.center.x
200        params["center_y"] = self.center.y
201        return params
202
203    def get_mask(self):
204        """
205        return mask as a result of boxcut
206        """
207        mask = self.mask
208        return mask
209
210    def set_params(self, params):
211        """
212        Receive a dictionary and reset the slicer with values contained
213        in the values of the dictionary.
214
215        :param params: a dictionary containing name of slicer parameters and
216           values the user assigned to the slicer.
217        """
218        x_max = math.fabs(params["Width"]) / 2
219        y_max = math.fabs(params["Height"]) / 2
220
221        self.center_x = params["center_x"]
222        self.center_y = params["center_y"]
223        # update the slicer given values of params
224        self.center.update(center_x=self.center_x, center_y=self.center_y)
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
228        self._post_data()
229
230    def freeze_axes(self):
231        self.base.freeze_axes()
232
233    def thaw_axes(self):
234        self.base.thaw_axes()
235
236    def draw(self):
237        self.base.update()
238
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.