source: trunk/GSASIIplot.py @ 85

Last change on this file since 85 was 85, checked in by vondreel, 12 years ago

threshold masks operational
add index peak list load/reload menu & remove delete key method
plotting of threshold masks
remove "U" in image open command; implement reading of MAR CCD tif images

File size: 39.0 KB
Line 
1import math
2import time
3import copy
4import numpy as np
5import wx
6import wx.aui
7import matplotlib as mpl
8import GSASIIpath
9import GSASIIgrid as G2gd
10import GSASIIimage as G2img
11import GSASIIIO as G2IO
12import GSASIIpwdGUI as G2pdG
13from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as Canvas
14from matplotlib.backends.backend_wxagg import NavigationToolbar2Wx as Toolbar
15
16# useful degree trig functions
17sind = lambda x: math.sin(x*math.pi/180.)
18cosd = lambda x: math.cos(x*math.pi/180.)
19tand = lambda x: math.tan(x*math.pi/180.)
20asind = lambda x: 180.*math.asin(x)/math.pi
21acosd = lambda x: 180.*math.acos(x)/math.pi
22atan2d = lambda x,y: 180.*math.atan2(y,x)/math.pi
23atand = lambda x: 180.*math.atan(x)/math.pi
24   
25class G2Plot(wx.Panel):
26   
27    def __init__(self,parent,id=-1,dpi=None,**kwargs):
28        wx.Panel.__init__(self,parent,id=id,**kwargs)
29        self.figure = mpl.figure.Figure(dpi=dpi,figsize=(5,7))
30        self.canvas = Canvas(self,-1,self.figure)
31        self.toolbar = Toolbar(self.canvas)
32
33        self.toolbar.Realize()
34       
35        sizer=wx.BoxSizer(wx.VERTICAL)
36        sizer.Add(self.canvas,1,wx.EXPAND)
37        sizer.Add(self.toolbar,0,wx.LEFT|wx.EXPAND)
38        self.SetSizer(sizer)
39               
40class G2PlotNoteBook(wx.Panel):
41    def __init__(self,parent,id=-1):
42        wx.Panel.__init__(self,parent,id=id)
43        #so one can't delete a plot page!!
44        self.nb = wx.aui.AuiNotebook(self, \
45            style=wx.aui.AUI_NB_DEFAULT_STYLE ^ wx.aui.AUI_NB_CLOSE_ON_ACTIVE_TAB)
46        sizer = wx.BoxSizer()
47        sizer.Add(self.nb,1,wx.EXPAND)
48        self.SetSizer(sizer)
49        self.status = parent.CreateStatusBar()
50        self.status.SetFieldsCount(2)
51        self.status.SetStatusWidths([-1,120])
52        self.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CHANGED, self.OnPageChanged)
53       
54        self.plotList = []
55           
56    def add(self,name=""):
57        page = G2Plot(self.nb)
58        self.nb.AddPage(page,name)
59       
60        self.plotList.append(name)
61       
62        return page.figure
63       
64    def OnPageChanged(self,event):
65        self.status.DestroyChildren()                           #get rid of special stuff on status bar
66       
67def PlotSngl(self,newPlot=False):
68    from matplotlib.patches import Circle
69
70    def OnSCMotion(event):
71        xpos = event.xdata
72        if xpos:
73            xpos = round(xpos)                                        #avoid out of frame mouse position
74            ypos = round(event.ydata)
75            zpos = Data['Layer']
76            if '100' in Data['Zone']:
77                HKLtxt = '(%3d,%3d,%3d)'%(zpos,xpos,ypos)
78            elif '010' in Data['Zone']:
79                HKLtxt = '(%3d,%3d,%3d)'%(xpos,zpos,ypos)
80            elif '001' in Data['Zone']:
81                HKLtxt = '(%3d,%3d,%3d)'%(xpos,ypos,zpos)
82            Page.canvas.SetToolTipString(HKLtxt)
83            self.G2plotNB.status.SetFields(['HKL = '+HKLtxt,''])
84               
85    def OnSCPick(event):
86        zpos = Data['Layer']
87        pos = event.artist.center
88        if '100' in Data['Zone']:
89            Page.canvas.SetToolTipString('(picked:(%3d,%3d,%3d))'%(zpos,pos[0],pos[1]))
90            hkl = [zpos,pos[0],pos[1]]
91        elif '010' in Data['Zone']:
92            Page.canvas.SetToolTipString('(picked:(%3d,%3d,%3d))'%(pos[0],zpos,pos[1]))
93            hkl = [pos[0],zpos,pos[1]]
94        elif '001' in Data['Zone']:
95            Page.canvas.SetToolTipString('(picked:(%3d,%3d,%3d))'%(pos[0],pos[1],zpos))
96            hkl = [pos[0],pos[1],zpos]
97        h,k,l = hkl
98        i = HKL.all(hkl)
99        print i
100        HKLtxt = '(%3d,%3d,%3d %10.2f %6.3f %10.2f)'%(h,k,l,Fosq,sig,Fcsq)
101        self.G2plotNB.status.SetFields(['HKL, Fosq, sig, Fcsq = '+HKLtxt,''])
102                         
103       
104    def OnSCKeyPress(event):
105        print event.key
106
107    try:
108        plotNum = self.G2plotNB.plotList.index('Structure Factors')
109        Page = self.G2plotNB.nb.GetPage(plotNum)
110        if not newPlot:
111            Plot = Page.figure.gca()          #get previous powder plot & get limits
112            xylim = Plot.get_xlim(),Plot.get_ylim()
113        Page.figure.clf()
114        Plot = Page.figure.gca()          #get a fresh plot after clf()
115    except ValueError,error:
116        Plot = self.G2plotNB.add('Structure Factors').gca()
117        plotNum = self.G2plotNB.plotList.index('Structure Factors')
118        Page = self.G2plotNB.nb.GetPage(plotNum)
119        Page.canvas.mpl_connect('key_press_event', OnSCKeyPress)
120        Page.canvas.mpl_connect('pick_event', OnSCPick)
121        Page.canvas.mpl_connect('motion_notify_event', OnSCMotion)
122    Page.SetFocus()
123   
124    Plot.set_aspect(aspect='equal')
125    HKLref = self.PatternTree.GetItemPyData(self.Sngl)
126    Data = self.PatternTree.GetItemPyData( \
127        G2gd.GetPatternTreeItemId(self,self.Sngl, 'HKL Plot Controls'))
128    Type = Data['Type']           
129    scale = Data['Scale']
130    HKLmax = Data['HKLmax']
131    HKLmin = Data['HKLmin']
132    FosqMax = Data['FoMax']
133    FoMax = math.sqrt(FosqMax)
134    ifFc = Data['ifFc']
135    xlabel = ['k, h=','h, k=','h, l=']
136    ylabel = ['l','l','k']
137    zones = ['100','010','001']
138    pzone = [[1,2],[0,2],[0,1]]
139    izone = zones.index(Data['Zone'])
140    Plot.set_title(self.PatternTree.GetItemText(self.Sngl)[5:])
141    HKL = []
142    for H,Fosq,sig,Fcsq,x,x,x in HKLref:
143        HKL.append(H)
144        if H[izone] == Data['Layer']:
145            B = 0
146            if Type == 'Fosq':
147                A = scale*Fosq/FosqMax
148                B = scale*Fcsq/FosqMax
149                C = abs(A-B)
150            elif Type == 'Fo':
151                A = scale*math.sqrt(max(0,Fosq))/FoMax
152                B = scale*math.sqrt(max(0,Fcsq))/FoMax
153                C = abs(A-B)
154            elif Type == '|DFsq|/sig':
155                A = abs(Fosq-Fcsq)/(scale*sig)
156            elif Type == '|DFsq|>sig':
157                A = abs(Fosq-Fcsq)/(scale*sig)
158                if A < 1.0: A = 0                   
159            elif Type == '|DFsq|>3sig':
160                A = abs(Fosq-Fcsq)/(scale*sig)
161                if A < 3.0: A = 0                   
162            xy = (H[pzone[izone][0]],H[pzone[izone][1]])
163            if A > 0.0:
164                Plot.add_artist(Circle(xy,radius=A,ec='g',fc='w',picker=3))
165            if B:
166                Plot.add_artist(Circle(xy,radius=B,ec='b',fc='w'))
167                radius = C
168                if radius > 0:
169                    if A > B:
170                        Plot.add_artist(Circle(xy,radius=radius,ec='r',fc='r'))
171                    else:                   
172                        Plot.add_artist(Circle(xy,radius=radius,ec='g',fc='g'))
173    HKL = np.array(HKL)
174    Plot.set_xlabel(xlabel[izone]+str(Data['Layer']),fontsize=12)
175    Plot.set_ylabel(ylabel[izone],fontsize=12)
176    Plot.set_xlim((HKLmin[pzone[izone][0]],HKLmax[pzone[izone][0]]))
177    Plot.set_ylim((HKLmin[pzone[izone][1]],HKLmax[pzone[izone][1]]))
178    if not newPlot:
179        Page.toolbar.push_current()
180        Plot.set_xlim(xylim[0])
181        Plot.set_ylim(xylim[1])
182        xylim = []
183        Page.toolbar.push_current()
184        Page.toolbar.draw()
185    else:
186        Page.canvas.draw()
187       
188def PlotPatterns(self,newPlot=False):
189   
190    def OnPick(event):
191        if self.itemPicked is not None: return
192        PatternId = self.PatternId
193        PickId = self.PickId
194        pick = event.artist
195        mouse = event.mouseevent
196        xpos = pick.get_xdata()
197        ypos = pick.get_ydata()
198        ind = event.ind
199        view = Page.toolbar._views.forward()
200        if view and 'line2' in str(pick):           #apply offset only for picked powder pattern points
201            ind += np.searchsorted(xye[0],view[0][0])
202        xy = zip(xpos[ind],ypos[ind])[0]
203        if self.PatternTree.GetItemText(PickId) == 'Peak List':
204            if ind.all() != [0]:                                    #picked a data point
205                inst = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,PatternId, 'Instrument Parameters'))
206                if len(inst[1]) == 11:
207                    ins = inst[1][4:10]
208                else:
209                    ins = inst[1][6:12]   
210                sig = ins[0]*tand(xy[0]/2.0)**2+ins[1]*tand(xy[0]/2.0)+ins[2]
211                gam = ins[3]/cosd(xy[0]/2.0)+ins[4]*tand(xy[0]/2.0)           
212                data = self.PatternTree.GetItemPyData(self.PickId)
213                XY = [xy[0],0, xy[1],1, sig,0, gam,0]       #default refine intensity 1st   
214                data.append(XY)
215                G2pdG.UpdatePeakGrid(self,data)
216                PlotPatterns(self)
217            else:                                                   #picked a peak list line
218                self.itemPicked = pick
219        elif self.PatternTree.GetItemText(PickId) == 'Limits':
220            if ind.all() != [0]:                                    #picked a data point
221                LimitId = G2gd.GetPatternTreeItemId(self,PatternId, 'Limits')
222                data = self.PatternTree.GetItemPyData(LimitId)
223                if mouse.button==1:
224                    data[1][0] = min(xy[0],data[1][1])
225                if mouse.button==3:
226                    data[1][1] = max(xy[0],data[1][0])
227                self.PatternTree.SetItemPyData(LimitId,data)
228                G2pdG.UpdateLimitsGrid(self,data)
229                PlotPatterns(self)
230            else:                                                   #picked a limit line
231                self.itemPicked = pick               
232       
233    def OnPlotKeyPress(event):
234        if event.key == 'w':
235            if self.Weight:
236                self.Weight = False
237            else:
238                self.Weight = True
239            print 'plot weighting:',self.Weight
240        elif event.key == 'u' and self.Offset < 100.:
241            self.Offset += 1.
242        elif event.key == 'd' and self.Offset > 0.:
243            self.Offset -= 1.
244        elif event.key == 'c':
245            if self.Contour:
246                self.Contour = False
247            else:
248                self.Contour = True
249        elif event.key == 's':
250            if self.SinglePlot:
251                self.SinglePlot = False
252            else:
253                self.SinglePlot = True
254           
255        PlotPatterns(self)
256       
257    def OnKeyBox(event):
258        if self.G2plotNB.nb.GetSelection() == self.G2plotNB.plotList.index('Powder Patterns'):
259            event.key = cb.GetValue()[0]
260            cb.SetValue(' key press')
261            OnPlotKeyPress(event)
262                       
263    def OnMotion(event):
264        xpos = event.xdata
265        if xpos:                                        #avoid out of frame mouse position
266            ypos = event.ydata
267            Page.canvas.SetCursor(wx.CROSS_CURSOR)
268            try:
269                wave = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self, \
270                    self.PatternId, 'Instrument Parameters'))[0][1]
271                dsp = 0.0
272                if abs(xpos) > 0.:                  #avoid possible singularity at beam center
273                    dsp = wave/(2.*sind(abs(xpos)/2.0))
274                self.G2plotNB.status.SetStatusText('2-theta =%9.3f d =%9.5f Intensity =%9.1f'%(xpos,dsp,ypos),0)
275                if self.itemPicked:
276                    Page.canvas.SetToolTipString('%9.3f'%(xpos))
277            except TypeError:
278                self.G2plotNB.status.SetStatusText('Select PWDR powder pattern first',0)
279                                   
280    def OnRelease(event):
281        if self.itemPicked is None: return
282        xpos = event.xdata
283        if xpos:                                        #avoid out of frame mouse position
284            lines = []
285            for line in self.Lines: lines.append(line.get_xdata()[0])
286            lineNo = lines.index(self.itemPicked.get_xdata()[0])
287            if  lineNo in [0,1]:
288                LimitId = G2gd.GetPatternTreeItemId(self,self.PatternId, 'Limits')
289                data = self.PatternTree.GetItemPyData(LimitId)
290#                print 'limits',xpos
291                data[1][lineNo] = xpos
292                self.PatternTree.SetItemPyData(LimitId,data)
293                if self.PatternTree.GetItemText(self.PickId) == 'Limits':
294                    G2pdG.UpdateLimitsGrid(self,data)
295            else:
296                PeakId = G2gd.GetPatternTreeItemId(self,self.PatternId, 'Peak List')
297                data = self.PatternTree.GetItemPyData(PeakId)
298#                print 'peaks',xpos
299                data[lineNo-2][0] = xpos
300                self.PatternTree.SetItemPyData(PeakId,data)
301                G2pdG.UpdatePeakGrid(self,data)
302        PlotPatterns(self)
303        self.itemPicked = None   
304
305    xylim = []
306    try:
307        plotNum = self.G2plotNB.plotList.index('Powder Patterns')
308        Page = self.G2plotNB.nb.GetPage(plotNum)
309        if not newPlot:
310            Plot = Page.figure.gca()          #get previous powder plot & get limits
311            xylim = Plot.get_xlim(),Plot.get_ylim()
312        Page.figure.clf()
313        Plot = Page.figure.gca()          #get a fresh plot after clf()
314    except ValueError,error:
315        newPlot = True
316        Plot = self.G2plotNB.add('Powder Patterns').gca()
317        plotNum = self.G2plotNB.plotList.index('Powder Patterns')
318        Page = self.G2plotNB.nb.GetPage(plotNum)
319        Page.canvas.mpl_connect('key_press_event', OnPlotKeyPress)
320        Page.canvas.mpl_connect('motion_notify_event', OnMotion)
321        Page.canvas.mpl_connect('pick_event', OnPick)
322        Page.canvas.mpl_connect('button_release_event', OnRelease)
323    Page.SetFocus()
324    cb = wx.ComboBox(self.G2plotNB.status,style=wx.CB_DROPDOWN|wx.CB_READONLY,
325        choices=(' key press','d: offset down','u: offset up','c: toggle contour','s: toggle single plot'))
326    cb.Bind(wx.EVT_COMBOBOX, OnKeyBox)
327    rect = self.G2plotNB.status.GetFieldRect(1)
328    cb.SetPosition((rect.x,rect.y))
329    cb.SetValue(' key press')
330   
331    PickId = self.PickId
332    PatternId = self.PatternId
333    colors=['b','g','r','c','m','k']
334    Lines = []
335    if self.SinglePlot:
336        Pattern = self.PatternTree.GetItemPyData(self.PatternId)
337        Pattern.append(self.PatternTree.GetItemText(self.PatternId))
338        PlotList = [Pattern,]
339    else:       
340        PlotList = []
341        item, cookie = self.PatternTree.GetFirstChild(self.root)
342        while item:
343            if 'PWDR' in self.PatternTree.GetItemText(item):
344                Pattern = self.PatternTree.GetItemPyData(item)
345                Pattern.append(self.PatternTree.GetItemText(item))
346                PlotList.append(Pattern)
347            item, cookie = self.PatternTree.GetNextChild(self.root, cookie)               
348    Ymax = 1.0
349    for Pattern in PlotList:
350        xye = Pattern[1]
351        Ymax = max(Ymax,max(xye[1]))
352    offset = self.Offset*Ymax/100.0
353    Plot.set_title('Powder Patterns')
354    Plot.set_xlabel(r'$\mathsf{2\theta}$',fontsize=14)
355    Plot.set_ylabel('Intensity',fontsize=12)
356    if self.Contour:
357        ContourZ = []
358        ContourY = []
359        Nseq = 0
360    for N,Pattern in enumerate(PlotList):
361        ifpicked = False
362        LimitId = 0
363        xye = Pattern[1]
364        if PickId:
365            ifpicked = Pattern[2] == self.PatternTree.GetItemText(PatternId)
366            LimitId = G2gd.GetPatternTreeItemId(self,PatternId, 'Limits')
367        X = xye[0]
368        Y = xye[1]+offset*N
369        if LimitId:
370            limits = self.PatternTree.GetItemPyData(LimitId)
371            Lines.append(Plot.axvline(limits[1][0],color='g',dashes=(5,5),picker=3.))   
372            Lines.append(Plot.axvline(limits[1][1],color='r',dashes=(5,5),picker=3.))                   
373        if self.Contour:
374            ContourY.append(N)
375            ContourZ.append(Y)
376            ContourX = X
377            Nseq += 1
378            Plot.set_ylabel('Data sequence',fontsize=12)
379        else:
380            if ifpicked:
381                Z = xye[3]+offset*N
382                W = xye[4]+offset*N
383                D = xye[5]+offset*N-Ymax*.02
384                if self.Weight:
385                    W2 = np.sqrt(xye[2])
386                    D *= W2-Ymax*.02
387                Plot.plot(X,Y,colors[N%6]+'+',picker=3.,clip_on=False)
388                Plot.plot(X,Z,colors[(N+1)%6],picker=False)
389                Plot.plot(X,W,colors[(N+2)%6],picker=False)
390                Plot.plot(X,D,colors[(N+3)%6],picker=False)
391                Plot.axhline(0.,color=wx.BLACK)
392                Page.canvas.SetToolTipString('')
393                if self.PatternTree.GetItemText(PickId) == 'Peak List':
394                    tip = 'On data point: Pick peak - L or R MB.On line: MB down to move'
395                    Page.canvas.SetToolTipString(tip)
396                    data = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,PatternId, 'Peak List'))
397                    for item in data:
398                        Lines.append(Plot.axvline(item[0],color=colors[N%6],picker=2.))
399                if self.PatternTree.GetItemText(PickId) == 'Limits':
400                    tip = 'On data point: Lower limit - L MB; Upper limit - R MB. On limit: MB down to move'
401                    Page.canvas.SetToolTipString(tip)
402                    data = self.LimitsTable.GetData()
403            else:
404                Plot.plot(X,Y,colors[N%6],picker=False)
405    if PickId and self.PatternTree.GetItemText(PickId) in ['Index Peak List','Unit Cells List']:
406        peaks = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,PatternId, 'Index Peak List'))
407        for peak in peaks:
408            Plot.axvline(peak[0],color='b')
409        for hkl in self.HKL:
410            Plot.axvline(hkl[5],color='r',dashes=(5,5))
411    if self.Contour:
412        acolor = mpl.cm.get_cmap('Paired')
413        Plot.imshow(ContourZ,cmap=acolor,vmin=0,vmax=Ymax,interpolation='nearest', 
414            extent=[ContourX[0],ContourX[-1],ContourY[0],ContourY[-1]],aspect='auto')
415        newPlot = True
416    else:
417        self.Lines = Lines
418    if not newPlot:
419        Page.toolbar.push_current()
420        Plot.set_xlim(xylim[0])
421        Plot.set_ylim(xylim[1])
422        xylim = []
423        Page.toolbar.push_current()
424        Page.toolbar.draw()
425    else:
426        Page.canvas.draw()
427    self.Pwdr = True
428
429def PlotPowderLines(self):
430
431    def OnMotion(event):
432        xpos = event.xdata
433        if xpos:                                        #avoid out of frame mouse position
434            Page.canvas.SetCursor(wx.CROSS_CURSOR)
435            self.G2plotNB.status.SetFields(['2-theta =%9.3f '%(xpos,),''])
436
437    try:
438        plotNum = self.G2plotNB.plotList.index('Powder Lines')
439        Page = self.G2plotNB.nb.GetPage(plotNum)
440        Page.figure.clf()
441        Plot = Page.figure.gca()
442    except ValueError,error:
443        Plot = self.G2plotNB.add('Powder Lines').gca()
444        plotNum = self.G2plotNB.plotList.index('Powder Lines')
445        Page = self.G2plotNB.nb.GetPage(plotNum)
446        Page.canvas.mpl_connect('motion_notify_event', OnMotion)
447       
448    Page.SetFocus()
449    Plot.set_title('Powder Pattern Lines')
450    Plot.set_xlabel(r'$\mathsf{2\theta}$',fontsize=14)
451    PickId = self.PickId
452    PatternId = self.PatternId
453    peaks = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,PatternId, 'Index Peak List'))
454    for peak in peaks:
455        Plot.axvline(peak[0],color='b')
456    for hkl in self.HKL:
457        Plot.axvline(hkl[5],color='r',dashes=(5,5))
458    xmin = peaks[0][0]
459    xmax = peaks[-1][0]
460    delt = xmax-xmin
461    xlim = [max(0,xmin-delt/20.),min(180.,xmax+delt/20.)]
462    Plot.set_xlim(xlim)
463    Page.canvas.draw()
464
465def PlotPeakWidths(self):
466    PatternId = self.PatternId
467    limitID = G2gd.GetPatternTreeItemId(self,PatternId, 'Limits')
468    if limitID:
469        limits = self.PatternTree.GetItemPyData(limitID)
470    else:
471        return
472    instParms = self.PatternTree.GetItemPyData( \
473        G2gd.GetPatternTreeItemId(self,PatternId, 'Instrument Parameters'))
474    if instParms[0][0] == 'PXC':
475        lam = instParms[1][1]
476        if len(instParms[1]) == 13:
477            GU,GV,GW,LX,LY = instParms[0][6:11]
478        else:
479            GU,GV,GW,LX,LY = instParms[0][4:9]
480    peakID = G2gd.GetPatternTreeItemId(self,PatternId, 'Peak List')
481    if peakID:
482        peaks = self.PatternTree.GetItemPyData(peakID)
483    else:
484        peaks = []
485   
486    try:
487        plotNum = self.G2plotNB.plotList.index('Peak Widths')
488        Page = self.G2plotNB.nb.GetPage(plotNum)
489        Page.figure.clf()
490        Plot = Page.figure.gca()
491    except ValueError,error:
492        Plot = self.G2plotNB.add('Peak Widths').gca()
493        plotNum = self.G2plotNB.plotList.index('Peak Widths')
494        Page = self.G2plotNB.nb.GetPage(plotNum)
495    Page.SetFocus()
496   
497    Page.canvas.SetToolTipString('')
498    colors=['b','g','r','c','m','k']
499    Xmin,Xmax = limits[1]
500    Xmin = min(0.5,max(Xmin,1))
501    Xmin /= 2
502    Xmax /= 2
503    nPts = 100
504    delt = (Xmax-Xmin)/nPts
505    thetas = []
506    for i in range(nPts):
507        thetas.append(Xmin+i*delt)
508    X = []
509    Y = []
510    Z = []
511    W = []
512    V = []
513    sig = lambda Th,U,V,W: 1.17741*math.sqrt(U*tand(Th)**2+V*tand(Th)+W)*math.pi/18000.
514    gam = lambda Th,X,Y: (X/cosd(Th)+Y*tand(Th))*math.pi/18000.
515    gamFW = lambda s,g: math.exp(math.log(s**5+2.69269*s**4*g+2.42843*s**3*g**2+4.47163*s**2*g**3+0.07842*s*g**4+g**5)/5.)
516    gamFW2 = lambda s,g: math.sqrt(s**2+(0.4654996*g)**2)+.5345004*#Ubaldo Bafile - private communication
517    for theta in thetas:
518        X.append(4.0*math.pi*sind(theta)/lam)              #q
519        s = sig(theta,GU,GV,GW)
520        g = gam(theta,LX,LY)
521        G = gamFW(g,s)
522        H = gamFW2(g,s)
523        Y.append(s/tand(theta))
524        Z.append(g/tand(theta))
525        W.append(G/tand(theta))
526        V.append(H/tand(theta))
527    Plot.set_title('Instrument and sample peak widths')
528    Plot.set_ylabel(r'$\Delta q/q, \Delta d/d$',fontsize=14)
529    Plot.set_xlabel(r'$q, \AA^{-1}$',fontsize=14)
530    Plot.plot(X,Y,color='r',label='Gaussian')
531    Plot.plot(X,Z,color='g',label='Lorentzian')
532    Plot.plot(X,W,color='b',label='G+L')
533    Plot.plot(X,V,color='k',label='G+L2')
534    X = []
535    Y = []
536    Z = []
537    W = []
538    V = []
539    for peak in peaks:
540        X.append(4.0*math.pi*sind(peak[0]/2.0)/lam)
541        s = 1.17741*math.sqrt(peak[4])*math.pi/18000.
542        g = peak[6]*math.pi/18000.
543        G = gamFW(g,s)
544        H = gamFW2(g,s)
545        Y.append(s/tand(peak[0]/2.))
546        Z.append(g/tand(peak[0]/2.))
547        W.append(G/tand(peak[0]/2.))
548        V.append(H/tand(peak[0]/2.))
549    Plot.plot(X,Y,'+',color='r',label='G peak')
550    Plot.plot(X,Z,'+',color='g',label='L peak')
551    Plot.plot(X,W,'+',color='b',label='G+L peak')
552    Plot.plot(X,V,'+',color='k',label='G+L2 peak')
553    Plot.legend(loc='best')
554    Page.canvas.draw()
555           
556def PlotExposedImage(self,newPlot=False):
557    plotNo = self.G2plotNB.nb.GetSelection()
558    if self.G2plotNB.nb.GetPageText(plotNo) == '2D Powder Image':
559        PlotImage(self,newPlot)
560    elif self.G2plotNB.nb.GetPageText(plotNo) == '2D Integration':
561        PlotIntegration(self,newPlot)
562
563def PlotImage(self,newPlot=False):
564    from matplotlib.patches import Ellipse,Arc
565    import numpy.ma as ma
566
567    def OnImMotion(event):
568        Page.canvas.SetToolTipString('')
569        size = len(self.ImageZ)
570        if event.xdata and event.ydata:                 #avoid out of frame errors
571            Data = self.PatternTree.GetItemPyData( \
572                G2gd.GetPatternTreeItemId(self,self.Image, 'Image Controls'))
573            Page.canvas.SetCursor(wx.CROSS_CURSOR)
574            item = self.itemPicked
575            pixelSize = Data['pixelSize']
576            scalex = 1000./pixelSize[0]
577            scaley = 1000./pixelSize[1]                   
578            if item and self.PatternTree.GetItemText(self.PickId) == 'Image Controls':
579                if 'Text' in str(item):
580                    Page.canvas.SetToolTipString('%8.3f %8.3fmm'%(event.xdata,event.ydata))
581                else:
582                    xcent,ycent = Data['center']
583                    xpos = event.xdata-xcent
584                    ypos = event.ydata-ycent
585                    if 'line3' in  str(item) or 'line4' in str(item) and not Data['fullIntegrate']:
586                        ang = int(atan2d(xpos,ypos))
587                        Page.canvas.SetToolTipString('%6d deg'%(ang))
588                    elif 'line1' in  str(item) or 'line2' in str(item):
589                        tth = G2img.GetTth(event.xdata,event.ydata,Data)
590                        Page.canvas.SetToolTipString('%8.3fdeg'%(tth))                           
591            else:
592                xpos = event.xdata
593                ypos = event.ydata
594                xpix = xpos*scalex
595                ypix = ypos*scaley
596                Int = 0
597                if (0 <= xpix <= size) and (0 <= ypix <= size):
598                    Int = self.ImageZ[ypix][xpix]
599#                    Page.canvas.SetToolTipString('%4x'%((ypix*2048+xpix)*2+4096))
600                tth,azm,dsp = G2img.GetTthAzmDsp(xpos,ypos,Data)
601                Q = 2.*math.pi/dsp
602                self.G2plotNB.status.SetFields(\
603                    ['Detector 2-th =%9.2fdeg, dsp =%9.3fA, Q = %6.3fA-1, azm = %7.2fdeg, I = %6d'%(tth,dsp,Q,azm,Int),''])
604
605    def OnImPlotKeyPress(event):
606        if self.PatternTree.GetItemText(self.PickId) == 'Image Controls':
607            Data = self.PatternTree.GetItemPyData(self.PickId)
608            pixelSize = Data['pixelSize']
609            size = len(self.ImageZ)
610            Xpos = event.xdata
611            if not Xpos:            #got point out of frame
612                return
613            Ypos = event.ydata
614            if event.key == 'm':
615                print 'mask = ',Xpos,Ypos
616           
617    def OnImPick(event):
618        if self.PatternTree.GetItemText(self.PickId) != 'Image Controls':
619            return
620        if self.itemPicked is not None: return
621        pick = event.artist
622        self.itemPicked = pick
623       
624    def OnImRelease(event):
625        if self.PatternTree.GetItemText(self.PickId) != 'Image Controls':
626            return
627        Data = self.PatternTree.GetItemPyData(self.PickId)
628        pixelSize = Data['pixelSize']
629        scalex = 1000./pixelSize[0]
630        scaley = 1000./pixelSize[1]
631        if self.itemPicked is None:
632            size = len(self.ImageZ)
633            Xpos = event.xdata
634            if not (Xpos and self.ifGetRing):                   #got point out of frame
635                return
636            Ypos = event.ydata
637            if Ypos and not Page.toolbar._active:         #make sure zoom/pan not selected
638                if event.button == 1:
639                    Xpix = Xpos*scalex
640                    Ypix = Ypos*scaley
641                    xpos,ypos,I,J = G2img.ImageLocalMax(self.ImageZ,20,Xpix,Ypix)
642                    if I and J:
643                        xpos += .5                              #shift to pixel center
644                        ypos += .5
645                        xpos /= scalex                          #convert to mm
646                        ypos /= scaley
647                        Data['ring'].append([xpos,ypos])
648                PlotImage(self)
649            return
650        else:
651            xpos = event.xdata
652            if xpos:                                        #avoid out of frame mouse position
653                ypos = event.ydata
654                if self.ifGetRing:
655                    xypos = [xpos,ypos]
656                    rings = Data['ring']
657                    for ring in rings:
658                        if np.allclose(ring,xypos,.01,0):
659                            rings.remove(ring)                                                                       
660                else:
661                    tth,azm,dsp = G2img.GetTthAzmDsp(xpos,ypos,Data)
662                    if 'Line2D' in str(self.itemPicked):
663                        if 'line1' in str(self.itemPicked):
664                            Data['IOtth'][0] = tth
665                        elif 'line2' in str(self.itemPicked):
666                            Data['IOtth'][1] = tth
667                        elif 'line3' in str(self.itemPicked) and not Data['fullIntegrate']:
668                            Data['LRazimuth'][0] = int(azm)
669                        elif 'line4' in str(self.itemPicked) and not Data['fullIntegrate']:
670                            Data['LRazimuth'][1] = int(azm)
671                           
672                        if Data['LRazimuth'][1] < Data['LRazimuth'][0]:
673                            Data['LRazimuth'][1] += 360
674                        if  Data['IOtth'][0] > Data['IOtth'][1]:
675                            Data['IOtth'][0],Data['IOtth'][1] = Data['IOtth'][1],Data['IOtth'][0]
676                           
677                        self.InnerTth.SetValue("%8.2f" % (Data['IOtth'][0]))
678                        self.OuterTth.SetValue("%8.2f" % (Data['IOtth'][1]))
679                        self.Lazim.SetValue("%6d" % (Data['LRazimuth'][0]))
680                        self.Razim.SetValue("%6d" % (Data['LRazimuth'][1]))
681                    else:
682                        print event.xdata,event.ydata,event.button
683                PlotImage(self)
684            self.itemPicked = None
685           
686    try:
687        plotNum = self.G2plotNB.plotList.index('2D Powder Image')
688        Page = self.G2plotNB.nb.GetPage(plotNum)
689        if not newPlot:
690            Plot = Page.figure.gca()          #get previous powder plot & get limits
691            xylim = Plot.get_xlim(),Plot.get_ylim()
692        Page.figure.clf()
693        Plot = Page.figure.gca()          #get a fresh plot after clf()
694       
695    except ValueError,error:
696        Plot = self.G2plotNB.add('2D Powder Image').gca()
697        plotNum = self.G2plotNB.plotList.index('2D Powder Image')
698        Page = self.G2plotNB.nb.GetPage(plotNum)
699        Page.canvas.mpl_connect('key_press_event', OnImPlotKeyPress)
700        Page.canvas.mpl_connect('motion_notify_event', OnImMotion)
701        Page.canvas.mpl_connect('pick_event', OnImPick)
702        Page.canvas.mpl_connect('button_release_event', OnImRelease)
703    Page.SetFocus()
704    Plot.set_title(self.PatternTree.GetItemText(self.Image)[4:])
705    size,imagefile = self.PatternTree.GetItemPyData(self.Image)
706    if imagefile != self.oldImagefile:
707        self.ImageZ = G2IO.GetImageData(imagefile,imageOnly=True)
708        self.oldImagefile = imagefile
709    Data = self.PatternTree.GetItemPyData(
710        G2gd.GetPatternTreeItemId(self,self.Image, 'Image Controls'))
711    Masks = self.PatternTree.GetItemPyData(
712        G2gd.GetPatternTreeItemId(self,self.Image, 'Masks'))
713    imScale = 1
714    if len(self.ImageZ) > 1024:
715        imScale = len(self.ImageZ)/1024
716    pixelSize = Data['pixelSize']
717    scalex = 1000./pixelSize[0]
718    scaley = 1000./pixelSize[1]
719    xmax = len(self.ImageZ)
720    Xmax = len(self.ImageZ)*pixelSize[0]/1000.
721    xlim = (-0.5,Xmax-.5)
722    ylim = (Xmax-.5,-0.5,)
723    Imin,Imax = Data['range'][1]
724    acolor = mpl.cm.get_cmap(Data['color'])
725    xcent,ycent = Data['center']
726    Plot.set_xlabel('Image x-axis, mm',fontsize=12)
727    Plot.set_ylabel('Image y-axis, mm',fontsize=12)
728    #need "applyMask" routine here
729    Zlim = Masks['Thresholds'][1]
730    MA = ma.masked_greater(ma.masked_less(self.ImageZ,Zlim[0]),Zlim[1])
731    MaskA = ma.getmaskarray(MA)
732    A = G2img.ImageCompress(MA,imScale)
733    AM = G2img.ImageCompress(MaskA,imScale)
734   
735    ImgM = Plot.imshow(AM,aspect='equal',cmap='Reds',
736        interpolation='nearest',vmin=0,vmax=2,extent=[0,Xmax,Xmax,0])
737    Img = Plot.imshow(A,aspect='equal',cmap=acolor,
738        interpolation='nearest',vmin=Imin,vmax=Imax,extent=[0,Xmax,Xmax,0])
739
740    Plot.plot(xcent,ycent,'x')
741    if Data['showLines']:
742        LRAzim = Data['LRazimuth']                  #NB: integers
743        IOtth = Data['IOtth']
744        wave = Data['wavelength']
745        dspI = wave/(2.0*sind(IOtth[0]/2.0))
746        ellI = G2img.GetEllipse(dspI,Data)           #=False if dsp didn't yield an ellipse (ugh! a parabola or a hyperbola)
747        dspO = wave/(2.0*sind(IOtth[1]/2.0))
748        ellO = G2img.GetEllipse(dspO,Data)           #Ditto & more likely for outer ellipse
749        if Data['fullIntegrate']:
750            Azm = np.array(range(0,361))
751        else:
752            Azm = np.array(range(LRAzim[0],LRAzim[1]+1))
753        if ellI:
754            xyI = []
755            for azm in Azm:
756                xyI.append(G2img.GetDetectorXY(dspI,azm,Data))
757            xyI = np.array(xyI)
758            arcxI,arcyI = xyI.T
759            Plot.plot(arcxI,arcyI,picker=3)
760        if ellO:
761            xyO = []
762            for azm in Azm:
763                xyO.append(G2img.GetDetectorXY(dspO,azm,Data))
764            xyO = np.array(xyO)
765            arcxO,arcyO = xyO.T
766            Plot.plot(arcxO,arcyO,picker=3)
767        if ellO and ellI and not Data['fullIntegrate']:
768            Plot.plot([arcxI[0],arcxO[0]],[arcyI[0],arcyO[0]],picker=3)
769            Plot.plot([arcxI[-1],arcxO[-1]],[arcyI[-1],arcyO[-1]],picker=3)
770    for xring,yring in Data['ring']:
771        Plot.plot(xring,yring,'r+',picker=3)
772    if Data['setRings']:
773        rings = np.concatenate((Data['rings']),axis=0)
774        for xring,yring,dsp in rings:
775            Plot.plot(xring,yring,'r+')           
776    for ellipse in Data['ellipses']:
777        cent,phi,[width,height],col = ellipse
778        Plot.add_artist(Ellipse([cent[0],cent[1]],2*width,2*height,phi,ec=col,fc='none'))
779        Plot.text(cent[0],cent[1],'+',color=col,ha='center',va='center')
780    colorBar = Page.figure.colorbar(Img)
781    Plot.set_xlim(xlim)
782    Plot.set_ylim(ylim)
783    if not newPlot:
784        Page.toolbar.push_current()
785        Plot.set_xlim(xylim[0])
786        Plot.set_ylim(xylim[1])
787        xylim = []
788        Page.toolbar.push_current()
789        Page.toolbar.draw()
790    else:
791        Page.canvas.draw()
792       
793def PlotIntegration(self,newPlot=False):
794           
795    def OnMotion(event):
796        Page.canvas.SetToolTipString('')
797        Page.canvas.SetCursor(wx.CROSS_CURSOR)
798        azm = event.ydata
799        tth = event.xdata
800        if azm and tth:
801            self.G2plotNB.status.SetFields(\
802                ['Detector 2-th =%9.3fdeg, azm = %7.2fdeg'%(tth,azm),''])
803                               
804    try:
805        plotNum = self.G2plotNB.plotList.index('2D Integration')
806        Page = self.G2plotNB.nb.GetPage(plotNum)
807        if not newPlot:
808            Plot = Page.figure.gca()          #get previous plot & get limits
809            xylim = Plot.get_xlim(),Plot.get_ylim()
810        Page.figure.clf()
811        Plot = Page.figure.gca()          #get a fresh plot after clf()
812       
813    except ValueError,error:
814        Plot = self.G2plotNB.add('2D Integration').gca()
815        plotNum = self.G2plotNB.plotList.index('2D Integration')
816        Page = self.G2plotNB.nb.GetPage(plotNum)
817        Page.canvas.mpl_connect('motion_notify_event', OnMotion)
818        Page.views = False
819        view = False
820    Page.SetFocus()
821       
822    Data = self.PatternTree.GetItemPyData(
823        G2gd.GetPatternTreeItemId(self,self.Image, 'Image Controls'))
824    image = self.Integrate[0]
825    xsc = self.Integrate[1]
826    ysc = self.Integrate[2]
827    Imin,Imax = Data['range'][1]
828    acolor = mpl.cm.get_cmap(Data['color'])
829    Plot.set_title(self.PatternTree.GetItemText(self.Image)[4:])
830    Plot.set_ylabel('azimuth',fontsize=12)
831    Plot.set_xlabel('2-theta',fontsize=12)
832    Img = Plot.imshow(image,cmap=acolor,vmin=Imin,vmax=Imax,interpolation='nearest', \
833        extent=[ysc[0],ysc[-1],xsc[-1],xsc[0]],aspect='auto')
834    colorBar = Page.figure.colorbar(Img)
835    if Data['setRings']:
836        rings = np.concatenate((Data['rings']),axis=0)
837        for xring,yring,dsp in rings:
838            x,y = G2img.GetTthAzm(xring,yring,Data)
839            Plot.plot(x,y,'r+')
840    if Data['ellipses']:           
841        for ellipse in Data['ellipses']:
842            ring = np.array(G2img.makeIdealRing(ellipse[:3])) #skip color
843            x,y = np.hsplit(ring,2)
844            tth,azm = G2img.GetTthAzm(x,y,Data)
845            Plot.plot(tth,azm,'b,')
846    if not newPlot:
847        Page.toolbar.push_current()
848        Plot.set_xlim(xylim[0])
849        Plot.set_ylim(xylim[1])
850        xylim = []
851        Page.toolbar.push_current()
852        Page.toolbar.draw()
853    else:
854        Page.canvas.draw()
855       
856       
857def PlotTRImage(self,tax,tay,taz,newPlot=False):
858    #a test plot routine - not normally used
859           
860    def OnMotion(event):
861        Page.canvas.SetToolTipString('')
862        Page.canvas.SetCursor(wx.CROSS_CURSOR)
863        azm = event.xdata
864        tth = event.ydata
865        if azm and tth:
866            self.G2plotNB.status.SetFields(\
867                ['Detector 2-th =%9.3fdeg, azm = %7.2fdeg'%(tth,azm),''])
868                               
869    try:
870        plotNum = self.G2plotNB.plotList.index('2D Transformed Powder Image')
871        Page = self.G2plotNB.nb.GetPage(plotNum)
872        if not newPlot:
873            Plot = Page.figure.gca()          #get previous plot & get limits
874            xylim = Plot.get_xlim(),Plot.get_ylim()
875        Page.figure.clf()
876        Plot = Page.figure.gca()          #get a fresh plot after clf()
877       
878    except ValueError,error:
879        Plot = self.G2plotNB.add('2D Transformed Powder Image').gca()
880        plotNum = self.G2plotNB.plotList.index('2D Transformed Powder Image')
881        Page = self.G2plotNB.nb.GetPage(plotNum)
882        Page.canvas.mpl_connect('motion_notify_event', OnMotion)
883        Page.views = False
884        view = False
885    Page.SetFocus()
886       
887    Data = self.PatternTree.GetItemPyData(
888        G2gd.GetPatternTreeItemId(self,self.Image, 'Image Controls'))
889    Imin,Imax = Data['range'][1]
890    step = (Imax-Imin)/5.
891    V = np.arange(Imin,Imax,step)
892    acolor = mpl.cm.get_cmap(Data['color'])
893    Plot.set_title(self.PatternTree.GetItemText(self.Image)[4:])
894    Plot.set_xlabel('azimuth',fontsize=12)
895    Plot.set_ylabel('2-theta',fontsize=12)
896    Plot.contour(tax,tay,taz,V,cmap=acolor)
897    if Data['showLines']:
898        IOtth = Data['IOtth']
899        if Data['fullIntegrate']:
900            LRAzim = [-180,180]
901        else:
902            LRAzim = Data['LRazimuth']                  #NB: integers
903        Plot.plot([LRAzim[0],LRAzim[1]],[IOtth[0],IOtth[0]],picker=True)
904        Plot.plot([LRAzim[0],LRAzim[1]],[IOtth[1],IOtth[1]],picker=True)
905        if not Data['fullIntegrate']:
906            Plot.plot([LRAzim[0],LRAzim[0]],[IOtth[0],IOtth[1]],picker=True)
907            Plot.plot([LRAzim[1],LRAzim[1]],[IOtth[0],IOtth[1]],picker=True)
908    if Data['setRings']:
909        rings = np.concatenate((Data['rings']),axis=0)
910        for xring,yring,dsp in rings:
911            x,y = G2img.GetTthAzm(xring,yring,Data)
912            Plot.plot(y,x,'r+')           
913    if Data['ellipses']:           
914        for ellipse in Data['ellipses']:
915            ring = np.array(G2img.makeIdealRing(ellipse[:3])) #skip color
916            x,y = np.hsplit(ring,2)
917            tth,azm = G2img.GetTthAzm(x,y,Data)
918            Plot.plot(azm,tth,'b,')
919    if not newPlot:
920        Page.toolbar.push_current()
921        Plot.set_xlim(xylim[0])
922        Plot.set_ylim(xylim[1])
923        xylim = []
924        Page.toolbar.push_current()
925        Page.toolbar.draw()
926    else:
927        Page.canvas.draw()
928       
929       
Note: See TracBrowser for help on using the repository browser.