source: sasview/calculatorview/perspectives/calculator/sld_panel.py @ 210ff4f

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 210ff4f was 855546d, checked in by Gervaise Alina <gervyh@…>, 14 years ago

add minus sign to all imaginary part of sld

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