source: sasview/src/sas/perspectives/calculator/slit_length_calculator_panel.py @ 418e59f

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.2release_4.0.1ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since 418e59f was 9654baf, checked in by butler, 10 years ago
  • Add help to Kiessig calculator plus some sizing/positioning panel
  • change order of buttons on slit length calculator to match the rest of

the panels with close be the furthest right button on panel

  • Property mode set to 100644
File size: 11.9 KB
Line 
1"""
2This software was developed by the University of Tennessee as part of the
3Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
4project funded by the US National Science Foundation.
5
6See the license text in license.txt
7
8copyright 2008, 2009, University of Tennessee
9"""
10
11import wx
12import sys
13import os
14
15from sas.guiframe.panel_base import PanelBase
16
17from sas.guiframe.events import StatusEvent 
18from sas.calculator.slit_length_calculator import SlitlengthCalculator 
19from calculator_widgets import OutputTextCtrl
20from calculator_widgets import InterActiveOutputTextCtrl
21from sas.perspectives.calculator import calculator_widgets as widget   
22from sas.guiframe.documentation_window import DocumentationWindow
23
24_BOX_WIDTH = 76
25#Slit length panel size
26if sys.platform.count("win32") > 0:
27    PANEL_WIDTH = 500
28    PANEL_HEIGHT = 210
29    FONT_VARIANT = 0
30else:
31    PANEL_WIDTH = 530
32    PANEL_HEIGHT = 210
33    FONT_VARIANT = 1
34 
35class SlitLengthCalculatorPanel(wx.Panel, PanelBase):
36    """
37        Provides the slit length calculator GUI.
38    """
39    ## Internal nickname for the window, used by the AUI manager
40    window_name = "Slit Size Calculator"
41    ## Name to appear on the window title bar
42    window_caption = "Slit Size Calculator"
43    ## Flag to tell the AUI manager to put this panel in the center pane
44    CENTER_PANE = True
45   
46    def __init__(self, parent, *args, **kwds):
47        wx.Panel.__init__(self, parent, *args, **kwds)
48        PanelBase.__init__(self)
49        #Font size
50        self.SetWindowVariant(variant=FONT_VARIANT)
51        #thread to read data
52        self.reader = None
53        # Default location
54        self._default_save_location = os.getcwd() 
55        # Object that receive status event
56        self.parent = parent
57        self._do_layout()
58       
59    def _define_structure(self):
60        """
61            Define the main sizers building to build this application.
62        """
63        self.main_sizer = wx.BoxSizer(wx.VERTICAL)
64        self.box_source = wx.StaticBox(self, -1,str("Slit Size Calculator"))
65        self.boxsizer_source = wx.StaticBoxSizer(self.box_source,
66                                                    wx.VERTICAL)
67        self.data_name_sizer = wx.BoxSizer(wx.HORIZONTAL)
68        self.slit_size_sizer = wx.BoxSizer(wx.HORIZONTAL)
69        self.hint_sizer = wx.BoxSizer(wx.HORIZONTAL)
70        self.button_sizer = wx.BoxSizer(wx.HORIZONTAL)
71       
72    def _layout_data_name(self):
73        """
74            Fill the sizer containing data's name
75        """
76        data_name_txt = wx.StaticText(self, -1, 'Data: ')
77        self.data_name_tcl = OutputTextCtrl(self, -1, 
78                                            size=(_BOX_WIDTH*4, -1))
79        data_hint = "Loaded data"
80        self.data_name_tcl.SetToolTipString(data_hint)
81        #control that triggers importing data
82        id = wx.NewId()
83        self.browse_button = wx.Button(self, id, "Browse")
84        hint_on_browse = "Click on this button to import data in this panel."
85        self.browse_button.SetToolTipString(hint_on_browse)
86        self.Bind(wx.EVT_BUTTON, self.on_load_data, id=id)
87        self.data_name_sizer.AddMany([(data_name_txt, 0, wx.LEFT, 15),
88                                      (self.data_name_tcl, 0, wx.LEFT, 10),
89                                      (self.browse_button, 0, wx.LEFT, 10)])
90    def _layout_slit_size(self):
91        """
92            Fill the sizer containing slit size information
93        """
94        slit_size_txt = wx.StaticText(self, -1, 'Slit Size (FWHM/2): ')
95        self.slit_size_tcl = InterActiveOutputTextCtrl(self, -1,
96                                                       size=(_BOX_WIDTH, -1))
97        slit_size_hint = " Estimated full slit size"
98        self.slit_size_tcl.SetToolTipString(slit_size_hint)
99        slit_size_unit_txt = wx.StaticText(self, -1, 'Unit: ')
100        self.slit_size_unit_tcl = OutputTextCtrl(self, -1, 
101                                                 size=(_BOX_WIDTH, -1)) 
102        slit_size_unit_hint = "Full slit size's unit"
103        self.slit_size_unit_tcl.SetToolTipString(slit_size_unit_hint)
104        self.slit_size_sizer.AddMany([(slit_size_txt, 0, wx.LEFT, 15),
105                                      (self.slit_size_tcl, 0, wx.LEFT, 10),
106                                      (slit_size_unit_txt, 0, wx.LEFT, 10),
107                                    (self.slit_size_unit_tcl, 0, wx.LEFT, 10)])
108   
109    def _layout_hint(self):
110        """
111            Fill the sizer containing hint
112        """
113        hint_msg = "This calculation works only for  SAXSess beam profile data."
114        self.hint_txt = wx.StaticText(self, -1, hint_msg)
115        self.hint_sizer.AddMany([(self.hint_txt, 0, wx.LEFT, 15)])
116   
117    def _layout_button(self): 
118        """
119            Do the layout for the button widgets
120        """ 
121        self.bt_close = wx.Button(self, wx.ID_CANCEL,'Close')
122        self.bt_close.Bind(wx.EVT_BUTTON, self.on_close)
123        self.bt_close.SetToolTipString("Close this window.")
124 
125        id = wx.NewId()
126        self.button_help = wx.Button(self, id, "HELP")
127        self.button_help.SetToolTipString("Help for slit length calculator.")
128        self.Bind(wx.EVT_BUTTON, self.on_help,id=id)   
129
130        self.button_sizer.AddMany([(self.button_help, 0, wx.LEFT, 280),
131                                   (self.bt_close, 0, wx.LEFT, 20)])
132               
133    def _do_layout(self):
134        """
135            Draw window content
136        """
137        self._define_structure()
138        self._layout_data_name()
139        self._layout_slit_size()
140        self._layout_hint()
141        self._layout_button()
142        self.boxsizer_source.AddMany([(self.data_name_sizer, 0,
143                                          wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
144                                   (self.slit_size_sizer, 0,
145                                     wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
146                                     (self.hint_sizer, 0,
147                                     wx.EXPAND|wx.TOP|wx.BOTTOM, 5)])
148        self.main_sizer.AddMany([(self.boxsizer_source, 0, wx.ALL, 10),
149                                  (self.button_sizer, 0,
150                                    wx.EXPAND|wx.TOP|wx.BOTTOM, 5)])
151        self.SetSizer(self.main_sizer)
152        self.SetAutoLayout(True)
153       
154    def choose_data_file(self, location=None):
155        path = None
156        filename = ''
157        if location == None:
158            location = os.getcwd()
159       
160        wildcard = "SAXSess Data 1D (*.DAT, *.dat)|*.DAT" 
161       
162        dlg = wx.FileDialog(self, "Choose a file", location,
163                            "", wildcard, wx.OPEN)
164        if dlg.ShowModal() == wx.ID_OK:
165            path = dlg.GetPath()
166            filename = os.path.basename(path)
167        dlg.Destroy()
168       
169        return path
170
171    def on_help(self, event):   
172        """
173        Bring up the slit length calculator Documentation whenever
174        the HELP button is clicked.
175       
176        Calls DocumentationWindow with the path of the location within the
177        documentation tree (after /doc/ ....".  Note that when using old
178        versions of Wx (before 2.9) and thus not the release version of
179        installers, the help comes up at the top level of the file as
180        webbrowser does not pass anything past the # to the browser when it is
181        running "file:///...."
182   
183    :param evt: Triggers on clicking the help button
184    """
185               
186        _TreeLocation = "user/perspectives/calculator/slit_calculator_help.html"
187        _doc_viewer = DocumentationWindow(self, -1, \
188             _TreeLocation,"Slit Length Calculator Help")
189
190    def on_close(self, event):
191        """
192            close the window containing this panel
193        """
194        self.parent.Close()
195       
196    def on_load_data(self, event):
197        """
198            Open a file dialog to allow the user to select a given file.
199            The user is only allow to load file with extension .DAT or .dat.
200            Display the slit size corresponding to the loaded data.
201        """
202        path = self.choose_data_file(location=self._default_save_location)
203       
204        if path is None:
205            return 
206        self._default_save_location = path
207        try:
208            #Load data
209            from load_thread import DataReader
210            ## If a thread is already started, stop it
211            if self.reader is not None and self.reader.isrunning():
212                self.reader.stop()
213            if self.parent.parent is not None:
214                wx.PostEvent(self.parent.parent, 
215                                StatusEvent(status="Loading...",
216                                type="progress"))
217            self.reader = DataReader(path=path,
218                                    completefn=self.complete_loading,
219                                    updatefn=self.load_update)
220            self.reader.queue()
221            self.load_update()
222        except:
223            if self.parent.parent is None:
224                return 
225            msg = "Slit Length Calculator: %s" % (sys.exc_value)
226            wx.PostEvent(self.parent.parent,
227                          StatusEvent(status=msg, type='stop'))
228            return 
229       
230    def load_update(self):
231        """
232        print update on the status bar
233        """
234        if self.parent.parent is None:
235                return 
236        if self.reader.isrunning():
237            type = "progress"
238        else:
239            type = "stop"
240        wx.PostEvent(self.parent.parent, StatusEvent(status="",
241                                                  type=type))
242           
243    def complete_loading(self, data=None, filename=''):
244        """
245            Complete the loading and compute the slit size
246        """
247        if data is None or data.__class__.__name__ == 'Data2D':
248            if self.parent.parent is None:
249                return 
250            msg = "Slit Length cannot be computed for 2D Data"
251            wx.PostEvent(self.parent.parent, 
252                         StatusEvent(status=msg, type='stop'))
253            return 
254        self.data_name_tcl.SetValue(str(data.filename))
255        #compute the slit size
256        try:
257            x = data.x
258            y = data.y
259            if x == [] or  x is None or y == [] or y is None:
260                msg = "The current data is empty please check x and y"
261                raise ValueError, msg
262            slit_length_calculator = SlitlengthCalculator()
263            slit_length_calculator.set_data(x=x, y=y)
264            slit_length = slit_length_calculator.calculate_slit_length()
265        except:
266            if self.parent.parent is None:
267                return 
268            msg = "Slit Size Calculator: %s" % (sys.exc_value)
269            wx.PostEvent(self.parent.parent,
270                          StatusEvent(status=msg, type='stop'))
271            return 
272        self.slit_size_tcl.SetValue(str(slit_length))
273        #Display unit
274        self.slit_size_unit_tcl.SetValue('[Unknown]')
275        if self.parent.parent is None:
276            return 
277        msg = "Load Complete"
278        wx.PostEvent(self.parent.parent, StatusEvent(status=msg, type='stop'))
279   
280   
281class SlitLengthCalculatorWindow(widget.CHILD_FRAME):
282    """
283    """
284    def __init__(self, parent=None, manager=None, title="Slit Size Calculator",
285                size=(PANEL_WIDTH,PANEL_HEIGHT), *args, **kwds):
286        """
287        """
288        kwds['size']= size
289        kwds['title']= title
290        widget.CHILD_FRAME.__init__(self, parent, *args, **kwds)
291        self.parent = parent
292        self.manager = manager
293        self.panel = SlitLengthCalculatorPanel(parent=self)
294        self.Bind(wx.EVT_CLOSE, self.on_close)
295        self.SetPosition((25, 10))
296        self.Show(True)
297
298    def on_close(self, event):
299        """
300        Close event
301        """
302        if self.manager != None:
303            self.manager.cal_slit_frame = None
304        self.Destroy()
305       
306if __name__ == "__main__": 
307    app = wx.PySimpleApp()
308    widget.CHILD_FRAME = wx.Frame
309    frame = SlitLengthCalculatorWindow()   
310    frame.Show(True)
311    app.MainLoop()     
Note: See TracBrowser for help on using the repository browser.