source: trunk/GSASIIplot.py @ 49

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

resolved zoom issues with peak picking, etc.
further steps for image integration

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