source: trunk/fprime.py @ 3968

Last change on this file since 3968 was 3968, checked in by vondreele, 2 years ago

add grid control to absorb & fprime

File size: 24.2 KB
Line 
1#!/usr/bin/env python
2
3"""main Fprime routines
4   Copyright: 2008, Robert B. Von Dreele (Argonne National Laboratory)
5"""
6from __future__ import division, print_function
7import platform
8import math
9import wx
10import numpy as np
11import sys
12import matplotlib as mpl
13import GSASIIpath
14GSASIIpath.SetVersionNumber("$Revision: 3765 $")
15import GSASIIElem as G2elem
16import GSASIIElemGUI as G2elemGUI
17
18try:
19    wx.NewIdRef
20    wx.NewId = wx.NewIdRef
21except AttributeError:
22    pass
23
24if '2' in platform.python_version_tuple()[0]:
25    Gkmu = unichr(0x3bc)
26    Gktheta = unichr(0x3b8)
27    Gklambda = unichr(0x3bb)
28    GkDelta = unichr(0x0394)
29    Pwr10 = unichr(0x0b9)+unichr(0x2070)
30    Pwr20 = unichr(0x0b2)+unichr(0x2070)
31    Pwrm1 = unichr(0x207b)+unichr(0x0b9)
32    Pwrm2 = unichr(0x207b)+unichr(0x0b2)
33    Pwrm6 = unichr(0x207b)+unichr(0x2076)
34    Pwrm4 = unichr(0x207b)+unichr(0x2074)
35    Angstr = unichr(0x00c5)
36else:
37    Gkmu = chr(0x3bc)
38    Gktheta = chr(0x3b8)
39    Gklambda = chr(0x3bb)
40    GkDelta = chr(0x0394)
41    Pwr10 = chr(0x0b9)+chr(0x2070)
42    Pwr20 = chr(0x0b2)+chr(0x2070)
43    Pwrm1 = chr(0x207b)+chr(0x0b9)
44    Pwrm2 = chr(0x207b)+chr(0x0b2)
45    Pwrm6 = chr(0x207b)+chr(0x2076)
46    Pwrm4 = chr(0x207b)+chr(0x2074)
47    Angstr = chr(0x00c5)   
48
49[wxID_FPRIMECHOICE1, wxID_FPRIMECHOICE2, wxID_SPINTEXT1, wxID_SPINTEXT2,
50 wxID_FPRIMERESULTS,wxID_FPRIMESLIDER1, wxID_SPINBUTTON,
51] = [wx.NewId() for _init_ctrls in range(7)]
52
53[wxID_FPRIMEEXIT, wxID_FPRIMEDELETE, wxID_FPRIMENEW, 
54] = [wx.NewId() for _init_coll_FPRIME_Items in range(3)]
55
56[wxID_FPRIMEKALPHAAGKA, wxID_FPRIMEKALPHACOKA, wxID_FPRIMEKALPHACRKA, 
57 wxID_FPRIMEKALPHACUKA, wxID_FPRIMEKALPHAFEKA, wxID_FPRIMEKALPHAMNKA, 
58 wxID_FPRIMEKALPHAMOKA, wxID_FPRIMEKALPHANIKA, wxID_FPRIMEKALPHAZNKA, 
59] = [wx.NewId() for _init_coll_KALPHA_Items in range(9)]
60
61[wxID_FPRIMEABOUT] = [wx.NewId() for _init_coll_ABOUT_Items in range(1)]
62
63class Fprime(wx.Frame):
64    ''' '''
65    Elems = []
66    Wave = 1.5405      #CuKa default
67    Kev = 12.397639    #keV for 1A x-rays
68    for arg in sys.argv:
69        if '-w' in arg:
70            Wave = float(arg.split('-w')[1])
71        elif '-e' in arg:
72            E = float(arg.split('-e')[1])
73            Wave = Kev/E
74        elif '-h' in arg:
75            print( '''
76fprime.py can take the following arguments:
77-h   -  this help listing
78-wv  -  set default wavelength to v, e.g. -w1.54 sets wavelength to 1.54A
79-ev  -  set default energy to v, e.g. -e27 sets energy to 27keV
80without arguments fprime uses CuKa as default (Wave=1.54052A, E=8.0478keV)
81''')
82            sys.exit()
83    Wmin = 0.05        #wavelength range
84    Wmax = 3.0
85    Wres = 0.004094    #plot resolution step size as const delta-lam/lam - gives 1000 steps for Wmin to Wmax
86    Eres = 1.5e-4      #typical energy resolution for synchrotron x-ray sources
87    ffpfignum = 1
88    fppfignum = 2
89    Energy = Kev/Wave
90    ifWave = True
91    FFxaxis = 'S'      #default form factor plot is vs sin(theta)/lambda
92    def _init_coll_ABOUT_Items(self, parent):
93
94        parent.Append(wxID_FPRIMEABOUT, 'About')
95        self.Bind(wx.EVT_MENU, self.OnABOUTItems0Menu, id=wxID_FPRIMEABOUT)
96
97    def _init_coll_menuBar1_Menus(self, parent):
98
99        parent.Append(menu=self.FPRIME, title='Fprime')
100        parent.Append(menu=self.KALPHA, title='Kalpha')
101        parent.Append(menu=self.ABOUT, title='About')
102
103    def _init_coll_KALPHA_Items(self, parent):
104        "Set of characteristic radiation from sealed tube sources"
105
106        parent.Append(wxID_FPRIMEKALPHACRKA,'CrKa')
107        parent.Append(wxID_FPRIMEKALPHAMNKA,'MnKa')
108        parent.Append(wxID_FPRIMEKALPHAFEKA,'FeKa')
109        parent.Append(wxID_FPRIMEKALPHACOKA,'CoKa')
110        parent.Append(wxID_FPRIMEKALPHANIKA,'NiKa')
111        parent.Append(wxID_FPRIMEKALPHACUKA,'CuKa')
112        parent.Append(wxID_FPRIMEKALPHAZNKA,'ZnKa')
113        parent.Append(wxID_FPRIMEKALPHAMOKA,'MoKa')
114        parent.Append(wxID_FPRIMEKALPHAAGKA,'AgKa')
115        self.Bind(wx.EVT_MENU, self.OnKALPHACrkaMenu, id=wxID_FPRIMEKALPHACRKA)
116        self.Bind(wx.EVT_MENU, self.OnKALPHAMnkaMenu, id=wxID_FPRIMEKALPHAMNKA)
117        self.Bind(wx.EVT_MENU, self.OnKALPHAFekaMenu, id=wxID_FPRIMEKALPHAFEKA)
118        self.Bind(wx.EVT_MENU, self.OnKALPHACokaMenu, id=wxID_FPRIMEKALPHACOKA)
119        self.Bind(wx.EVT_MENU, self.OnKALPHANikaMenu, id=wxID_FPRIMEKALPHANIKA)
120        self.Bind(wx.EVT_MENU, self.OnKALPHACukaMenu, id=wxID_FPRIMEKALPHACUKA)
121        self.Bind(wx.EVT_MENU, self.OnKALPHAZnkaMenu, id=wxID_FPRIMEKALPHAZNKA)
122        self.Bind(wx.EVT_MENU, self.OnKALPHAMokaMenu, id=wxID_FPRIMEKALPHAMOKA)
123        self.Bind(wx.EVT_MENU, self.OnKALPHAAgkaMenu, id=wxID_FPRIMEKALPHAAGKA)
124
125    def _init_coll_FPRIME_Items(self, parent):
126        parent.Append(wxID_FPRIMENEW,'&New Element','Add new element')
127        self.Delete = parent.Append(wxID_FPRIMEDELETE,'&Delete Element','Delete an element')
128        self.Delete.Enable(False)
129        parent.Append(wxID_FPRIMEEXIT,'&Exit','Exit Fprime')
130        self.Bind(wx.EVT_MENU, self.OnFPRIMEExitMenu, id=wxID_FPRIMEEXIT)
131        self.Bind(wx.EVT_MENU, self.OnFPRIMENewMenu, id=wxID_FPRIMENEW)
132        self.Bind(wx.EVT_MENU, self.OnFPRIMEDeleteMenu, id=wxID_FPRIMEDELETE)
133
134    def _init_utils(self):
135        self.FPRIME = wx.Menu(title='')
136
137        self.KALPHA = wx.Menu(title='')
138        self.KALPHA.SetEvtHandlerEnabled(True)
139
140        self.ABOUT = wx.Menu(title='')
141
142        self.menuBar1 = wx.MenuBar()
143
144        self._init_coll_FPRIME_Items(self.FPRIME)
145        self._init_coll_KALPHA_Items(self.KALPHA)
146        self._init_coll_ABOUT_Items(self.ABOUT)
147        self._init_coll_menuBar1_Menus(self.menuBar1)
148
149    def _init_ctrls(self, parent):
150
151        wx.Frame.__init__(self, parent=parent,
152              size=wx.Size(500, 300),style=wx.DEFAULT_FRAME_STYLE ^ wx.CLOSE_BOX, title='Fprime')             
153        self._init_utils()
154        self.SetMenuBar(self.menuBar1)
155        panel = wx.Panel(self)
156
157        mainSizer = wx.BoxSizer(wx.VERTICAL)
158        self.Results = wx.TextCtrl( parent=panel,style=wx.TE_MULTILINE|wx.TE_DONTWRAP )
159        self.Results.SetEditable(False)
160        mainSizer.Add(self.Results,1,wx.ALIGN_CENTER_HORIZONTAL|wx.EXPAND)
161        mainSizer.Add((10,15),0)
162
163        selSizer = wx.BoxSizer(wx.HORIZONTAL)
164        selSizer.Add((5,10),0)
165        selSizer.Add(wx.StaticText(parent=panel, label='Wavelength:'),0,
166            wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
167        selSizer.Add((5,10),0)
168        self.SpinText1 = wx.TextCtrl(id=wxID_SPINTEXT1, parent=panel, 
169              size=wx.Size(100,20), value = "%6.4f" % (self.Wave),style=wx.TE_PROCESS_ENTER )
170        selSizer.Add(self.SpinText1,0)
171        selSizer.Add((5,10),0)
172        self.SpinText1.Bind(wx.EVT_TEXT_ENTER, self.OnSpinText1, id=wxID_SPINTEXT1)
173       
174        selSizer.Add(wx.StaticText(parent=panel, label='Energy:'),0,
175            wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
176        selSizer.Add((5,10),0)
177        self.SpinText2 = wx.TextCtrl(id=wxID_SPINTEXT2, parent=panel, 
178              size=wx.Size(100,20), value = "%7.4f" % (self.Energy),style=wx.TE_PROCESS_ENTER) 
179        selSizer.Add(self.SpinText2,0)
180        self.SpinText2.Bind(wx.EVT_TEXT_ENTER, self.OnSpinText2, id=wxID_SPINTEXT2)
181        mainSizer.Add(selSizer,0)
182        mainSizer.Add((10,10),0)
183       
184        slideSizer = wx.BoxSizer(wx.HORIZONTAL)
185        self.SpinButton = wx.SpinButton(id=wxID_SPINBUTTON, parent=panel, 
186              size=wx.Size(25,24), style=wx.SP_VERTICAL | wx.SP_ARROW_KEYS)
187        slideSizer.Add(self.SpinButton,0,wx.ALIGN_RIGHT)
188        self.SpinButton.SetRange(int(10000.*self.Wmin),int(10000.*self.Wmax))
189        self.SpinButton.SetValue(int(10000.*self.Wave))
190        self.SpinButton.Bind(wx.EVT_SPIN, self.OnSpinButton, id=wxID_SPINBUTTON)
191
192        self.slider1 = wx.Slider(id=wxID_FPRIMESLIDER1, maxValue=int(1000.*self.Wmax),
193            minValue=int(1000.*self.Wmin), parent=panel,style=wx.SL_HORIZONTAL,
194            value=int(self.Wave*1000.), )
195        slideSizer.Add(self.slider1,1,wx.EXPAND|wx.ALIGN_RIGHT)
196        self.slider1.Bind(wx.EVT_SLIDER, self.OnSlider1, id=wxID_FPRIMESLIDER1)
197        mainSizer.Add(slideSizer,0,wx.EXPAND)
198        mainSizer.Add((10,10),0)
199       
200        choiceSizer = wx.BoxSizer(wx.HORIZONTAL)
201        choiceSizer.Add((5,10),0)
202        choiceSizer.Add(wx.StaticText(parent=panel, label='Plot scales:'),
203            0,wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
204        choiceSizer.Add((5,10),0)
205
206        self.choice1 = wx.ComboBox(id=wxID_FPRIMECHOICE1, parent=panel, value='Wavelength',
207             choices=['Wavelength','Energy'],style=wx.CB_READONLY|wx.CB_DROPDOWN)
208        choiceSizer.Add(self.choice1,0)
209        choiceSizer.Add((10,10),0)
210        self.choice1.Bind(wx.EVT_COMBOBOX, self.OnChoice1, id=wxID_FPRIMECHOICE1)
211
212        def OnChoice2(event):
213            if event.GetString() == ' sin('+Gktheta+')/'+Gklambda:
214                self.FFxaxis = 'S'
215            elif event.GetString() == ' Q':
216                self.FFxaxis = 'Q'
217            else:
218                self.FFxaxis = 'T'
219            self.UpDateFPlot(self.Wave,rePlot=False)
220           
221        self.choice2 = wx.ComboBox(id=wxID_FPRIMECHOICE2, value=' sin('+Gktheta+')/'+Gklambda,
222            choices=[' sin('+Gktheta+')/'+Gklambda,' 2'+Gktheta,' Q'],
223            parent=panel, style=wx.CB_READONLY|wx.CB_DROPDOWN)
224        choiceSizer.Add(self.choice2,0)
225        self.choice2.Bind(wx.EVT_COMBOBOX, OnChoice2, id=wxID_FPRIMECHOICE2)
226        mainSizer.Add(choiceSizer,0)
227        mainSizer.Add((10,10),0)
228        panel.SetSizer(mainSizer)
229
230    def __init__(self, parent):
231        self._init_ctrls(parent)
232        self.parent = parent
233        self.Lines = []
234        self.linePicked = None
235       
236    def OnFPRIMEExitMenu(self, event):
237        self.parent.G2plotNB.Delete('Fprime')
238        self.Close()
239        self.Destroy()
240
241    def OnFPRIMENewMenu(self, event):
242        ElList = []
243        for Elem in self.Elems: ElList.append(Elem[0])
244        PE = G2elemGUI.PickElements(self,ElList)
245        if PE.ShowModal() == wx.ID_OK:
246            Elems = PE.Elem
247        PE.Destroy()
248        if Elems:
249            for El in Elems:
250                ElemSym = El.strip().upper()
251                if ElemSym not in ElList:
252                    FormFactors = G2elem.GetFormFactorCoeff(ElemSym)
253                    for FormFac in FormFactors:
254                        FormSym = FormFac['Symbol'].strip()
255                        if FormSym == ElemSym:
256                            Z = FormFac['Z']                #At. No.
257                            Orbs = G2elem.GetXsectionCoeff(ElemSym)
258                            Elem = (ElemSym,Z,FormFac,Orbs)
259                    Fprime.Elems.append(Elem)
260            self.Delete.Enable(True)
261            self.CalcFPPS()
262            self.SetWaveEnergy(self.Wave)
263           
264    def OnFPRIMEDeleteMenu(self, event):
265        if len(self.Elems):
266            ElList = []
267            for Elem in self.Elems: ElList.append(Elem[0])
268            S = []
269            DE = G2elemGUI.DeleteElement(self,ElList)
270            if DE.ShowModal() == wx.ID_OK:
271                El = DE.GetDeleteElement().strip().upper()
272                for Elem in self.Elems:
273                    if Elem[0] != El:
274                        S.append(Elem)
275                self.Elems = S
276                self.CalcFPPS()
277                if not self.Elems:
278                    self.Delete.Enable(False)
279                self.SetWaveEnergy(self.Wave)
280       
281    def OnKALPHACrkaMenu(self, event):
282        self.SetWaveEnergy(2.28962)
283
284    def OnKALPHAMnkaMenu(self, event):
285        self.SetWaveEnergy(2.10174)
286
287    def OnKALPHAFekaMenu(self, event):
288        self.SetWaveEnergy(1.93597)
289
290    def OnKALPHACokaMenu(self, event):
291        self.SetWaveEnergy(1.78896)
292
293    def OnKALPHANikaMenu(self, event):
294        self.SetWaveEnergy(1.65784)
295
296    def OnKALPHACukaMenu(self, event):
297        self.SetWaveEnergy(1.54052)
298
299    def OnKALPHAZnkaMenu(self, event):
300        self.SetWaveEnergy(1.43510)
301
302    def OnKALPHAMokaMenu(self, event):
303        self.SetWaveEnergy(0.70926)
304
305    def OnKALPHAAgkaMenu(self, event):
306        self.SetWaveEnergy(0.55936)
307       
308    def OnSpinText1(self, event):
309        self.SetWaveEnergy(float(self.SpinText1.GetValue()))
310       
311    def OnSpinText2(self, event):
312        self.SetWaveEnergy(self.Kev/(float(self.SpinText2.GetValue())))
313       
314    def OnSpinButton(self, event):
315        if self.ifWave:
316            Wave = float(self.SpinButton.GetValue())/10000.
317        else:
318            Wave = self.Kev/(float(self.SpinButton.GetValue())/10000.)
319        self.SetWaveEnergy(Wave)
320
321    def OnSlider1(self, event):
322        if self.ifWave:
323            Wave = float(self.slider1.GetValue())/1000.
324        else:
325            Wave = self.Kev/(float(self.slider1.GetValue())/1000.)
326        self.SetWaveEnergy(Wave)
327       
328    def OnKeyPress(self,event):
329        if event.key == 'g':
330            mpl.rcParams['axes.grid'] = not mpl.rcParams['axes.grid']
331            self.SetWaveEnergy(self.Wave)           
332
333    def UpDateFPlot(self,Wave,rePlot=True):
334        """Plot f' & f" vs wavelength 0.05-3.0A"""
335        "generate a set of form factor curves & plot them vs sin-theta/lambda or q or 2-theta"
336        axylim = []
337        bxylim = []
338        try:
339            if rePlot:
340                asb,bsb = self.Page.get_children()[1:]
341                axylim = asb.get_xlim(),asb.get_ylim()
342                bxylim = bsb.get_xlim(),bsb.get_ylim()
343            newPlot = False
344        except:
345            new,plotNum,self.Page,self.fplot,lim = self.parent.G2plotNB.FindPlotTab('Fprime','mpl')
346            self.Page.canvas.mpl_connect('pick_event', self.OnPick)
347            self.Page.canvas.mpl_connect('button_release_event', self.OnRelease)
348            self.Page.canvas.mpl_connect('motion_notify_event', self.OnMotion)
349            self.Page.canvas.mpl_connect('key_press_event', self.OnKeyPress)
350            newPlot = True
351        self.Page.Choice = (' key press','g: toggle grid',)
352        self.Page.keyPress = self.OnKeyPress   
353        self.fplot.set_visible(False)
354        ax = self.Page.figure.add_subplot(211)
355        ax.clear()
356        ax.set_title('Resonant Scattering Factors',x=0,ha='left')
357        ax.set_ylabel("f ',"+' f ", e-',fontsize=14)
358        Ymin = 0.0
359        Ymax = 0.0
360        colors=['r','b','g','c','m','k']
361        if self.FPPS: 
362            for i,Fpps in enumerate(self.FPPS):
363                Color = colors[i%6]
364                Ymin = min(Ymin,min(Fpps[2]),min(Fpps[3]))
365                Ymax = max(Ymax,max(Fpps[2]),max(Fpps[3]))
366                fppsP1 = np.array(Fpps[1])
367                fppsP2 = np.array(Fpps[2])
368                fppsP3 = np.array(Fpps[3])
369                ax.plot(fppsP1,fppsP2,Color,label=Fpps[0]+" f '")
370                ax.plot(fppsP1,fppsP3,Color,label=Fpps[0]+' f "')
371        if self.ifWave: 
372            ax.set_xlabel(r'$\mathsf{\lambda, \AA}$',fontsize=14)
373            ax.axvline(x=Wave,picker=3,color='black')
374        else:
375            ax.set_xlabel(r'$\mathsf{E, keV}$',fontsize=14)
376            ax.set_xscale('log')
377            ax.axvline(x=self.Kev/Wave,picker=3,color='black')
378        ax.set_ylim(Ymin,Ymax)
379        if self.FPPS:
380            ax.legend(loc='best')
381        bx = self.Page.figure.add_subplot(212)
382        self.Page.figure.subplots_adjust(hspace=0.25)
383        bx.clear()
384        if self.ifWave:
385            bx.set_title('%s%s%6.4f%s'%('Form factors (',r'$\lambda=$',self.Wave,r'$\AA)$'),x=0,ha='left')
386        else:
387            bx.set_title('%s%6.2f%s'%('Form factors  (E =',self.Energy,'keV)'),x=0,ha='left')
388        if self.FFxaxis == 'S':
389            bx.set_xlabel(r'$\mathsf{sin(\theta)/\lambda}$',fontsize=14)
390        elif self.FFxaxis == 'T':
391            bx.set_xlabel(r'$\mathsf{2\theta}$',fontsize=14)
392        else:
393            bx.set_xlabel(r'$Q, \AA$',fontsize=14)
394        bx.set_ylabel("f+f ', e-",fontsize=14)
395        E = self.Energy
396        DE = E*self.Eres                         #smear by defined source resolution
397        StlMax = min(2.0,math.sin(80.0*math.pi/180.)/Wave)
398        Stl = np.arange(0.,StlMax,.01)
399        Ymax = 0.0
400        for i,Elem in enumerate(self.Elems):
401            Els = Elem[0]
402            Els = Els = Els.ljust(2).lower().capitalize()
403            Ymax = max(Ymax,Elem[1])
404            res1 = G2elem.FPcalc(Elem[3],E+DE)
405            res2 = G2elem.FPcalc(Elem[3],E-DE)
406            res = (res1[0]+res2[0])/2.0
407            if Elem[1] > 78 and self.Energy > self.Kev/0.16: res = 0.0
408            if Elem[1] > 94 and self.Energy < self.Kev/2.67: res = 0.0
409            Els = Elem[0]
410            Els = Els.ljust(2).lower().capitalize()
411            X = []
412            ff = []
413            ffo = []
414            for S in Stl: 
415                ff.append(G2elem.ScatFac(Elem[2],S)+res)
416                ffo.append(G2elem.ScatFac(Elem[2],S))
417                if self.FFxaxis == 'S':
418                    X.append(S)
419                elif self.FFxaxis == 'T':
420                    X.append(360.0*math.asin(S*self.Wave)/math.pi)
421                else:
422                    X.append(4.0*S*math.pi)
423            Color = colors[i%6]
424            Xp = np.array(X)
425            ffop = np.array(ffo)
426            ffp = np.array(ff)
427            bx.plot(Xp,ffop,Color+'--',label=Els+" f")
428            bx.plot(Xp,ffp,Color,label=Els+" f+f'")
429        if self.Elems:
430            bx.legend(loc='best')
431        bx.set_ylim(0.0,Ymax+1.0)
432       
433        if newPlot:
434            newPlot = False
435            self.Page.canvas.draw()
436        else:
437            if rePlot:
438                tb = self.Page.canvas.toolbar
439                tb.push_current()
440                ax.set_xlim(axylim[0])
441                ax.set_ylim(axylim[1])
442                axylim = []
443                tb.push_current()
444                bx.set_xlim(bxylim[0])
445                bx.set_ylim(bxylim[1])
446                bxylim = []
447                tb.push_current()
448            self.Page.canvas.draw()
449       
450    def OnPick(self, event):
451        self.linePicked = event.artist
452       
453    def OnMotion(self,event):
454        if self.linePicked:
455            xpos = event.xdata
456            if xpos:
457                if self.ifWave:
458                    Wave = xpos
459                else:
460                    Wave = self.Kev/xpos               
461                self.SetWaveEnergy(Wave)
462               
463    def OnRelease(self, event):
464        if self.linePicked is None: return
465        self.linePicked = None
466        xpos = event.xdata
467        if xpos:
468            if self.ifWave:
469                Wave = xpos
470            else:
471                Wave = self.Kev/xpos               
472            self.SetWaveEnergy(Wave)
473
474    def SetWaveEnergy(self,Wave):
475        self.Wave = Wave
476        self.Energy = self.Kev/self.Wave
477        self.Energy = round(self.Energy,4)
478        E = self.Energy
479        DE = E*self.Eres                         #smear by defined source resolution
480        self.SpinText1.SetValue("%6.4f" % (self.Wave))
481        self.SpinText2.SetValue("%7.4f" % (self.Energy))
482        self.SpinText1.Update()
483        self.SpinText2.Update()
484        if self.ifWave:
485            self.slider1.SetValue(int(1000.*self.Wave))
486            self.SpinButton.SetValue(int(10000.*self.Wave))
487        else:
488            self.slider1.SetValue(int(1000.*self.Energy))
489            self.SpinButton.SetValue(int(10000.*self.Energy))
490        Text = ''
491        for Elem in self.Elems:
492            r1 = G2elem.FPcalc(Elem[3],E+DE)
493            r2 = G2elem.FPcalc(Elem[3],E-DE)
494            Els = Elem[0]
495            Els = Els.ljust(2).lower().capitalize()
496            if Elem[1] > 78 and self.Energy+DE > self.Kev/0.16:
497                Text += "%s\t%s%6s\t%s%6.3f  \t%s%10.2f %s\n" %    (
498                    'Element= '+str(Els)," f'=",'not valid',
499                    ' f"=',(r1[1]+r2[1])/2.0,' '+Gkmu+'=',(r1[2]+r2[2])/2.0,'barns/atom')
500            elif Elem[1] > 94 and self.Energy-DE < self.Kev/2.67:
501                Text += "%s\t%s%6s\t%s%6s\t%s%10s%s\n" %    (
502                    'Element= '+str(Els)," f'=",'not valid',
503                    ' f"=','not valid',' '+Gkmu+'=','not valid')
504            else:
505                Text += "%s\t%s%6.3f   \t%s%6.3f  \t%s%10.2f %s\n" %    (
506                    'Element= '+str(Els)," f'=",(r1[0]+r2[0])/2.0,
507                    ' f"=',(r1[1]+r2[1])/2.0,' '+Gkmu+'=',(r1[2]+r2[2])/2.0,'barns/atom')
508        self.Results.SetValue(Text)
509        self.Results.Update()
510        self.UpDateFPlot(Wave)
511
512    def CalcFPPS(self):
513        """generate set of f' & f" curves for selected elements
514           does constant delta-lambda/lambda steps over defined range
515        """
516        FPPS = []
517        if self.Elems:
518            wx.BeginBusyCursor()
519            try:
520                for Elem in self.Elems:
521                    Els = Elem[0]
522                    Els = Els = Els.ljust(2).lower().capitalize()
523                    Wmin = self.Wmin
524                    Wmax = self.Wmax
525                    Z = Elem[1]
526                    if Z > 78: Wmin = 0.16        #heavy element high energy failure of Cromer-Liberman
527                    if Z > 94: Wmax = 2.67        #heavy element low energy failure of Cromer-Liberman
528                    lWmin = math.log(Wmin)
529                    N = int(round(math.log(Wmax/Wmin)/self.Wres))    #number of constant delta-lam/lam steps
530                    I = range(N+1)
531                    Ws = []
532                    for i in I: Ws.append(math.exp(i*self.Wres+lWmin))
533                    fps = []
534                    fpps = []
535                    Es = []
536                    for W in Ws:
537                        E = self.Kev/W
538                        DE = E*self.Eres                         #smear by defined source resolution
539                        res1 = G2elem.FPcalc(Elem[3],E+DE)
540                        res2 = G2elem.FPcalc(Elem[3],E-DE)
541                        fps.append((res1[0]+res2[0])/2.0)
542                        fpps.append((res1[1]+res2[1])/2.0)
543                        Es.append(E)
544                    if self.ifWave:
545                        Fpps = (Els,Ws,fps,fpps)
546                    else:
547                        Fpps = (Els,Es,fps,fpps)
548                    FPPS.append(Fpps)
549            finally:
550                wx.EndBusyCursor()
551        self.FPPS = FPPS
552
553    def OnChoice1(self, event):
554        if event.GetString() == "Wavelength":
555            self.ifWave = True
556            self.NewFPPlot = True
557            self.Wave = round(self.Wave,4)
558            self.slider1.SetRange(int(1000.*self.Wmin),int(1000.*self.Wmax))
559            self.slider1.SetValue(int(1000.*self.Wave))
560            self.SpinButton.SetRange(int(10000.*self.Wmin),int(10000.*self.Wmax))
561            self.SpinButton.SetValue(int(10000.*self.Wave))
562            self.SpinText1.SetValue("%6.4f" % (self.Wave))
563            self.SpinText2.SetValue("%7.4f" % (self.Energy))
564        else:
565            self.ifWave = False
566            self.NewFPPlot = True
567            Emin = self.Kev/self.Wmax
568            Emax = self.Kev/self.Wmin
569            self.Energy = round(self.Energy,4)
570            self.slider1.SetRange(int(1000.*Emin),int(1000.*Emax))
571            self.slider1.SetValue(int(1000.*self.Energy))
572            self.SpinButton.SetRange(int(10000.*Emin),int(10000.*Emax))
573            self.SpinButton.SetValue(int(10000.*self.Energy))
574            self.SpinText1.SetValue("%6.4f" % (self.Wave))
575            self.SpinText2.SetValue("%7.4f" % (self.Energy))
576        self.CalcFPPS()
577        self.UpDateFPlot(self.Wave,rePlot=False)
578
579    def OnABOUTItems0Menu(self, event):
580        ''' '''
581        try:
582            import wx.adv as wxadv  # AboutBox moved here in Phoenix
583        except:
584            wxadv = wx
585        info = wxadv.AboutDialogInfo()
586        info.Name = 'pyFprime'
587        info.Copyright = '''
588Robert B. Von Dreele, 2008(C)
589Argonne National Laboratory
590This product includes software developed
591by the UChicago Argonne, LLC, as
592Operator of Argonne National Laboratory.        '''
593        info.Description = '''
594For calculating real and resonant X-ray scattering factors to 250keV;       
595based on Fortran program of Cromer & Liberman corrected for
596Kissel & Pratt energy term; Jensen term not included
597        '''
598        wxadv.AboutBox(info)
Note: See TracBrowser for help on using the repository browser.