source: sasview/src/sas/perspectives/calculator/slit_length_calculator_panel.py @ 7168b8b

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 7168b8b was 79492222, checked in by krzywon, 10 years ago

Changed the file and folder names to remove all SANS references.

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