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

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.2ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since cf67a45 was d85c194, checked in by Piotr Rozyczko <piotr.rozyczko@…>, 9 years ago

Remaining modules refactored

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