source: sasview/src/sas/qtgui/Plotting/Masks/SectorMask.py @ e20870bc

ESS_GUIESS_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 e20870bc was e20870bc, checked in by Piotr Rozyczko <rozyczko@…>, 6 years ago

Masking dialog for fitting

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