source: sasview/calculatorview/src/sans/perspectives/calculator/sld_panel.py @ 6550b64

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 6550b64 was 9c30b8c, checked in by Jae Cho <jhjcho@…>, 13 years ago

longer textbox for formula

  • Property mode set to 100644
File size: 19.1 KB
Line 
1"""
2This module provide GUI for the neutron scattering length density calculator
3
4"""
5
6import wx
7import math
8import sys
9
10from sans.guiframe.panel_base import PanelBase
11
12from sans.guiframe.utils import format_number
13from sans.guiframe.utils import check_float
14from sans.guiframe.events import StatusEvent 
15
16# the calculator default value for wavelength is 6
17#import periodictable
18from periodictable import formula
19from periodictable.xsf import xray_energy
20from periodictable.xsf import xray_sld_from_atoms
21from periodictable.nsf import neutron_scattering
22       
23WAVELENGTH = 6.0
24_BOX_WIDTH = 76
25_STATICBOX_WIDTH = 350
26_SCALE = 1e-6
27
28#SLD panel size
29if sys.platform.count("win32") > 0:
30    _STATICBOX_WIDTH = 350
31    PANEL_SIZE = 400
32    FONT_VARIANT = 0
33else:
34    _STATICBOX_WIDTH = 380
35    PANEL_SIZE = 410
36    FONT_VARIANT = 1
37   
38class SldPanel(wx.Panel, PanelBase):
39    """
40    Provides the SLD calculator GUI.
41    """
42    ## Internal nickname for the window, used by the AUI manager
43    window_name = "SLD Calculator"
44    ## Name to appear on the window title bar
45    window_caption = "SLD Calculator"
46    ## Flag to tell the AUI manager to put this panel in the center pane
47    CENTER_PANE = True
48   
49    def __init__(self, parent, base=None, *args, **kwds):
50        """
51        """
52        wx.Panel.__init__(self, parent, *args, **kwds)
53        PanelBase.__init__(self)
54        #Font size
55        self.SetWindowVariant(variant=FONT_VARIANT)
56        # Object that receive status event
57        self.base = base
58        self.wavelength = WAVELENGTH
59        #layout attribute
60        self.compound_ctl = None
61        self.density_ctl = None
62        self.compound = ""
63        self.density = ""
64        self.wavelength_ctl = None
65        self.neutron_sld_real_ctl = None
66        self.neutron_sld_im_ctl = None
67        self.mo_ka_sld_real_ctl = None
68        self.mo_ka_sld_im_ctl = None
69        self.cu_ka_sld_real_ctl = None
70        self.cu_ka_sld_im_ctl = None
71        self.neutron_abs_ctl = None
72        self.neutron_inc_ctl = None
73        self.neutron_length_ctl = None
74        self.button_calculate = None
75        #Draw the panel
76        self._do_layout()
77        self.SetAutoLayout(True)
78        self.Layout()
79       
80    def _do_layout(self):
81        """
82        Draw window content
83        """
84        unit_a = '[A]'
85        unit_density = '[g/cm^(3)]'
86        unit_sld = '[1/A^(2)]'
87        unit_cm1 = '[1/cm]'
88        unit_cm = '[cm]'
89        sizer_input = wx.GridBagSizer(5, 5)
90        sizer_output = wx.GridBagSizer(5, 5)
91        sizer_button = wx.BoxSizer(wx.HORIZONTAL)
92        sizer1 = wx.BoxSizer(wx.HORIZONTAL)
93        sizer2 = wx.BoxSizer(wx.HORIZONTAL)
94        sizer3 = wx.BoxSizer(wx.HORIZONTAL)
95        #---------inputs----------------
96        inputbox = wx.StaticBox(self, -1, "Input")
97        boxsizer1 = wx.StaticBoxSizer(inputbox, wx.VERTICAL)
98        boxsizer1.SetMinSize((_STATICBOX_WIDTH, -1))
99       
100        compound_txt = wx.StaticText(self, -1, 'Compound ')
101        self.compound_ctl = wx.TextCtrl(self, -1, size=(_BOX_WIDTH*2, -1))
102        density_txt = wx.StaticText(self, -1, 'Density ')
103        self.density_ctl = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, -1))
104        unit_density_txt = wx.StaticText(self, -1, unit_density)
105        wavelength_txt = wx.StaticText(self, -1, 'Wavelength ')
106        self.wavelength_ctl = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, -1))
107        self.wavelength_ctl.SetValue(str(self.wavelength))
108        unit_a_txt = wx.StaticText(self, -1, unit_a)
109        iy = 0
110        ix = 0
111        sizer_input.Add(compound_txt, (iy, ix), (1, 1),
112                             wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
113        ix += 1
114        sizer_input.Add(self.compound_ctl, (iy, ix), (1, 1),
115                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
116        iy += 1
117        ix = 0
118        sizer_input.Add(density_txt, (iy, ix), (1, 1),
119                             wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
120        ix += 1
121        sizer_input.Add(self.density_ctl, (iy, ix), (1, 1),
122                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
123        ix +=1
124        sizer_input.Add(unit_density_txt,(iy, ix), (1, 1),
125                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
126        iy += 1
127        ix = 0
128        sizer_input.Add(wavelength_txt, (iy, ix), (1, 1),
129                             wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
130        ix += 1
131        sizer_input.Add(self.wavelength_ctl, (iy, ix), (1, 1),
132                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
133        ix += 1
134        sizer_input.Add(unit_a_txt, (iy, ix), (1, 1),
135                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
136        boxsizer1.Add(sizer_input)
137        sizer1.Add(boxsizer1, 0, wx.EXPAND | wx.ALL, 10)
138        #---------Outputs sizer--------
139        outputbox = wx.StaticBox(self, -1, "Output")
140        boxsizer2 = wx.StaticBoxSizer(outputbox, wx.VERTICAL)
141        boxsizer2.SetMinSize((_STATICBOX_WIDTH, -1))
142       
143        i_complex = '- i'
144        neutron_sld_txt = wx.StaticText(self, -1, 'Neutron SLD')
145        self.neutron_sld_real_ctl = wx.TextCtrl(self, -1,
146                                                 size=(_BOX_WIDTH, -1))
147        self.neutron_sld_real_ctl.SetEditable(False)
148        self.neutron_sld_real_ctl.SetToolTipString("Neutron SLD real.")
149        self.neutron_sld_im_ctl = wx.TextCtrl(self, -1, 
150                                              size=(_BOX_WIDTH, -1))
151        self.neutron_sld_im_ctl.SetEditable(False)
152        self.neutron_sld_im_ctl.SetToolTipString("Neutron SLD imaginary.")
153        neutron_sld_units_txt = wx.StaticText(self, -1, unit_sld)
154       
155        cu_ka_sld_txt = wx.StaticText(self, -1, 'Cu Ka SLD')
156        self.cu_ka_sld_real_ctl = wx.TextCtrl(self, -1,
157                                               size=(_BOX_WIDTH, -1))
158        self.cu_ka_sld_real_ctl.SetEditable(False)
159        self.cu_ka_sld_real_ctl.SetToolTipString("Cu Ka SLD real.")
160        self.cu_ka_sld_im_ctl = wx.TextCtrl(self, -1, 
161                                            size=(_BOX_WIDTH, -1))
162        self.cu_ka_sld_im_ctl.SetEditable(False)
163        self.cu_ka_sld_im_ctl.SetToolTipString("Cu Ka SLD imaginary.")
164        cu_ka_sld_units_txt = wx.StaticText(self, -1, unit_sld)
165       
166        mo_ka_sld_txt = wx.StaticText(self, -1, 'Mo Ka SLD')
167        self.mo_ka_sld_real_ctl = wx.TextCtrl(self, -1,
168                                               size=(_BOX_WIDTH, -1))
169        self.mo_ka_sld_real_ctl.SetEditable(False)
170        self.mo_ka_sld_real_ctl.SetToolTipString("Mo Ka SLD real.")
171        self.mo_ka_sld_im_ctl = wx.TextCtrl(self, -1,
172                                             size=(_BOX_WIDTH, -1))
173        self.mo_ka_sld_im_ctl.SetEditable(False)
174        self.mo_ka_sld_im_ctl.SetToolTipString("Mo Ka SLD imaginary.")
175        mo_ka_sld_units_txt = wx.StaticText(self, -1, unit_sld)
176       
177        neutron_inc_txt = wx.StaticText(self, -1, 'Neutron Inc. Xs')
178        self.neutron_inc_ctl = wx.TextCtrl(self, -1,
179                                            size=(_BOX_WIDTH, -1))
180        self.neutron_inc_ctl.SetEditable(False)
181        self.neutron_inc_ctl.SetToolTipString("Neutron Inc. Xs")
182        neutron_inc_units_txt = wx.StaticText(self, -1,  unit_cm1)
183       
184        neutron_abs_txt = wx.StaticText(self, -1, 'Neutron Abs. Xs')     
185        self.neutron_abs_ctl = wx.TextCtrl(self, -1, 
186                                           size=(_BOX_WIDTH, -1))
187        self.neutron_abs_ctl.SetEditable(False)
188        self.neutron_abs_ctl.SetToolTipString("Neutron Abs. Xs")
189        neutron_abs_units_txt = wx.StaticText(self, -1,  unit_cm1)
190     
191        neutron_length_txt = wx.StaticText(self, -1, 'Neutron 1/e length')
192        self.neutron_length_ctl = wx.TextCtrl(self, -1,
193                                               size=(_BOX_WIDTH, -1))
194        self.neutron_length_ctl.SetEditable(False)
195        self.neutron_length_ctl.SetToolTipString("Neutron 1/e length")
196        neutron_length_units_txt = wx.StaticText(self, -1,  unit_cm)
197     
198        iy = 0
199        ix = 0
200        sizer_output.Add(neutron_sld_txt, (iy, ix), (1, 1),
201                             wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
202        ix += 1
203        sizer_output.Add(self.neutron_sld_real_ctl, (iy, ix), (1, 1),
204                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
205        ix += 1
206        sizer_output.Add(wx.StaticText(self, -1, i_complex),
207                         (iy, ix), (1, 1), wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
208        ix += 1
209        sizer_output.Add(self.neutron_sld_im_ctl,
210                         (iy, ix), (1, 1), wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
211        ix += 1
212        sizer_output.Add(neutron_sld_units_txt,
213                         (iy, ix), (1, 1), wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
214        iy += 1
215        ix = 0
216        sizer_output.Add(cu_ka_sld_txt, (iy, ix), (1, 1),
217                             wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
218        ix += 1
219        sizer_output.Add(self.cu_ka_sld_real_ctl, (iy, ix), (1, 1),
220                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
221        ix += 1
222        sizer_output.Add(wx.StaticText(self, -1, i_complex),
223                         (iy, ix), (1, 1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
224        ix += 1
225        sizer_output.Add(self.cu_ka_sld_im_ctl,
226                         (iy, ix), (1, 1), wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
227        ix += 1
228        sizer_output.Add(cu_ka_sld_units_txt,
229                         (iy, ix), (1, 1), wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
230        iy += 1
231        ix = 0
232        sizer_output.Add(mo_ka_sld_txt,(iy, ix), (1, 1),
233                             wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
234        ix += 1
235        sizer_output.Add(self.mo_ka_sld_real_ctl,(iy, ix), (1, 1),
236                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
237        ix += 1
238        sizer_output.Add(wx.StaticText(self, -1, i_complex),
239                         (iy, ix), (1, 1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
240        ix += 1
241        sizer_output.Add(self.mo_ka_sld_im_ctl,
242                         (iy, ix), (1, 1), wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
243        ix += 1
244        sizer_output.Add(mo_ka_sld_units_txt,
245                         (iy, ix), (1, 1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
246        iy += 1
247        ix = 0
248        sizer_output.Add(neutron_inc_txt, (iy, ix), (1, 1),
249                             wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
250        ix += 1
251        sizer_output.Add(self.neutron_inc_ctl, (iy, ix), (1, 1),
252                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
253        ix += 2
254        sizer_output.Add(neutron_inc_units_txt,(iy, ix), (1, 1),
255                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
256        iy += 1
257        ix = 0
258        sizer_output.Add(neutron_abs_txt, (iy, ix), (1, 1),
259                             wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
260        ix += 1
261        sizer_output.Add(self.neutron_abs_ctl, (iy, ix), (1, 1),
262                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
263        ix += 2
264        sizer_output.Add(neutron_abs_units_txt, (iy, ix), (1, 1),
265                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
266        iy += 1
267        ix = 0
268        sizer_output.Add(neutron_length_txt, (iy, ix), (1, 1),
269                             wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
270        ix += 1
271        sizer_output.Add(self.neutron_length_ctl, (iy, ix), (1, 1),
272                            wx.EXPAND|wx.ADJUST_MINSIZE, 0)
273        ix += 2
274        sizer_output.Add(neutron_length_units_txt, (iy, ix), (1, 1),
275                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
276        boxsizer2.Add(sizer_output)
277        sizer2.Add(boxsizer2, 0, wx.EXPAND|wx.ALL, 10)
278        #-----Button  sizer------------
279   
280        id = wx.NewId()
281        self.button_calculate = wx.Button(self, id, "Calculate")
282        self.button_calculate.SetToolTipString("Calculate SLD.")
283        self.Bind(wx.EVT_BUTTON, self.calculateSld, id=id)   
284       
285        sizer_button.Add((250, 20), 1, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
286        sizer_button.Add(self.button_calculate, 0, wx.RIGHT|wx.ADJUST_MINSIZE, 20)
287        sizer3.Add(sizer_button)
288        #---------layout----------------
289        vbox  = wx.BoxSizer(wx.VERTICAL)
290        vbox.Add(sizer1)
291        vbox.Add(sizer2)
292        vbox.Add(sizer3)
293        vbox.Fit(self) 
294        self.SetSizer(vbox)
295       
296    def calculate_xray_sld(self, element):
297        """
298        Get an element and compute the corresponding SLD for a given formula
299       
300        :param element:  elements a string of existing atom
301       
302        """
303        myformula = formula(str(element))
304        if len(myformula.atoms) != 1:
305            return 
306        element = myformula.atoms.keys()[0] 
307        energy = xray_energy(element.K_alpha)
308       
309        self.sld_formula = formula(str(self.compound), density=self.density)
310        atom = self.sld_formula.atoms
311        return xray_sld_from_atoms(atom, density=self.density, energy= energy)
312   
313    def check_inputs(self):
314        """Check validity user inputs"""
315        flag = True
316        msg = ""
317        if check_float(self.density_ctl):
318            self.density = float(self.density_ctl.GetValue())
319        else:
320            flag = False
321            msg += "Error for Density value :expect float"
322   
323        self.wavelength = self.wavelength_ctl.GetValue()
324        if str(self.wavelength).lstrip().rstrip() == "":
325            self.wavelength = WAVELENGTH
326            self.wavelength_ctl.SetValue(str(WAVELENGTH))
327            self.wavelength_ctl.SetBackgroundColour(wx.WHITE)
328            self.wavelength_ctl.Refresh()
329            msg += "Default value for wavelength is 6.0"
330        else:
331            if check_float(self.wavelength_ctl):
332                self.wavelength = float(self.wavelength)
333            else:
334                flag = False
335                msg += "Error for wavelength value :expect float"
336               
337        self.compound = self.compound_ctl.GetValue().lstrip().rstrip()
338        if self.compound != "":
339            try :
340                formula(self.compound)
341                self.compound_ctl.SetBackgroundColour(wx.WHITE)
342                self.compound_ctl.Refresh()
343            except:
344                self.compound_ctl.SetBackgroundColour("pink")
345                self.compound_ctl.Refresh()
346                flag = False
347                msg += "Enter correct formula"
348        else:
349            self.compound_ctl.SetBackgroundColour("pink")
350            self.compound_ctl.Refresh()
351            flag = False
352            msg += "Enter a formula"
353        return flag, msg
354       
355    def calculate_sld_helper(self, element, density, molecule_formula):
356        """
357        Get an element and compute the corresponding SLD for a given formula
358       
359        :param element:  elements a string of existing atom
360       
361        """
362        element_formula = formula(str(element))
363        if len(element_formula.atoms) != 1:
364            return 
365        element = element_formula.atoms.keys()[0] 
366        energy = xray_energy(element.K_alpha)
367        atom = molecule_formula.atoms
368        return xray_sld_from_atoms(atom, density=density, energy=energy)
369
370
371    def calculateSld(self, event):
372        """
373            Calculate the neutron scattering density length of a molecule
374        """
375        self.clear_outputs()
376        try:
377            #Check validity user inputs
378            flag, msg = self.check_inputs()
379            if self.base is not None and msg.lstrip().rstrip() != "":
380                msg = "SLD Calculator: %s" % str(msg)
381                wx.PostEvent(self.base, StatusEvent(status=msg))
382            if not flag:
383               return 
384            #get ready to compute
385            self.sld_formula = formula(self.compound,
386                                            density=self.density)
387            (sld_real, sld_im, _), (_, absorp, incoh), \
388                        length = neutron_scattering(compound=self.compound,
389                                   density=self.density, 
390                                   wavelength=self.wavelength) 
391            cu_real, cu_im = self.calculate_sld_helper(element="Cu",
392                                                 density=self.density,
393                                        molecule_formula=self.sld_formula)
394            mo_real, mo_im = self.calculate_sld_helper(element="Mo", 
395                                                       density=self.density,
396                                     molecule_formula=self.sld_formula)
397            # set neutron sld values
398            val = format_number(sld_real * _SCALE)
399            self.neutron_sld_real_ctl.SetValue(val)
400            val = format_number(math.fabs(sld_im) * _SCALE)
401            self.neutron_sld_im_ctl.SetValue(val)
402            # Compute the Cu SLD
403            self.cu_ka_sld_real_ctl.SetValue(format_number(cu_real *_SCALE))
404            val = format_number(math.fabs(cu_im )* _SCALE)
405            self.cu_ka_sld_im_ctl.SetValue(val)
406            # Compute the Mo SLD
407            self.mo_ka_sld_real_ctl.SetValue(format_number(mo_real *_SCALE))
408            val = format_number(math.fabs(mo_im)* _SCALE)
409            self.mo_ka_sld_im_ctl.SetValue(val)
410            # set incoherence and absorption
411            self.neutron_inc_ctl.SetValue(format_number(incoh))
412            self.neutron_abs_ctl.SetValue(format_number(absorp))
413            # Neutron length
414            self.neutron_length_ctl.SetValue(format_number(length))
415            # display wavelength
416            self.wavelength_ctl.SetValue(str(self.wavelength))
417        except:
418            if self.base is not None:
419                msg = "SLD Calculator: %s"%(sys.exc_value)
420                wx.PostEvent(self.base, StatusEvent(status=msg))
421        if event is not None:
422            event.Skip()
423           
424    def clear_outputs(self):
425        """
426        Clear the outputs textctrl
427        """
428        self.neutron_sld_real_ctl.SetValue("")
429        self.neutron_sld_im_ctl.SetValue("")
430        self.mo_ka_sld_real_ctl.SetValue("")
431        self.mo_ka_sld_im_ctl.SetValue("")
432        self.cu_ka_sld_real_ctl.SetValue("")
433        self.cu_ka_sld_im_ctl.SetValue("")
434        self.neutron_abs_ctl.SetValue("")
435        self.neutron_inc_ctl.SetValue("")
436        self.neutron_length_ctl.SetValue("")
437       
438       
439class SldWindow(wx.Frame):
440    """
441    """
442    def __init__(self, parent=None, title="SLD Calculator",
443                  base=None, size=(PANEL_SIZE, PANEL_SIZE), *args, **kwds):
444        """
445        """
446        kwds['title'] = title
447        kwds['size'] = size
448        wx.Frame.__init__(self, parent, *args, **kwds)
449        """
450        """
451        self.panel = SldPanel(self, base=base)
452        self.Centre()
453        self.Show(True)
454       
455class ViewApp(wx.App):
456    """
457    """
458    def OnInit(self):
459        """
460        """
461        frame = SldWindow(None, title='SLD Calculator')   
462        frame.Show(True)
463        self.SetTopWindow(frame)
464        return True
465       
466
467if __name__ == "__main__": 
468    app = ViewApp(0)
469    app.MainLoop()     
Note: See TracBrowser for help on using the repository browser.