source: trunk/GSASIIplot.py @ 54

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

pick, motion bugs fixed

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