source: trunk/fprime.py @ 3963

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

change pylab to pyplot in fprime & absorb
undo the addition of S301 to the set for 3m1 Laue groups. Did bad things even if the fit was "improved". Can be reinstated if I can work out what went wrong.

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