source: sasview/src/sas/sasgui/guiframe/local_perspectives/plotting/sector_mask.py @ 6d7b252b

Last change on this file since 6d7b252b was 5251ec6, checked in by Paul Kienzle <pkienzle@…>, 6 years ago

improved support for py37 in sasgui

  • Property mode set to 100644
File size: 7.4 KB
Line 
1"""
2    Sector mask interactor
3"""
4import math
5
6import wx
7
8from sas.sasgui.guiframe.events import SlicerParameterEvent
9
10from .BaseInteractor import _BaseInteractor
11from .SectorSlicer import SideInteractor
12from .SectorSlicer import LineInteractor
13
14class SectorMask(_BaseInteractor):
15    """
16    Draw a sector slicer.Allow to find the data 2D inside of the sector lines
17    """
18    def __init__(self, base, axes, color='gray', zorder=3, side=False):
19        """
20        """
21        _BaseInteractor.__init__(self, base, axes, color=color)
22        ## Class initialization
23        self.markers = []
24        self.axes = axes
25        self.is_inside = side
26        ## connect the plot to event
27        self.connect = self.base.connect
28
29        ## compute qmax limit to reset the graph
30        x = math.pow(max(self.base.data.xmax,
31                         math.fabs(self.base.data.xmin)), 2)
32        y = math.pow(max(self.base.data.ymax,
33                         math.fabs(self.base.data.ymin)), 2)
34        self.qmax = math.sqrt(x + y)
35        ## Number of points on the plot
36        self.nbins = 20
37        ## Angle of the middle line
38        self.theta2 = math.pi / 3
39        ## Absolute value of the Angle between the middle line and any side line
40        self.phi = math.pi / 12
41
42        ## Middle line
43        self.main_line = LineInteractor(self, self.base.subplot, color='blue',
44                                        zorder=zorder, r=self.qmax, theta=self.theta2)
45        self.main_line.qmax = self.qmax
46        ## Right Side line
47        self.right_line = SideInteractor(self, self.base.subplot, color='gray',
48                                         zorder=zorder, r=self.qmax, phi=-1 * self.phi,
49                                         theta2=self.theta2)
50        self.right_line.qmax = self.qmax
51        ## Left Side line
52        self.left_line = SideInteractor(self, self.base.subplot, color='gray',
53                                        zorder=zorder, r=self.qmax, phi=self.phi,
54                                        theta2=self.theta2)
55        self.left_line.qmax = self.qmax
56        ## draw the sector
57        self.update()
58        self._post_data()
59
60    def clear(self):
61        """
62        Clear the slicer and all connected events related to this slicer
63        """
64        self.clear_markers()
65        self.main_line.clear()
66        self.left_line.clear()
67        self.right_line.clear()
68        self.base.connect.clearall()
69
70    def update(self):
71        """
72        Respond to changes in the model by recalculating the profiles and
73        resetting the widgets.
74        """
75        # Update locations
76        ## Check if the middle line was dragged and
77        #update the picture accordingly
78        if self.main_line.has_move:
79            self.main_line.update()
80            self.right_line.update(delta=-self.left_line.phi / 2,
81                                   mline=self.main_line.theta)
82            self.left_line.update(delta=self.left_line.phi / 2,
83                                  mline=self.main_line.theta)
84        ## Check if the left side has moved and update the slicer accordingly
85        if self.left_line.has_move:
86            self.main_line.update()
87            self.left_line.update(phi=None, delta=None, mline=self.main_line,
88                                  side=True, left=True)
89            self.right_line.update(phi=self.left_line.phi, delta=None,
90                                   mline=self.main_line, side=True,
91                                   left=False, right=True)
92        ## Check if the right side line has moved and
93        #update the slicer accordingly
94        if self.right_line.has_move:
95            self.main_line.update()
96            self.right_line.update(phi=None, delta=None, mline=self.main_line,
97                                   side=True, left=False, right=True)
98            self.left_line.update(phi=self.right_line.phi, delta=None,
99                                  mline=self.main_line, side=True, left=False)
100        #if self.is_inside is not None:
101        out = self._post_data()
102        return out
103
104    def save(self, ev):
105        """
106        Remember the roughness for this layer and the next so that we
107        can restore on Esc.
108        """
109        self.base.freeze_axes()
110        self.main_line.save(ev)
111        self.right_line.save(ev)
112        self.left_line.save(ev)
113
114    def _post_data(self):
115        """
116        compute sector averaging of data into data1D
117        """
118        ## get the data to average
119        data = self.base.data
120        # If we have no data, just return
121        if data is None:
122            return
123        ## Averaging
124        from sas.sascalc.dataloader.manipulations import Sectorcut
125        phimin = -self.left_line.phi + self.main_line.theta
126        phimax = self.left_line.phi + self.main_line.theta
127
128        mask = Sectorcut(phi_min=phimin, phi_max=phimax)
129        if self.is_inside:
130            out = (mask(data) == False)
131        else:
132            out = (mask(data))
133        return out
134
135    def moveend(self, ev):
136        """
137        Called a dragging motion ends.Get slicer event
138        """
139        self.base.thaw_axes()
140        ## Post parameters
141        event = SlicerParameterEvent()
142        event.type = self.__class__.__name__
143        event.params = self.get_params()
144        ## Send slicer paramers to plotter2D
145        wx.PostEvent(self.base, event)
146        self._post_data()
147
148    def restore(self):
149        """
150        Restore the roughness for this layer.
151        """
152        self.main_line.restore()
153        self.left_line.restore()
154        self.right_line.restore()
155
156    def move(self, x, y, ev):
157        """
158        Process move to a new position, making sure that the move is allowed.
159        """
160        pass
161
162    def set_cursor(self, x, y):
163        pass
164
165    def get_params(self):
166        """
167        Store a copy of values of parameters of the slicer into a dictionary.
168
169        :return params: the dictionary created
170
171        """
172        params = {}
173        ## Always make sure that the left and the right line are at phi
174        ## angle of the middle line
175        if math.fabs(self.left_line.phi) != math.fabs(self.right_line.phi):
176            msg = "Phi left and phi right are "
177            msg += "different %f, %f" % (self.left_line.phi,
178                                         self.right_line.phi)
179            raise ValueError(msg)
180        params["Phi"] = self.main_line.theta
181        params["Delta_Phi"] = math.fabs(self.left_line.phi)
182        return params
183
184    def set_params(self, params):
185        """
186        Receive a dictionary and reset the slicer with values contained
187        in the values of the dictionary.
188
189        :param params: a dictionary containing name of slicer parameters and
190            values the user assigned to the slicer.
191        """
192        main = params["Phi"]
193        phi = math.fabs(params["Delta_Phi"])
194
195        self.main_line.theta = main
196        ## Reset the slicer parameters
197        self.main_line.update()
198        self.right_line.update(phi=phi, delta=None, mline=self.main_line,
199                               side=True, right=True)
200        self.left_line.update(phi=phi, delta=None,
201                              mline=self.main_line, side=True)
202        ## post the new corresponding data
203        self._post_data()
204
205    def freeze_axes(self):
206        """
207        """
208        self.base.freeze_axes()
209
210    def thaw_axes(self):
211        """
212        """
213        self.base.thaw_axes()
214
215    def draw(self):
216        """
217        """
218        self.base.update()
Note: See TracBrowser for help on using the repository browser.