source: sasview/src/sas/sasgui/guiframe/local_perspectives/plotting/parameters_panel_slicer.py @ dfa1579

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.2.2ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since dfa1579 was dfa1579, checked in by krzywon, 7 years ago

Remove 1D data from batch slice list. Keep initial data set checked. Remove unused parameter.

  • Property mode set to 100644
File size: 11.4 KB
Line 
1
2
3import wx
4import wx.lib.newevent
5#from copy import deepcopy
6from sas.sasgui.guiframe.events import EVT_SLICER_PARS
7from sas.sasgui.guiframe.utils import format_number
8from sas.sasgui.guiframe.events import EVT_SLICER
9from sas.sasgui.guiframe.events import SlicerParameterEvent, SlicerEvent
10from Plotter2D import ModelPanel2D
11from sas.sascalc.dataloader.data_info import Data1D, Data2D
12
13
14class SlicerParameterPanel(wx.Dialog):
15    """
16    Panel class to show the slicer parameters
17    """
18    #TODO: show units
19    #TODO: order parameters properly
20
21    def __init__(self, parent, *args, **kwargs):
22        """
23        Dialog window that allow to edit parameters slicer
24        by entering new values
25        """
26        wx.Dialog.__init__(self, parent, *args, **kwargs)
27        self.params = {}
28        self.parent = parent
29        self.type = None
30        self.listeners = []
31        self.parameters = []
32        self.bck = wx.GridBagSizer(5, 5)
33        self.SetSizer(self.bck)
34        label = "Right-click on 2D plot for slicer options"
35        title = wx.StaticText(self, -1, label, style=wx.ALIGN_LEFT)
36        self.bck.Add(title, (0, 0), (1, 2),
37                     flag=wx.LEFT | wx.ALIGN_CENTER_VERTICAL, border=15)
38        # Bindings
39        self.parent.Bind(EVT_SLICER, self.onEVT_SLICER)
40        self.parent.Bind(EVT_SLICER_PARS, self.onParamChange)
41
42    def onEVT_SLICER(self, event):
43        """
44        Process EVT_SLICER events
45        When the slicer changes, update the panel
46
47        :param event: EVT_SLICER event
48        """
49        event.Skip()
50        if event.obj_class is None:
51            self.set_slicer(None, None)
52        else:
53            self.set_slicer(event.type, event.params)
54
55    def set_slicer(self, type, params):
56        """
57        Rebuild the panel
58        """
59        self.bck.Clear(True)
60        self.bck.Add((5, 5), (0, 0), (1, 1),
61                     wx.LEFT | wx.EXPAND | wx.ADJUST_MINSIZE, 5)
62        self.type = type
63        if type is None:
64            label = "Right-click on 2D plot for slicer options"
65            title = wx.StaticText(self, -1, label, style=wx.ALIGN_LEFT)
66            self.bck.Add(title, (1, 0), (1, 2),
67                         flag=wx.LEFT | wx.ALIGN_CENTER_VERTICAL, border=15)
68        else:
69            title = wx.StaticText(self, -1,
70                                  "Slicer Parameters:", style=wx.ALIGN_LEFT)
71            self.bck.Add(title, (1, 0), (1, 2),
72                         flag=wx.LEFT | wx.ALIGN_CENTER_VERTICAL, border=15)
73            ix = 0
74            iy = 1
75            self.parameters = []
76            keys = params.keys()
77            keys.sort()
78            for item in keys:
79                iy += 1
80                ix = 0
81                if not item in ["count", "errors"]:
82                    text = wx.StaticText(self, -1, item, style=wx.ALIGN_LEFT)
83                    self.bck.Add(text, (iy, ix), (1, 1),
84                                 wx.LEFT | wx.EXPAND | wx.ADJUST_MINSIZE, 15)
85                    ctl = wx.TextCtrl(self, -1, size=(80, 20),
86                                      style=wx.TE_PROCESS_ENTER)
87                    hint_msg = "Modify the value of %s to change" % item
88                    hint_msg += " the 2D slicer"
89                    ctl.SetToolTipString(hint_msg)
90                    ix = 1
91                    ctl.SetValue(format_number(str(params[item])))
92                    self.Bind(wx.EVT_TEXT_ENTER, self.onTextEnter)
93                    self.parameters.append([item, ctl])
94                    self.bck.Add(ctl, (iy, ix), (1, 1),
95                                 wx.EXPAND | wx.ADJUST_MINSIZE, 0)
96                    ix = 3
97                    self.bck.Add((20, 20), (iy, ix), (1, 1),
98                                 wx.EXPAND | wx.ADJUST_MINSIZE, 0)
99                else:
100                    text = wx.StaticText(self, -1, item + " : ",
101                                         style=wx.ALIGN_LEFT)
102                    self.bck.Add(text, (iy, ix), (1, 1),
103                                 wx.LEFT | wx.EXPAND | wx.ADJUST_MINSIZE, 15)
104                    ctl = wx.StaticText(self, -1,
105                                        format_number(str(params[item])),
106                                        style=wx.ALIGN_LEFT)
107                    ix = 1
108                    self.bck.Add(ctl, (iy, ix), (1, 1),
109                                 wx.EXPAND | wx.ADJUST_MINSIZE, 0)
110            ix = 0
111            iy += 1
112
113            # Change slicer within the window
114            txt = "Slicer"
115            text = wx.StaticText(self, -1, txt, style=wx.ALIGN_LEFT)
116            self.bck.Add(text, (iy, ix), (1, 1),
117                         wx.LEFT | wx.EXPAND | wx.ADJUST_MINSIZE, 15)
118            type_list = ["SectorInteractor", "AnnulusInteractor",
119                         "BoxInteractorX", "BoxInteractorY"]
120            self.type_select = wx.ComboBox(parent=self, choices=type_list)
121            self.Bind(wx.EVT_COMBOBOX, self.onChangeSlicer)
122            index = self.type_select.FindString(self.type)
123            self.type_select.SetSelection(index)
124            self.bck.Add(self.type_select, (iy, 1), (1, 1),
125                         wx.LEFT | wx.EXPAND | wx.ADJUST_MINSIZE, 15)
126
127            # batch slicing parameters
128            title_text = "Batch Slicing Options:"
129            title = wx.StaticText(self, -1, title_text, style=wx.ALIGN_LEFT)
130            iy += 1
131            ln = wx.StaticLine(self, -1, style=wx.LI_VERTICAL)
132            ln.SetSize((60,60))
133            self.bck.Add(ln, (iy, ix), (1, 2),
134                         wx.LEFT | wx.EXPAND | wx.ADJUST_MINSIZE, 15)
135            iy += 1
136            self.bck.Add(title, (iy, ix), (1, 1),
137                         wx.LEFT | wx.EXPAND | wx.ADJUST_MINSIZE, 15)
138            iy += 1
139            self.process_list()
140            self.bck.Add(self.data_list, (iy, ix), (1, 1),
141                         wx.LEFT | wx.EXPAND | wx.ADJUST_MINSIZE, 15)
142            iy += 1
143            button_label = "Apply Slicer to Selected Files"
144            self.batch_slicer_button = wx.Button(parent=self,
145                                                 label=button_label)
146            self.Bind(wx.EVT_BUTTON, self.onBatchSlice)
147            self.bck.Add(self.batch_slicer_button, (iy, ix), (1, 1),
148                             wx.LEFT | wx.EXPAND | wx.ADJUST_MINSIZE, 15)
149            # TODO: Check box for saving file
150            # TODO: append to file information and file type
151            # TODO: Send to fitting options
152
153            iy += 1
154            self.bck.Add((5, 5), (iy, ix), (1, 1),
155                         wx.LEFT | wx.EXPAND | wx.ADJUST_MINSIZE, 5)
156        self.bck.Layout()
157        self.bck.Fit(self)
158        self.parent.GetSizer().Layout()
159
160    def onParamChange(self, evt):
161        """
162        receive an event end reset value text fields
163        inside self.parameters
164        """
165        evt.Skip()
166        if evt.type == "UPDATE":
167            for item in self.parameters:
168                if item[0] in evt.params:
169                    item[1].SetValue("%-5.3g" % evt.params[item[0]])
170                    item[1].Refresh()
171
172    def onTextEnter(self, evt):
173        """
174        Parameters have changed
175        """
176        params = {}
177        has_error = False
178        for item in self.parameters:
179            try:
180                params[item[0]] = float(item[1].GetValue())
181                item[1].SetBackgroundColour(
182                    wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW))
183                item[1].Refresh()
184            except:
185                has_error = True
186                item[1].SetBackgroundColour("pink")
187                item[1].Refresh()
188
189        if not has_error:
190            # Post parameter event
191            # parent here is plotter2D
192            event = SlicerParameterEvent(type=self.type, params=params)
193            wx.PostEvent(self.parent, event)
194
195    def onBatchSlice(self, evt=None):
196        """
197        Batch slicing button is pushed
198        :param evt: Event triggering hide/show of the batch slicer parameters
199        """
200        # Process each data file individually
201        for item in self.data_list.CheckedStrings:
202            # Get data_id
203            num = len(item)
204            spp = self.parent.parent
205            data_panel = spp._data_panel
206            data_list = data_panel.list_cb_data
207            for key in data_list:
208                loaded_key = (key[:num]) if len(key) > num else key
209                if loaded_key == item:
210                    selection = key
211                    break
212            # Check the data checkbox
213            data_ctrl = data_list[selection][0]
214            self.check_item_and_children(data_ctrl=data_ctrl, check_value=True)
215            # Plot all checked data
216            data_panel.on_plot()
217            panel = plot_mgr = None
218            plot_mgrs = spp.plot_panels
219            for key, mgr in plot_mgrs.iteritems():
220                if isinstance(mgr, ModelPanel2D):
221                    plot_mgr = mgr
222                    break
223            if plot_mgr is not None:
224                # TODO: find proper plot window
225                panels = plot_mgr._manager.plot_panels
226                for _, pane in panels.iteritems():
227                    if pane.window_name == item:
228                        panel = pane
229                # TODO: apply slicer
230                print(panels)
231                if panel is not None:
232                    self._apply_slicer_to_plot(panel)
233            # TODO: save file (if desired)
234            # TODO: send to fitting (if desired)
235
236    def onChangeSlicer(self, evt):
237        """
238        Event driven slicer change when self.type_select changes
239        :param evt: Event triggering this change
240        """
241        self._apply_slicer_to_plot(self.parent)
242
243    def _apply_slicer_to_plot(self, plot):
244        """
245        Apply a slicer to *any* plot window, not just parent window
246        :param plot:
247        :return:
248        """
249        type = self.type_select.GetStringSelection()
250        if self.type != type:
251            if type == "SectorInteractor":
252                plot.onSectorQ(None)
253            elif type == "AnnulusInteractor":
254                plot.onSectorPhi(None)
255            elif type == "BoxInteractorX":
256                plot.onBoxavgX(None)
257            elif type == "BoxInteractorY":
258                plot.onBoxavgY(None)
259
260    def check_item_and_children(self, data_ctrl, check_value=True):
261        self.parent.parent._data_panel.tree_ctrl.CheckItem(data_ctrl, check_value)
262        if data_ctrl.HasChildren():
263            if check_value and not data_ctrl.IsExpanded():
264                # Only select children if control is expanded
265                # Always deselect children, regardless (see ticket #259)
266                return
267            for child_ctrl in data_ctrl.GetChildren():
268                self.tree_ctrl.CheckItem(child_ctrl, check_value)
269
270    def process_list(self):
271        main_window = self.parent.parent
272        self.loaded_data = []
273        id = wx.NewId()
274        for key, value in main_window._data_manager.stored_data.iteritems():
275            if isinstance(value.data, Data2D):
276                self.loaded_data.append(value.data.name)
277            if key == self.parent.data2D.id:
278                self.checkme = self.loaded_data.index(value.data.name)
279        self.data_list = wx.CheckListBox(parent=self, id=id,
280                                         choices=self.loaded_data,
281                                         name="Apply Slicer to Data Sets:")
282        self.data_list.Check(self.checkme)
283        self.data_list.Bind(wx.EVT_CHECKLISTBOX, self.onCheckBoxList)
284
285    def onCheckBoxList(self, e):
286        index = e.GetSelection()
287        if index == self.checkme:
288            self.data_list.Check(index)
Note: See TracBrowser for help on using the repository browser.