source: sasview/calculatorview/perspectives/calculator/sld_panel.py @ fa1b4ad

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 fa1b4ad was 810f196, checked in by Gervaise Alina <gervyh@…>, 14 years ago

working on sld calculator

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