source: trunk/GSASIIplot.py @ 53

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

finish image integration
problems still with motion, picking pts., etc. on patterns

File size: 37.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,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            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    else:
385        self.Lines = Lines
386    if not newPlot:
387        Page.toolbar.push_current()
388        Plot.set_xlim(xylim[0])
389        Plot.set_ylim(xylim[1])
390        xylim = []
391        Page.toolbar.push_current()
392        Page.toolbar.draw()
393    else:
394        Page.canvas.draw()
395
396   
397    self.Pwdr = True
398
399def PlotPowderLines(self):
400
401    def OnMotion(event):
402        xpos = event.xdata
403        if xpos:                                        #avoid out of frame mouse position
404            Page.canvas.SetCursor(wx.CROSS_CURSOR)
405            self.G2plotNB.status.SetFields(['2-theta =%9.3f '%(xpos,),])
406
407    try:
408        plotNum = self.G2plotNB.plotList.index('Powder Lines')
409        Page = self.G2plotNB.nb.GetPage(plotNum)
410        Page.figure.clf()
411        Plot = Page.figure.gca()
412    except ValueError,error:
413        Plot = self.G2plotNB.add('Powder Lines').gca()
414        plotNum = self.G2plotNB.plotList.index('Powder Lines')
415        Page = self.G2plotNB.nb.GetPage(plotNum)
416        Page.canvas.mpl_connect('motion_notify_event', OnMotion)
417       
418    Page.SetFocus()
419    Plot.set_title('Powder Pattern Lines')
420    Plot.set_xlabel(r'$\mathsf{2\theta}$',fontsize=14)
421    PickId = self.PickId
422    PatternId = self.PatternId
423    peaks = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,PatternId, 'Index Peak List'))
424    for peak in peaks:
425        Plot.axvline(peak[0],color='b')
426    for hkl in self.HKL:
427        Plot.axvline(hkl[5],color='r',dashes=(5,5))
428    xmin = peaks[0][0]
429    xmax = peaks[-1][0]
430    delt = xmax-xmin
431    xlim = [max(0,xmin-delt/20.),min(180.,xmax+delt/20.)]
432    Plot.set_xlim(xlim)
433    Page.canvas.draw()
434
435def PlotPeakWidths(self):
436    PatternId = self.PatternId
437    limitID = G2gd.GetPatternTreeItemId(self,PatternId, 'Limits')
438    if limitID:
439        limits = self.PatternTree.GetItemPyData(limitID)
440    else:
441        return
442    instParms = self.PatternTree.GetItemPyData( \
443        G2gd.GetPatternTreeItemId(self,PatternId, 'Instrument Parameters'))
444    if instParms[0][0] == 'PXC':
445        lam = instParms[1][1]
446        if len(instParms[1]) == 12:
447            GU,GV,GW,LX,LY = instParms[0][6:11]
448        else:
449            GU,GV,GW,LX,LY = instParms[0][4:9]
450    peakID = G2gd.GetPatternTreeItemId(self,PatternId, 'Peak List')
451    if peakID:
452        peaks = self.PatternTree.GetItemPyData(peakID)
453    else:
454        peaks = []
455   
456    try:
457        plotNum = self.G2plotNB.plotList.index('Peak Widths')
458        Page = self.G2plotNB.nb.GetPage(plotNum)
459        Page.figure.clf()
460        Plot = Page.figure.gca()
461    except ValueError,error:
462        Plot = self.G2plotNB.add('Peak Widths').gca()
463        plotNum = self.G2plotNB.plotList.index('Peak Widths')
464        Page = self.G2plotNB.nb.GetPage(plotNum)
465    Page.SetFocus()
466   
467    Page.canvas.SetToolTipString('')
468    colors=['b','g','r','c','m','k']
469    Xmin,Xmax = limits[1]
470    Xmin = min(0.5,max(Xmin,1))
471    Xmin /= 2
472    Xmax /= 2
473    nPts = 100
474    delt = (Xmax-Xmin)/nPts
475    thetas = []
476    for i in range(nPts):
477        thetas.append(Xmin+i*delt)
478    X = []
479    Y = []
480    Z = []
481    W = []
482    sig = lambda Th,U,V,W: 1.17741*math.sqrt(U*tand(Th)**2+V*tand(Th)+W)*math.pi/18000.
483    gam = lambda Th,X,Y: (X/cosd(Th)+Y*tand(Th))*math.pi/18000.
484    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.)
485    for theta in thetas:
486        X.append(4.0*math.pi*sind(theta)/lam)              #q
487        s = sig(theta,GU,GV,GW)
488        g = gam(theta,LX,LY)
489        G = gamFW(g,s)
490        Y.append(s/tand(theta))
491        Z.append(g/tand(theta))
492        W.append(G/tand(theta))
493    Plot.set_title('Instrument and sample peak widths')
494    Plot.set_ylabel(r'$\Delta q/q, \Delta d/d$',fontsize=14)
495    Plot.set_xlabel(r'$q, \AA^{-1}$',fontsize=14)
496    Plot.plot(X,Y,color='r',label='Gaussian')
497    Plot.plot(X,Z,color='g',label='Lorentzian')
498    Plot.plot(X,W,color='b',label='G+L')
499    X = []
500    Y = []
501    Z = []
502    W = []
503    for peak in peaks:
504        X.append(4.0*math.pi*sind(peak[0]/2.0)/lam)
505        s = 1.17741*math.sqrt(peak[4])*math.pi/18000.
506        g = peak[6]*math.pi/18000.
507        G = gamFW(g,s)
508        Y.append(s/tand(peak[0]/2.))
509        Z.append(g/tand(peak[0]/2.))
510        W.append(G/tand(peak[0]/2.))
511    Plot.plot(X,Y,'+',color='r',label='G peak')
512    Plot.plot(X,Z,'+',color='g',label='L peak')
513    Plot.plot(X,W,'+',color='b',label='G+L peak')
514    Plot.legend(loc='best')
515    Page.canvas.draw()
516
517def PlotImage(self,newPlot=False):
518    from matplotlib.patches import Ellipse,Arc
519
520    def OnImMotion(event):
521        Page.canvas.SetToolTipString('')
522        size = len(self.ImageZ)
523        if event.xdata and event.ydata:                 #avoid out of frame errors
524            Data = self.PatternTree.GetItemPyData( \
525                G2gd.GetPatternTreeItemId(self,self.Image, 'Image Controls'))
526            Page.canvas.SetCursor(wx.CROSS_CURSOR)
527            item = self.itemPicked
528            pixelSize = Data['pixelSize']
529            scalex = 1000./pixelSize[0]
530            scaley = 1000./pixelSize[1]                   
531            if item and self.PatternTree.GetItemText(self.PickId) == 'Image Controls':
532                if 'Text' in str(item):
533                    Page.canvas.SetToolTipString('%8.3f %8.3fmm'%(event.xdata,event.ydata))
534                else:
535                    xcent,ycent = Data['center']
536                    xpos = event.xdata-xcent
537                    ypos = event.ydata-ycent
538                    if 'line3' in  str(item) or 'line4' in str(item) and not Data['fullIntegrate']:
539                        ang = int(atan2d(xpos,ypos))
540                        Page.canvas.SetToolTipString('%6d deg'%(ang))
541                    elif 'line1' in  str(item) or 'line2' in str(item):
542                        tth = G2cmp.GetTth(event.xdata,event.ydata,Data)
543                        Page.canvas.SetToolTipString('%8.3fdeg'%(tth))                           
544            else:
545                xpos = event.xdata
546                ypos = event.ydata
547                xpix = xpos*scalex
548                ypix = ypos*scaley
549                if (0 <= xpix <= size) and (0 <= ypix <= size):
550                    Page.canvas.SetToolTipString('%6d'%(self.ImageZ[ypix][xpix]))
551                tth,azm,dsp = G2cmp.GetTthDspAzm(xpos,ypos,Data)
552                Q = 2.*math.pi/dsp
553                self.G2plotNB.status.SetFields(\
554                    ['Detector 2-th =%9.2fdeg, dsp =%9.3fA, Q = %6.3fA-1, azm = %7.2fdeg'%(tth,dsp,Q,azm),])
555
556    def OnImPlotKeyPress(event):
557        if self.PatternTree.GetItemText(self.PickId) == 'Image Controls':
558            Data = self.PatternTree.GetItemPyData(self.PickId)
559            pixelSize = Data['pixelSize']
560            size = len(self.ImageZ)
561            Xpos = event.xdata
562            if not Xpos:            #got point out of frame
563                return
564            Ypos = event.ydata
565            if event.key == 'm':
566                print 'mask = ',Xpos,Ypos
567           
568    def OnImPick(event):
569        if self.PatternTree.GetItemText(self.PickId) != 'Image Controls':
570            return
571        if self.itemPicked is not None: return
572        pick = event.artist
573        self.itemPicked = pick
574       
575    def OnImRelease(event):
576        if self.PatternTree.GetItemText(self.PickId) != 'Image Controls':
577            return
578        Data = self.PatternTree.GetItemPyData(self.PickId)
579        pixelSize = Data['pixelSize']
580        scalex = 1000./pixelSize[0]
581        scaley = 1000./pixelSize[1]
582        if self.itemPicked is None:
583            size = len(self.ImageZ)
584            Xpos = event.xdata
585            if not (Xpos and self.ifGetRing):                   #got point out of frame
586                return
587            Ypos = event.ydata
588            if Ypos and not Page.toolbar._active:         #make sure zoom/pan not selected
589                if event.button == 1:
590                    Xpix = Xpos*scalex
591                    Ypix = Ypos*scaley
592                    xpos,ypos,I,J = G2cmp.ImageLocalMax(self.ImageZ,20,Xpix,Ypix)
593                    if I and J:
594                        xpos /= scalex
595                        ypos /= scaley
596                        Data['ring'].append([xpos,ypos])
597                PlotImage(self)
598            return
599        else:
600            xpos = event.xdata
601            if xpos:                                        #avoid out of frame mouse position
602                ypos = event.ydata
603                if self.ifGetRing:
604                    xypos = [xpos,ypos]
605                    rings = Data['ring']
606                    for ring in rings:
607                        if np.allclose(ring,xypos,.01,0):
608                            rings.remove(ring)                                                                       
609                else:
610                    tth,azm,dsp = G2cmp.GetTthDspAzm(xpos,ypos,Data)
611                    if 'Line2D' in str(self.itemPicked):
612                        if 'line1' in str(self.itemPicked):
613                            Data['IOtth'][0] = tth
614                        elif 'line2' in str(self.itemPicked):
615                            Data['IOtth'][1] = tth
616                        elif 'line3' in str(self.itemPicked) and not Data['fullIntegrate']:
617                            Data['LRazimuth'][0] = int(azm)
618                        elif 'line4' in str(self.itemPicked) and not Data['fullIntegrate']:
619                            Data['LRazimuth'][1] = int(azm)
620                           
621                        if Data['LRazimuth'][1] < Data['LRazimuth'][0]:
622                            Data['LRazimuth'][1] += 360
623                        if  Data['IOtth'][0] > Data['IOtth'][1]:
624                            Data['IOtth'] = G2cmp.SwapXY(Data['IOtth'][0],Data['IOtth'][1])
625                           
626                        self.InnerTth.SetValue("%8.2f" % (Data['IOtth'][0]))
627                        self.OuterTth.SetValue("%8.2f" % (Data['IOtth'][1]))
628                        self.Lazim.SetValue("%6d" % (Data['LRazimuth'][0]))
629                        self.Razim.SetValue("%6d" % (Data['LRazimuth'][1]))
630                    else:
631                        print event.xdata,event.ydata,event.button
632                PlotImage(self)
633            self.itemPicked = None
634           
635    try:
636        plotNum = self.G2plotNB.plotList.index('2D Powder Image')
637        Page = self.G2plotNB.nb.GetPage(plotNum)
638        if not newPlot:
639            Plot = Page.figure.gca()          #get previous powder plot & get limits
640            xylim = Plot.get_xlim(),Plot.get_ylim()
641        Page.figure.clf()
642        Plot = Page.figure.gca()          #get a fresh plot after clf()
643       
644    except ValueError,error:
645        Plot = self.G2plotNB.add('2D Powder Image').gca()
646        plotNum = self.G2plotNB.plotList.index('2D Powder Image')
647        Page = self.G2plotNB.nb.GetPage(plotNum)
648        Page.canvas.mpl_connect('key_press_event', OnImPlotKeyPress)
649        Page.canvas.mpl_connect('motion_notify_event', OnImMotion)
650        Page.canvas.mpl_connect('pick_event', OnImPick)
651        Page.canvas.mpl_connect('button_release_event', OnImRelease)
652    Page.SetFocus()
653       
654    Plot.set_title(self.PatternTree.GetItemText(self.Image)[4:])
655    size,self.ImageZ = self.PatternTree.GetItemPyData(self.Image)
656    Data = self.PatternTree.GetItemPyData( \
657        G2gd.GetPatternTreeItemId(self,self.Image, 'Image Controls'))
658    imScale = 1
659    if len(self.ImageZ) > 1024:
660        imScale = len(self.ImageZ)/1024
661    pixelSize = Data['pixelSize']
662    scalex = 1000./pixelSize[0]
663    scaley = 1000./pixelSize[1]
664    xmax = len(self.ImageZ)
665    Xmax = len(self.ImageZ)*pixelSize[0]/1000.
666    xlim = (-0.5,Xmax-.5)
667    ylim = (Xmax-.5,-0.5,)
668    Imin,Imax = Data['range'][1]
669    acolor = mpl.cm.get_cmap(Data['color'])
670    xcent,ycent = Data['center']
671    Plot.set_xlabel('Image x-axis, mm',fontsize=12)
672    Plot.set_ylabel('Image y-axis, mm',fontsize=12)
673    A = G2cmp.ImageCompress(self.ImageZ,imScale)
674    self.Img = Plot.imshow(A,aspect='equal',cmap=acolor, \
675        interpolation='nearest',vmin=Imin,vmax=Imax,extent=[0,Xmax,Xmax,0])
676
677    Plot.plot(xcent,ycent,'x')
678    if Data['showLines']:
679        LRAzim = Data['LRazimuth']                  #NB: integers
680        IOtth = Data['IOtth']
681        wave = Data['wavelength']
682        dspI = wave/(2.0*sind(IOtth[0]/2.0))
683        ellI = G2cmp.GetEllipse(dspI,Data)           #=False if dsp didn't yield an ellipse (ugh! a parabola or a hyperbola)
684        dspO = wave/(2.0*sind(IOtth[1]/2.0))
685        ellO = G2cmp.GetEllipse(dspO,Data)           #Ditto & more likely for outer ellipse
686        if Data['fullIntegrate']:
687            Azm = np.array(range(0,361))
688        else:
689            Azm = np.array(range(LRAzim[0],LRAzim[1]+1))
690        if ellI:
691            xyI = []
692            for azm in Azm:
693                xyI.append(G2cmp.GetDetectorXY(dspI,azm,Data))
694            xyI = np.array(xyI)
695            arcxI,arcyI = xyI.T
696            Plot.plot(arcxI,arcyI,picker=3)
697        if ellO:
698            xyO = []
699            for azm in Azm:
700                xyO.append(G2cmp.GetDetectorXY(dspO,azm,Data))
701            xyO = np.array(xyO)
702            arcxO,arcyO = xyO.T
703            Plot.plot(arcxO,arcyO,picker=3)
704        if ellO and ellI and not Data['fullIntegrate']:
705            Plot.plot([arcxI[0],arcxO[0]],[arcyI[0],arcyO[0]],picker=3)
706            Plot.plot([arcxI[-1],arcxO[-1]],[arcyI[-1],arcyO[-1]],picker=3)
707    for xring,yring in Data['ring']:
708        Plot.plot(xring,yring,'r+',picker=3)
709    if Data['setRings']:
710        rings = np.concatenate((Data['rings']),axis=0)
711        for xring,yring,dsp in rings:
712            Plot.plot(xring,yring,'r+')           
713    for ellipse in Data['ellipses']:
714        cent,phi,[width,height],col = ellipse
715        Plot.add_artist(Ellipse([cent[0],cent[1]],2*width,2*height,phi,ec=col,fc='none'))
716        Plot.text(cent[0],cent[1],'+',color=col,ha='center',va='center')
717    colorBar = Page.figure.colorbar(self.Img)
718    Plot.set_xlim(xlim)
719    Plot.set_ylim(ylim)
720    if not newPlot:
721        Page.toolbar.push_current()
722        Plot.set_xlim(xylim[0])
723        Plot.set_ylim(xylim[1])
724        xylim = []
725        Page.toolbar.push_current()
726        Page.toolbar.draw()
727    else:
728        Page.canvas.draw()
729           
730def PlotTRImage(self,newPlot=False):
731           
732    def OnMotion(event):
733        Page.canvas.SetToolTipString('')
734        Page.canvas.SetCursor(wx.CROSS_CURSOR)
735        azm = event.xdata
736        tth = event.ydata
737        if azm and tth:
738            self.G2plotNB.status.SetFields(\
739                ['Detector 2-th =%9.2fdeg, azm = %7.2fdeg'%(tth,azm),])
740                   
741    def OnPick(event):
742        if self.PatternTree.GetItemText(self.PickId) != 'Image Controls':
743            return
744        if self.itemPicked is not None: return
745        pick = event.artist
746        self.itemPicked = pick
747       
748    def OnRelease(event):
749        if self.PatternTree.GetItemText(self.PickId) != 'Image Controls':
750            return
751        Data = self.PatternTree.GetItemPyData(self.PickId)
752        if self.itemPicked:
753            xpos = event.xdata
754            if xpos:                                        #avoid out of frame mouse position
755                ypos = event.ydata
756                if 'Line2D' in str(self.itemPicked):
757                    if 'line0' in str(self.itemPicked):
758                        Data['IOtth'][0] = ypos
759                    elif 'line1' in str(self.itemPicked):
760                        Data['IOtth'][1] = ypos
761                    elif 'line2' in str(self.itemPicked) and not Data['fullIntegrate']:
762                        Data['LRazimuth'][0] = int(xpos)
763                    elif 'line3' in str(self.itemPicked) and not Data['fullIntegrate']:
764                        Data['LRazimuth'][1] = int(xpos)
765                       
766                    if Data['LRazimuth'][1] < Data['LRazimuth'][0]:
767                        Data['LRazimuth'][1] += 360
768                    if  Data['IOtth'][0] > Data['IOtth'][1]:
769                        Data['IOtth'] = G2cmp.SwapXY(Data['IOtth'][0],Data['IOtth'][1])
770                       
771                    self.InnerTth.SetValue("%8.2f" % (Data['IOtth'][0]))
772                    self.OuterTth.SetValue("%8.2f" % (Data['IOtth'][1]))
773                    self.Lazim.SetValue("%6d" % (Data['LRazimuth'][0]))
774                    self.Razim.SetValue("%6d" % (Data['LRazimuth'][1]))
775                else:
776                    print event.xdata,event.ydata,event.button
777                PlotTRImage(self)
778            self.itemPicked = None
779           
780    try:
781        plotNum = self.G2plotNB.plotList.index('2D Transformed Powder Image')
782        Page = self.G2plotNB.nb.GetPage(plotNum)
783        if not newPlot:
784            Plot = Page.figure.gca()          #get previous plot & get limits
785            xylim = Plot.get_xlim(),Plot.get_ylim()
786        Page.figure.clf()
787        Plot = Page.figure.gca()          #get a fresh plot after clf()
788       
789    except ValueError,error:
790        Plot = self.G2plotNB.add('2D Transformed Powder Image').gca()
791        plotNum = self.G2plotNB.plotList.index('2D Transformed Powder Image')
792        Page = self.G2plotNB.nb.GetPage(plotNum)
793        Page.canvas.mpl_connect('motion_notify_event', OnMotion)
794        Page.canvas.mpl_connect('pick_event', OnPick)
795        Page.canvas.mpl_connect('button_release_event', OnRelease)
796        Page.views = False
797        view = False
798    Page.SetFocus()
799       
800    Data = self.PatternTree.GetItemPyData( \
801        G2gd.GetPatternTreeItemId(self,self.Image, 'Image Controls'))
802    image = self.ImageZ
803    Iz = len(image)
804    Imin,Imax = Data['range'][1]
805    step = (Imax-Imin)/5.
806    V = np.arange(Imin,Imax,step)
807    acolor = mpl.cm.get_cmap(Data['color'])
808    Plot.set_xlabel('azimuth',fontsize=12)
809    Plot.set_ylabel('2-theta',fontsize=12)
810    Plot.contour(self.TA[:,:,0],self.TA[:,:,1],self.TA[:,:,2],V,cmap=acolor)
811    if Data['showLines']:
812        IOtth = Data['IOtth']
813        if Data['fullIntegrate']:
814            LRAzim = [-180,180]
815        else:
816            LRAzim = Data['LRazimuth']                  #NB: integers
817        Plot.plot([LRAzim[0],LRAzim[1]],[IOtth[0],IOtth[0]],picker=True)
818        Plot.plot([LRAzim[0],LRAzim[1]],[IOtth[1],IOtth[1]],picker=True)
819        if not Data['fullIntegrate']:
820            Plot.plot([LRAzim[0],LRAzim[0]],[IOtth[0],IOtth[1]],picker=True)
821            Plot.plot([LRAzim[1],LRAzim[1]],[IOtth[0],IOtth[1]],picker=True)
822    if Data['setRings']:
823        rings = np.concatenate((Data['rings']),axis=0)
824        for xring,yring,dsp in rings:
825            x,y = G2cmp.GetTthAzm(xring,yring,Data)
826            Plot.plot(y,x,'r+')           
827    if not newPlot:
828        Page.toolbar.push_current()
829        Plot.set_xlim(xylim[0])
830        Plot.set_ylim(xylim[1])
831        xylim = []
832        Page.toolbar.push_current()
833        Page.toolbar.draw()
834    else:
835        Page.canvas.draw()
836       
837def PlotExposedImage(self,newPlot=False):
838    plotNo = self.G2plotNB.nb.GetSelection()
839    if self.G2plotNB.nb.GetPageText(plotNo) == '2D Transformed Powder Image':
840        PlotTRImage(self,newPlot)
841    elif self.G2plotNB.nb.GetPageText(plotNo) == '2D Powder Image':
842        PlotImage(self,newPlot)
843    elif self.G2plotNB.nb.GetPageText(plotNo) == '2D Integration':
844        PlotIntegration(self,newPlot)
845       
846def PlotIntegration(self,newPlot=False):
847           
848    def OnMotion(event):
849        Page.canvas.SetToolTipString('')
850        Page.canvas.SetCursor(wx.CROSS_CURSOR)
851        azm = event.ydata
852        tth = event.xdata
853        if azm and tth:
854            self.G2plotNB.status.SetFields(\
855                ['Detector 2-th =%9.2fdeg, azm = %7.2fdeg'%(tth,azm),])
856                               
857    try:
858        plotNum = self.G2plotNB.plotList.index('2D Integration')
859        Page = self.G2plotNB.nb.GetPage(plotNum)
860        if not newPlot:
861            Plot = Page.figure.gca()          #get previous plot & get limits
862            xylim = Plot.get_xlim(),Plot.get_ylim()
863        Page.figure.clf()
864        Plot = Page.figure.gca()          #get a fresh plot after clf()
865       
866    except ValueError,error:
867        Plot = self.G2plotNB.add('2D Integration').gca()
868        plotNum = self.G2plotNB.plotList.index('2D Integration')
869        Page = self.G2plotNB.nb.GetPage(plotNum)
870        Page.canvas.mpl_connect('motion_notify_event', OnMotion)
871        Page.views = False
872        view = False
873    Page.SetFocus()
874       
875    Data = self.PatternTree.GetItemPyData( \
876        G2gd.GetPatternTreeItemId(self,self.Image, 'Image Controls'))
877    image = self.Integrate[0]
878    xsc = self.Integrate[1]
879    ysc = self.Integrate[2]
880    Imin,Imax = Data['range'][1]
881    acolor = mpl.cm.get_cmap(Data['color'])
882    Plot.set_ylabel('azimuth',fontsize=12)
883    Plot.set_xlabel('2-theta',fontsize=12)
884    Plot.imshow(image,cmap=acolor,vmin=Imin,vmax=Imax,interpolation='nearest', \
885        extent=[ysc[0],ysc[-1],xsc[0],xsc[-1]],aspect='auto')
886    if Data['setRings']:
887        rings = np.concatenate((Data['rings']),axis=0)
888        for xring,yring,dsp in rings:
889            x,y = G2cmp.GetTthAzm(xring,yring,Data)
890            Plot.plot(x,y,'r+')           
891    if not newPlot:
892        Page.toolbar.push_current()
893        Plot.set_xlim(xylim[0])
894        Plot.set_ylim(xylim[1])
895        xylim = []
896        Page.toolbar.push_current()
897        Page.toolbar.draw()
898    else:
899        Page.canvas.draw()
900       
Note: See TracBrowser for help on using the repository browser.