source: trunk/GSASIIplot.py @ 50

Last change on this file since 50 was 50, checked in by vondreel, 13 years ago

fix graphics zoom, redraw, home issues
now OK for powder, single crystal, image & transformed image plots

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