source: trunk/GSASIIplot.py @ 552

Last change on this file since 552 was 552, checked in by vondreele, 11 years ago

charge flipping

  • Property svn:keywords set to Date Author Revision URL Id
File size: 128.8 KB
Line 
1#GSASII plotting routines
2########### SVN repository information ###################
3# $Date: 2012-04-18 19:52:20 +0000 (Wed, 18 Apr 2012) $
4# $Author: vondreele $
5# $Revision: 552 $
6# $URL: trunk/GSASIIplot.py $
7# $Id: GSASIIplot.py 552 2012-04-18 19:52:20Z vondreele $
8########### SVN repository information ###################
9import math
10import time
11import copy
12import os.path
13import numpy as np
14import numpy.ma as ma
15import numpy.linalg as nl
16import wx
17import wx.aui
18import wx.glcanvas
19import matplotlib as mpl
20import mpl_toolkits.mplot3d.axes3d as mp3d
21import GSASIIpath
22import GSASIIgrid as G2gd
23import GSASIIimage as G2img
24import GSASIIpwd as G2pwd
25import GSASIIIO as G2IO
26import GSASIIpwdGUI as G2pdG
27import GSASIIimgGUI as G2imG
28import GSASIIphsGUI as G2phG
29import GSASIIlattice as G2lat
30import GSASIIspc as G2spc
31import pytexture as ptx
32from  OpenGL.GL import *
33from OpenGL.GLU import *
34from OpenGL.GLUT import *
35from OpenGL.GLE import *
36from matplotlib.backends.backend_wx import _load_bitmap
37from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as Canvas
38from matplotlib.backends.backend_wxagg import NavigationToolbar2Wx as Toolbar
39
40# useful degree trig functions
41sind = lambda x: math.sin(x*math.pi/180.)
42cosd = lambda x: math.cos(x*math.pi/180.)
43tand = lambda x: math.tan(x*math.pi/180.)
44asind = lambda x: 180.*math.asin(x)/math.pi
45acosd = lambda x: 180.*math.acos(x)/math.pi
46atan2d = lambda x,y: 180.*math.atan2(y,x)/math.pi
47atand = lambda x: 180.*math.atan(x)/math.pi
48# numpy versions
49npsind = lambda x: np.sin(x*np.pi/180.)
50npcosd = lambda x: np.cos(x*np.pi/180.)
51npacosd = lambda x: 180.*np.arccos(x)/np.pi
52npasind = lambda x: 180.*np.arcsin(x)/np.pi
53npatand = lambda x: 180.*np.arctan(x)/np.pi
54npatan2d = lambda x,y: 180.*np.arctan2(x,y)/np.pi
55   
56class G2PlotMpl(wx.Panel):   
57    def __init__(self,parent,id=-1,dpi=None,**kwargs):
58        wx.Panel.__init__(self,parent,id=id,**kwargs)
59        mpl.rcParams['legend.fontsize'] = 10
60        self.figure = mpl.figure.Figure(dpi=dpi,figsize=(5,7))
61        self.canvas = Canvas(self,-1,self.figure)
62        self.toolbar = GSASIItoolbar(self.canvas)
63
64        self.toolbar.Realize()
65       
66        sizer=wx.BoxSizer(wx.VERTICAL)
67        sizer.Add(self.canvas,1,wx.EXPAND)
68        sizer.Add(self.toolbar,0,wx.LEFT|wx.EXPAND)
69        self.SetSizer(sizer)
70       
71class G2PlotOgl(wx.Panel):
72    def __init__(self,parent,id=-1,dpi=None,**kwargs):
73        self.figure = wx.Panel.__init__(self,parent,id=id,**kwargs)
74        self.canvas = wx.glcanvas.GLCanvas(self,-1,**kwargs)
75        self.camera = {}
76        sizer=wx.BoxSizer(wx.VERTICAL)
77        sizer.Add(self.canvas,1,wx.EXPAND)
78        self.SetSizer(sizer)
79       
80class G2Plot3D(wx.Panel):
81    def __init__(self,parent,id=-1,dpi=None,**kwargs):
82        wx.Panel.__init__(self,parent,id=id,**kwargs)
83        self.figure = mpl.figure.Figure(dpi=dpi,figsize=(6,6))
84        self.canvas = Canvas(self,-1,self.figure)
85        self.toolbar = GSASIItoolbar(self.canvas)
86
87        self.toolbar.Realize()
88       
89        sizer=wx.BoxSizer(wx.VERTICAL)
90        sizer.Add(self.canvas,1,wx.EXPAND)
91        sizer.Add(self.toolbar,0,wx.LEFT|wx.EXPAND)
92        self.SetSizer(sizer)
93                             
94class G2PlotNoteBook(wx.Panel):
95    def __init__(self,parent,id=-1):
96        wx.Panel.__init__(self,parent,id=id)
97        #so one can't delete a plot page!!
98        self.nb = wx.aui.AuiNotebook(self, \
99            style=wx.aui.AUI_NB_DEFAULT_STYLE ^ wx.aui.AUI_NB_CLOSE_ON_ACTIVE_TAB)
100        sizer = wx.BoxSizer()
101        sizer.Add(self.nb,1,wx.EXPAND)
102        self.SetSizer(sizer)
103        self.status = parent.CreateStatusBar()
104        self.status.SetFieldsCount(2)
105        self.status.SetStatusWidths([150,-1])
106        self.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CHANGED, self.OnPageChanged)
107       
108        self.plotList = []
109           
110    def addMpl(self,name=""):
111        page = G2PlotMpl(self.nb)
112        self.nb.AddPage(page,name)
113       
114        self.plotList.append(name)
115       
116        return page.figure
117       
118    def add3D(self,name=""):
119        page = G2Plot3D(self.nb)
120        self.nb.AddPage(page,name)
121       
122        self.plotList.append(name)
123       
124        return page.figure
125       
126    def addOgl(self,name=""):
127        page = G2PlotOgl(self.nb)
128        self.nb.AddPage(page,name)
129       
130        self.plotList.append(name)
131       
132        return page.figure
133       
134    def Delete(self,name):
135        try:
136            item = self.plotList.index(name)
137            del self.plotList[item]
138            self.nb.DeletePage(item)
139        except ValueError:          #no plot of this name - do nothing
140            return     
141               
142    def clear(self):
143        while self.nb.GetPageCount():
144            self.nb.DeletePage(0)
145        self.plotList = []
146        self.status.DestroyChildren()
147       
148    def Rename(self,oldName,newName):
149        try:
150            item = self.plotList.index(oldName)
151            self.plotList[item] = newName
152            self.nb.SetPageText(item,newName)
153        except ValueError:          #no plot of this name - do nothing
154            return     
155       
156    def OnPageChanged(self,event):       
157        if self.plotList:
158            self.status.SetStatusText('Better to select this from GSAS-II data tree',1)
159        self.status.DestroyChildren()                           #get rid of special stuff on status bar
160       
161class GSASIItoolbar(Toolbar):
162    ON_MPL_HELP = wx.NewId()
163    def __init__(self,plotCanvas):
164        Toolbar.__init__(self,plotCanvas)
165        POSITION_OF_CONFIGURE_SUBPLOTS_BTN = 6
166        self.DeleteToolByPos(POSITION_OF_CONFIGURE_SUBPLOTS_BTN)
167        help = os.path.join(os.path.split(__file__)[0],'help.ico')
168        self.AddSimpleTool(self.ON_MPL_HELP,_load_bitmap(help),'Help on','Show help on')
169        wx.EVT_TOOL(self,self.ON_MPL_HELP,self.OnHelp)
170    def OnHelp(self,event):
171        Page = self.GetParent().GetParent()
172        pageNo = Page.GetSelection()
173        bookmark = Page.GetPageText(pageNo)
174        bookmark = bookmark.strip(')').replace('(','_')
175        G2gd.ShowHelp(bookmark,self.TopLevelParent)
176
177################################################################################
178##### PlotSngl
179################################################################################
180           
181def PlotSngl(self,newPlot=False):
182    '''Single crystal structure factor plotting package - displays zone of reflections as rings proportional
183        to F, F**2, etc. as requested
184    '''
185    from matplotlib.patches import Circle
186    global HKL,HKLF
187
188    def OnSCMotion(event):
189        xpos = event.xdata
190        if xpos:
191            xpos = round(xpos)                                        #avoid out of frame mouse position
192            ypos = round(event.ydata)
193            zpos = Data['Layer']
194            if '100' in Data['Zone']:
195                HKLtxt = '(%3d,%3d,%3d)'%(zpos,xpos,ypos)
196            elif '010' in Data['Zone']:
197                HKLtxt = '(%3d,%3d,%3d)'%(xpos,zpos,ypos)
198            elif '001' in Data['Zone']:
199                HKLtxt = '(%3d,%3d,%3d)'%(xpos,ypos,zpos)
200            Page.canvas.SetToolTipString(HKLtxt)
201            self.G2plotNB.status.SetFields(['HKL = '+HKLtxt,''])
202               
203    def OnSCPick(event):
204        zpos = Data['Layer']
205        pos = event.artist.center
206        if '100' in Data['Zone']:
207            Page.canvas.SetToolTipString('(picked:(%3d,%3d,%3d))'%(zpos,pos[0],pos[1]))
208            hkl = np.array([zpos,pos[0],pos[1]])
209        elif '010' in Data['Zone']:
210            Page.canvas.SetToolTipString('(picked:(%3d,%3d,%3d))'%(pos[0],zpos,pos[1]))
211            hkl = np.array([pos[0],zpos,pos[1]])
212        elif '001' in Data['Zone']:
213            Page.canvas.SetToolTipString('(picked:(%3d,%3d,%3d))'%(pos[0],pos[1],zpos))
214            hkl = np.array([pos[0],pos[1],zpos])
215        h,k,l = hkl
216        hklf = HKLF[np.where(np.all(HKL-hkl == [0,0,0],axis=1))]
217        if len(hklf):
218            Fosq,sig,Fcsq = hklf[0]
219            HKLtxt = '(%3d,%3d,%3d %.2f %.3f %.2f %.2f)'%(h,k,l,Fosq,sig,Fcsq,(Fosq-Fcsq)/(scale*sig))
220            self.G2plotNB.status.SetFields(['','HKL, Fosq, sig, Fcsq, delFsq/sig = '+HKLtxt])
221                                 
222    def OnSCKeyPress(event):
223        print event.key
224
225    try:
226        plotNum = self.G2plotNB.plotList.index('Structure Factors')
227        Page = self.G2plotNB.nb.GetPage(plotNum)
228        if not newPlot:
229            Plot = Page.figure.gca()          #get previous powder plot & get limits
230            xylim = Plot.get_xlim(),Plot.get_ylim()
231        Page.figure.clf()
232        Plot = Page.figure.gca()          #get a fresh plot after clf()
233    except ValueError:
234        Plot = self.G2plotNB.addMpl('Structure Factors').gca()
235        plotNum = self.G2plotNB.plotList.index('Structure Factors')
236        Page = self.G2plotNB.nb.GetPage(plotNum)
237#        Page.canvas.mpl_connect('key_press_event', OnSCKeyPress)
238        Page.canvas.mpl_connect('pick_event', OnSCPick)
239        Page.canvas.mpl_connect('motion_notify_event', OnSCMotion)
240    Page.SetFocus()
241   
242    Plot.set_aspect(aspect='equal')
243    HKLref = self.PatternTree.GetItemPyData(self.Sngl)
244    Data = self.PatternTree.GetItemPyData( \
245        G2gd.GetPatternTreeItemId(self,self.Sngl, 'HKL Plot Controls'))
246    Type = Data['Type']           
247    scale = Data['Scale']
248    HKLmax = Data['HKLmax']
249    HKLmin = Data['HKLmin']
250    FosqMax = Data['FoMax']
251    FoMax = math.sqrt(FosqMax)
252    ifFc = Data['ifFc']
253    xlabel = ['k, h=','h, k=','h, l=']
254    ylabel = ['l','l','k']
255    zones = ['100','010','001']
256    pzone = [[1,2],[0,2],[0,1]]
257    izone = zones.index(Data['Zone'])
258    Plot.set_title(self.PatternTree.GetItemText(self.Sngl)[5:])
259    HKL = []
260    HKLF = []
261    for H,Fosq,sig,Fcsq,x,x,x in HKLref:
262        HKL.append(H)
263        HKLF.append([Fosq,sig,Fcsq])
264        if H[izone] == Data['Layer']:
265            B = 0
266            if Type == 'Fosq':
267                A = scale*Fosq/FosqMax
268                B = scale*Fcsq/FosqMax
269                C = abs(A-B)
270            elif Type == 'Fo':
271                A = scale*math.sqrt(max(0,Fosq))/FoMax
272                B = scale*math.sqrt(max(0,Fcsq))/FoMax
273                C = abs(A-B)
274            elif Type == '|DFsq|/sig':
275                A = abs(Fosq-Fcsq)/(scale*sig)
276            elif Type == '|DFsq|>sig':
277                A = abs(Fosq-Fcsq)/(scale*sig)
278                if A < 1.0: A = 0                   
279            elif Type == '|DFsq|>3sig':
280                A = abs(Fosq-Fcsq)/(scale*sig)
281                if A < 3.0: A = 0                   
282            xy = (H[pzone[izone][0]],H[pzone[izone][1]])
283            if A > 0.0:
284                Plot.add_artist(Circle(xy,radius=A,ec='g',fc='w',picker=3))
285            if B:
286                Plot.add_artist(Circle(xy,radius=B,ec='b',fc='w'))
287                radius = C
288                if radius > 0:
289                    if A > B:
290                        Plot.add_artist(Circle(xy,radius=radius,ec='g',fc='g'))
291                    else:                   
292                        Plot.add_artist(Circle(xy,radius=radius,ec='r',fc='r'))
293    HKL = np.array(HKL,dtype=np.int)
294    HKLF = np.array(HKLF)
295    Plot.set_xlabel(xlabel[izone]+str(Data['Layer']),fontsize=12)
296    Plot.set_ylabel(ylabel[izone],fontsize=12)
297    Plot.set_xlim((HKLmin[pzone[izone][0]],HKLmax[pzone[izone][0]]))
298    Plot.set_ylim((HKLmin[pzone[izone][1]],HKLmax[pzone[izone][1]]))
299    if not newPlot:
300        Page.toolbar.push_current()
301        Plot.set_xlim(xylim[0])
302        Plot.set_ylim(xylim[1])
303        xylim = []
304        Page.toolbar.push_current()
305        Page.toolbar.draw()
306    else:
307        Page.canvas.draw()
308       
309################################################################################
310##### PlotPatterns
311################################################################################
312           
313def PlotPatterns(G2frame,newPlot=False):
314    '''Powder pattern plotting package - displays single or multiple powder patterns as intensity vs
315    2-theta or q (future TOF). Can display multiple patterns as "waterfall plots" or contour plots. Log I
316    plotting available.
317    '''
318    global HKL
319   
320    def OnKeyBox(event):
321        if G2frame.G2plotNB.nb.GetSelection() == G2frame.G2plotNB.plotList.index('Powder Patterns'):
322            event.key = cb.GetValue()[0]
323            cb.SetValue(' key press')
324            OnPlotKeyPress(event)
325                       
326    def OnPlotKeyPress(event):
327        newPlot = False
328        if event.key == 'w':
329            if G2frame.Weight:
330                G2frame.Weight = False
331            else:
332                G2frame.Weight = True
333                G2frame.SinglePlot = True
334            newPlot = True
335        elif event.key == 'n':
336            if G2frame.Contour:
337                pass
338            else:
339                if G2frame.logPlot:
340                    G2frame.logPlot = False
341                else:
342                    G2frame.Offset[0] = 0
343                    G2frame.logPlot = True
344                newPlot = True
345        elif event.key == 'u':
346            if G2frame.Contour:
347                G2frame.Cmax = min(1.0,G2frame.Cmax*1.2)
348            elif G2frame.logPlot:
349                pass
350            elif G2frame.Offset[0] < 100.:
351                G2frame.Offset[0] += 1.
352        elif event.key == 'd':
353            if G2frame.Contour:
354                G2frame.Cmax = max(0.0,G2frame.Cmax*0.8)
355            elif G2frame.logPlot:
356                pass
357            elif G2frame.Offset[0] > 0.:
358                G2frame.Offset[0] -= 1.
359        elif event.key == 'l':
360            G2frame.Offset[1] -= 1.
361        elif event.key == 'r':
362            G2frame.Offset[1] += 1.
363        elif event.key == 'o':
364            G2frame.Offset = [0,0]
365        elif event.key == 'c':
366            newPlot = True
367            if G2frame.Contour:
368                G2frame.Contour = False
369            else:
370                G2frame.Contour = True
371                G2frame.SinglePlot = False
372                G2frame.Offset = [0.,0.]
373        elif event.key == 'q':
374            newPlot = True
375            if G2frame.qPlot:
376                G2frame.qPlot = False
377            else:
378                G2frame.qPlot = True
379        elif event.key == 's':
380            if G2frame.Contour:
381                choice = [m for m in mpl.cm.datad.keys() if not m.endswith("_r")]
382                choice.sort()
383                dlg = wx.SingleChoiceDialog(G2frame,'Select','Color scheme',choice)
384                if dlg.ShowModal() == wx.ID_OK:
385                    sel = dlg.GetSelection()
386                    G2frame.ContourColor = choice[sel]
387                else:
388                    G2frame.ContourColor = 'Paired'
389                dlg.Destroy()
390            else:               
391                if G2frame.SinglePlot:
392                    G2frame.SinglePlot = False
393                else:
394                    G2frame.SinglePlot = True
395            newPlot = True
396        elif event.key == '+':
397            if G2frame.PickId:
398                G2frame.PickId = False
399        elif event.key == 'i':                  #for smoothing contour plot
400            choice = ['nearest','bilinear','bicubic','spline16','spline36','hanning',
401               'hamming','hermite','kaiser','quadric','catrom','gaussian','bessel',
402               'mitchell','sinc','lanczos']
403            dlg = wx.SingleChoiceDialog(G2frame,'Select','Interpolation',choice)
404            if dlg.ShowModal() == wx.ID_OK:
405                sel = dlg.GetSelection()
406                G2frame.Interpolate = choice[sel]
407            else:
408                G2frame.Interpolate = 'nearest'
409            dlg.Destroy()
410           
411        PlotPatterns(G2frame,newPlot=newPlot)
412       
413    def OnMotion(event):
414        xpos = event.xdata
415        if xpos:                                        #avoid out of frame mouse position
416            ypos = event.ydata
417            Page.canvas.SetCursor(wx.CROSS_CURSOR)
418            try:
419                Values,Names = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Instrument Parameters'))[1::2]
420                Parms = dict(zip(Names,Values))
421                try:
422                    wave = Parms['Lam']
423                except KeyError:
424                    wave = Parms['Lam1']
425                if G2frame.qPlot:
426                    xpos = 2.0*asind(xpos*wave/(4*math.pi))
427                dsp = 0.0
428                if abs(xpos) > 0.:                  #avoid possible singularity at beam center
429                    dsp = wave/(2.*sind(abs(xpos)/2.0))
430                if G2frame.Contour:
431                    G2frame.G2plotNB.status.SetStatusText('2-theta =%9.3f d =%9.5f pattern ID =%5d'%(xpos,dsp,int(ypos)),1)
432                else:
433                    G2frame.G2plotNB.status.SetStatusText('2-theta =%9.3f d =%9.5f Intensity =%9.1f'%(xpos,dsp,ypos),1)
434                if G2frame.itemPicked:
435                    Page.canvas.SetToolTipString('%9.3f'%(xpos))
436                if G2frame.PickId:
437                    found = []
438                    if G2frame.PatternTree.GetItemText(G2frame.PickId) in ['Index Peak List','Unit Cells List','Reflection Lists'] or \
439                        'PWDR' in G2frame.PatternTree.GetItemText(PickId):
440                        if len(HKL):
441                            view = Page.toolbar._views.forward()[0][:2]
442                            wid = view[1]-view[0]
443                            found = HKL[np.where(np.fabs(HKL.T[5]-xpos) < 0.002*wid)]
444                        if len(found):
445                            h,k,l = found[0][:3] 
446                            Page.canvas.SetToolTipString('%d,%d,%d'%(int(h),int(k),int(l)))
447                        else:
448                            Page.canvas.SetToolTipString('')
449
450            except TypeError:
451                G2frame.G2plotNB.status.SetStatusText('Select PWDR powder pattern first',1)
452                                                   
453    def OnPick(event):
454        if G2frame.itemPicked is not None: return
455        PatternId = G2frame.PatternId
456        try:
457            Values,Names = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Instrument Parameters'))[1::2]
458        except TypeError:
459            return
460        Parms = dict(zip(Names,Values))
461        try:
462            wave = Parms['Lam']
463        except KeyError:
464            wave = Parms['Lam1']
465        PickId = G2frame.PickId
466        pick = event.artist
467        mouse = event.mouseevent       
468        xpos = pick.get_xdata()
469        ypos = pick.get_ydata()
470        ind = event.ind
471        xy = list(zip(np.take(xpos,ind),np.take(ypos,ind))[0])
472        if G2frame.PatternTree.GetItemText(PickId) == 'Peak List':
473            if ind.all() != [0]:                                    #picked a data point
474                if 'C' in Parms['Type']:                            #CW data - TOF later in an elif
475                    ins = [Parms[x] for x in ['U','V','W','X','Y']]
476                    if G2frame.qPlot:                              #qplot - convert back to 2-theta
477                        xy[0] = 2.0*asind(xy[0]*wave/(4*math.pi))
478                    sig = ins[0]*tand(xy[0]/2.0)**2+ins[1]*tand(xy[0]/2.0)+ins[2]
479                    gam = ins[3]/cosd(xy[0]/2.0)+ins[4]*tand(xy[0]/2.0)           
480                    data = G2frame.PatternTree.GetItemPyData(G2frame.PickId)
481                    XY = [xy[0],0, xy[1],1, sig,0, gam,0]       #default refine intensity 1st
482                data.append(XY)
483                G2pdG.UpdatePeakGrid(G2frame,data)
484                PlotPatterns(G2frame)
485            else:                                                   #picked a peak list line
486                G2frame.itemPicked = pick
487        elif G2frame.PatternTree.GetItemText(PickId) == 'Limits':
488            if ind.all() != [0]:                                    #picked a data point
489                LimitId = G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Limits')
490                data = G2frame.PatternTree.GetItemPyData(LimitId)
491                if 'C' in Parms['Type']:                            #CW data - TOF later in an elif
492                    if G2frame.qPlot:                              #qplot - convert back to 2-theta
493                        xy[0] = 2.0*asind(xy[0]*wave/(4*math.pi))
494                if mouse.button==1:
495                    data[1][0] = min(xy[0],data[1][1])
496                if mouse.button==3:
497                    data[1][1] = max(xy[0],data[1][0])
498                G2frame.PatternTree.SetItemPyData(LimitId,data)
499                G2pdG.UpdateLimitsGrid(G2frame,data)
500                PlotPatterns(G2frame)
501            else:                                                   #picked a limit line
502                G2frame.itemPicked = pick
503        elif G2frame.PatternTree.GetItemText(PickId) == 'Reflection Lists' or \
504            'PWDR' in G2frame.PatternTree.GetItemText(PickId):
505            G2frame.itemPicked = pick
506            pick = str(pick)
507       
508    def OnRelease(event):
509        if G2frame.itemPicked is None: return
510        Values,Names = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Instrument Parameters'))[1::2]
511        Parms = dict(zip(Names,Values))
512        try:
513            wave = Parms['Lam']
514        except KeyError:
515            wave = Parms['Lam1']
516        xpos = event.xdata
517        PickId = G2frame.PickId
518        if G2frame.PatternTree.GetItemText(PickId) in ['Peak List','Limits'] and xpos:
519            lines = []
520            for line in G2frame.Lines: 
521                lines.append(line.get_xdata()[0])
522#            print G2frame.itemPicked.get_xdata()
523            lineNo = lines.index(G2frame.itemPicked.get_xdata()[0])
524            if  lineNo in [0,1]:
525                LimitId = G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Limits')
526                data = G2frame.PatternTree.GetItemPyData(LimitId)
527                if G2frame.qPlot:
528                    data[1][lineNo] = 2.0*asind(wave*xpos/(4*math.pi))
529                else:
530                    data[1][lineNo] = xpos
531                G2frame.PatternTree.SetItemPyData(LimitId,data)
532                if G2frame.PatternTree.GetItemText(G2frame.PickId) == 'Limits':
533                    G2pdG.UpdateLimitsGrid(G2frame,data)
534            else:
535                PeakId = G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Peak List')
536                data = G2frame.PatternTree.GetItemPyData(PeakId)
537#                print 'peaks',xpos
538                if event.button == 3:
539                    del data[lineNo-2]
540                else:
541                    if G2frame.qPlot:
542                        data[lineNo-2][0] = 2.0*asind(wave*xpos/(4*math.pi))
543                    else:
544                        data[lineNo-2][0] = xpos
545                G2frame.PatternTree.SetItemPyData(PeakId,data)
546                G2pdG.UpdatePeakGrid(G2frame,data)
547        elif (G2frame.PatternTree.GetItemText(PickId) == 'Reflection Lists' or \
548            'PWDR' in G2frame.PatternTree.GetItemText(PickId)) and xpos:
549            Phases = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId,'Reflection Lists'))
550            pick = str(G2frame.itemPicked).split('(')[1].strip(')')
551            if 'Line' not in pick:       #avoid data points, etc.
552                num = Phases.keys().index(pick)
553                if num:
554                    G2frame.refDelt = -(event.ydata-G2frame.refOffset)/(num*Ymax)
555                else:       #1st row of refl ticks
556                    G2frame.refOffset = event.ydata
557        PlotPatterns(G2frame)
558        G2frame.itemPicked = None   
559
560    xylim = []
561    try:
562        plotNum = G2frame.G2plotNB.plotList.index('Powder Patterns')
563        Page = G2frame.G2plotNB.nb.GetPage(plotNum)
564        if not newPlot:
565            Plot = Page.figure.gca()          #get previous powder plot & get limits
566            xylim = Plot.get_xlim(),Plot.get_ylim()
567        Page.figure.clf()
568        Plot = Page.figure.gca()          #get a fresh plot after clf()
569    except ValueError:
570        newPlot = True
571        G2frame.Cmax = 1.0
572        Plot = G2frame.G2plotNB.addMpl('Powder Patterns').gca()
573        plotNum = G2frame.G2plotNB.plotList.index('Powder Patterns')
574        Page = G2frame.G2plotNB.nb.GetPage(plotNum)
575        Page.canvas.mpl_connect('key_press_event', OnPlotKeyPress)
576        Page.canvas.mpl_connect('motion_notify_event', OnMotion)
577        Page.canvas.mpl_connect('pick_event', OnPick)
578        Page.canvas.mpl_connect('button_release_event', OnRelease)
579    Page.SetFocus()
580    G2frame.G2plotNB.status.DestroyChildren()
581    if G2frame.Contour:
582        Choice = (' key press','d: lower contour max','u: raise contour max',
583            'i: interpolation method','s: color scheme','c: contour off')
584    else:
585        if G2frame.logPlot:
586            Choice = (' key press','n: log(I) off','l: offset left','r: offset right',
587                'c: contour on','q: toggle q plot','s: toggle single plot','+: no selection')
588        else:
589            Choice = (' key press','l: offset left','r: offset right','d: offset down',
590                'u: offset up','o: reset offset','n: log(I) on','c: contour on',
591                'q: toggle q plot','s: toggle single plot','w: toggle divide by sig','+: no selection')
592    cb = wx.ComboBox(G2frame.G2plotNB.status,style=wx.CB_DROPDOWN|wx.CB_READONLY,
593        choices=Choice)
594    cb.Bind(wx.EVT_COMBOBOX, OnKeyBox)
595    cb.SetValue(' key press')
596   
597    PickId = G2frame.PickId
598    PatternId = G2frame.PatternId
599    colors=['b','g','r','c','m','k']
600    Lines = []
601    if G2frame.SinglePlot:
602        Pattern = G2frame.PatternTree.GetItemPyData(PatternId)
603        Pattern.append(G2frame.PatternTree.GetItemText(PatternId))
604        PlotList = [Pattern,]
605        ParmList = [G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,
606            G2frame.PatternId, 'Instrument Parameters'))[1],]
607    else:       
608        PlotList = []
609        ParmList = []
610        item, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root)
611        while item:
612            if 'PWDR' in G2frame.PatternTree.GetItemText(item):
613                Pattern = G2frame.PatternTree.GetItemPyData(item)
614                if len(Pattern) < 3:                    # put name on end if needed
615                    Pattern.append(G2frame.PatternTree.GetItemText(item))
616                PlotList.append(Pattern)
617                ParmList.append(G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,
618                    item,'Instrument Parameters'))[1])
619            item, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie)               
620    Ymax = 1.0
621    lenX = 0
622    if G2frame.PatternTree.GetItemText(PickId) in ['Reflection Lists']:
623        Phases = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId,'Reflection Lists'))
624        HKL = []
625        if Phases:
626            for peak in Phases[G2frame.RefList]:
627                HKL.append(peak[:6])
628            HKL = np.array(HKL)
629    else:
630        HKL = np.array(G2frame.HKL)
631    for Pattern in PlotList:
632        xye = Pattern[1]
633        Ymax = max(Ymax,max(xye[1]))
634    offset = G2frame.Offset[0]*Ymax/100.0
635    Title = 'Powder Patterns: '+os.path.split(G2frame.GSASprojectfile)[1]
636    if G2frame.logPlot:
637        Title = 'log('+Title+')'
638    Plot.set_title(Title)
639    if G2frame.qPlot:
640        Plot.set_xlabel(r'$q, \AA^{-1}$',fontsize=14)
641    else:       
642        Plot.set_xlabel(r'$\mathsf{2\theta}$',fontsize=14)
643    if G2frame.Weight:
644        Plot.set_ylabel(r'$\mathsf{I/\sigma(I)}$',fontsize=14)
645    else:
646        Plot.set_ylabel('Intensity',fontsize=12)
647    if G2frame.Contour:
648        ContourZ = []
649        ContourY = []
650        Nseq = 0
651    if len(PlotList) < 2:
652        G2frame.Contour = False
653    for N,Pattern in enumerate(PlotList):
654        Parms = ParmList[N]
655        ifpicked = False
656        LimitId = 0
657        xye = np.array(Pattern[1])
658        if PickId:
659            ifpicked = Pattern[2] == G2frame.PatternTree.GetItemText(PatternId)
660            LimitId = G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Limits')
661        if G2frame.qPlot:
662            Id = G2gd.GetPatternTreeItemId(G2frame,G2frame.root, Pattern[2])
663            X = 4*np.pi*npsind(xye[0]/2.0)/Parms[1]
664        else:
665            X = xye[0]
666        if not lenX:
667            lenX = len(X)           
668        Y = xye[1]+offset*N
669        if LimitId:
670            limits = np.array(G2frame.PatternTree.GetItemPyData(LimitId))
671            if G2frame.qPlot:
672                limits = 4*np.pi*npsind(limits/2.0)/Parms[1]
673            Lines.append(Plot.axvline(limits[1][0],color='g',dashes=(5,5),picker=3.))   
674            Lines.append(Plot.axvline(limits[1][1],color='r',dashes=(5,5),picker=3.))                   
675        if G2frame.Contour:
676           
677            if lenX == len(X):
678                ContourY.append(N)
679                ContourZ.append(Y)
680                ContourX = X
681                Nseq += 1
682                Plot.set_ylabel('Data sequence',fontsize=12)
683        else:
684            X += G2frame.Offset[1]*.005*N
685            if ifpicked:
686                Z = xye[3]+offset*N
687                W = xye[4]+offset*N
688                D = xye[5]-Ymax*G2frame.delOffset
689                if G2frame.logPlot:
690                    Plot.semilogy(X,Y,colors[N%6]+'+',picker=3.,clip_on=False,nonposy='mask')
691                    Plot.semilogy(X,Z,colors[(N+1)%6],picker=False,nonposy='mask')
692                    Plot.semilogy(X,W,colors[(N+2)%6],picker=False,nonposy='mask')
693                elif G2frame.Weight:
694                    DY = xye[1]*np.sqrt(xye[2])
695                    DYmax = max(DY)
696                    DZ = xye[3]*np.sqrt(xye[2])
697                    DS = xye[5]*np.sqrt(xye[2])-DYmax*G2frame.delOffset
698                    Plot.plot(X,DY,colors[N%6]+'+',picker=3.,clip_on=False)
699                    Plot.plot(X,DZ,colors[(N+1)%6],picker=False)
700                    Plot.plot(X,DS,colors[(N+3)%6],picker=False)
701                    Plot.axhline(0.,color=wx.BLACK)
702                else:
703                    Plot.plot(X,Y,colors[N%6]+'+',picker=3.,clip_on=False)
704                    Plot.plot(X,Z,colors[(N+1)%6],picker=False)
705                    Plot.plot(X,W,colors[(N+2)%6],picker=False)
706                    Plot.plot(X,D,colors[(N+3)%6],picker=False)
707                    Plot.axhline(0.,color=wx.BLACK)
708                Page.canvas.SetToolTipString('')
709                if G2frame.PatternTree.GetItemText(PickId) == 'Peak List':
710                    tip = 'On data point: Pick peak - L or R MB. On line: L-move, R-delete'
711                    Page.canvas.SetToolTipString(tip)
712                    data = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Peak List'))
713                    for item in data:
714                        if G2frame.qPlot:
715                            Lines.append(Plot.axvline(4*math.pi*sind(item[0]/2.)/Parms[1],color=colors[N%6],picker=2.))
716                        else:
717                            Lines.append(Plot.axvline(item[0],color=colors[N%6],picker=2.))
718                if G2frame.PatternTree.GetItemText(PickId) == 'Limits':
719                    tip = 'On data point: Lower limit - L MB; Upper limit - R MB. On limit: MB down to move'
720                    Page.canvas.SetToolTipString(tip)
721                    data = G2frame.LimitsTable.GetData()
722            else:
723                if G2frame.logPlot:
724                    Plot.semilogy(X,Y,colors[N%6],picker=False,nonposy='clip')
725                else:
726                    Plot.plot(X,Y,colors[N%6],picker=False)
727    if PickId and not G2frame.Contour:
728        Values,Names = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Instrument Parameters'))[1::2]
729        Parms = dict(zip(Names,Values))
730        try:
731            wave = Parms['Lam']
732        except KeyError:
733            wave = Parms['Lam1']
734        if G2frame.PatternTree.GetItemText(PickId) in ['Index Peak List','Unit Cells List']:
735            peaks = np.array((G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Index Peak List'))))
736            for peak in peaks:
737                if G2frame.qPlot:
738                    Plot.axvline(4*np.pi*sind(peak[0]/2.0)/wave,color='b')
739                else:
740                    Plot.axvline(peak[0],color='b')
741            for hkl in G2frame.HKL:
742                if G2frame.qPlot:
743                    Plot.axvline(4*np.pi*sind(hkl[5]/2.0)/wave,color='r',dashes=(5,5))
744                else:
745                    Plot.axvline(hkl[5],color='r',dashes=(5,5))
746        elif G2frame.PatternTree.GetItemText(PickId) in ['Reflection Lists'] or \
747            'PWDR' in G2frame.PatternTree.GetItemText(PickId):
748            Phases = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId,'Reflection Lists'))
749            for pId,phase in enumerate(Phases):
750                peaks = Phases[phase]
751                peak = np.array([[peak[4],peak[5]] for peak in peaks])
752                pos = G2frame.refOffset-pId*Ymax*G2frame.refDelt*np.ones_like(peak)
753                if G2frame.qPlot:
754                    Plot.plot(2*np.pi/peak.T[0],pos,colors[pId%6]+'|',mew=1,ms=8,picker=3.,label=phase)
755                else:
756                    Plot.plot(peak.T[1],pos,colors[pId%6]+'|',mew=1,ms=8,picker=3.,label=phase)
757            if len(Phases):
758                handles,legends = Plot.get_legend_handles_labels()  #got double entries in the legends for some reason
759                Plot.legend(handles[::2],legends[::2],title='Phases',loc='best')    #skip every other one
760           
761    if G2frame.Contour:
762        acolor = mpl.cm.get_cmap(G2frame.ContourColor)
763        Img = Plot.imshow(ContourZ,cmap=acolor,vmin=0,vmax=Ymax*G2frame.Cmax,interpolation=G2frame.Interpolate, 
764            extent=[ContourX[0],ContourX[-1],ContourY[0],ContourY[-1]],aspect='auto',origin='lower')
765        Page.figure.colorbar(Img)
766    else:
767        G2frame.Lines = Lines
768    if not newPlot:
769        Page.toolbar.push_current()
770        Plot.set_xlim(xylim[0])
771        Plot.set_ylim(xylim[1])
772        xylim = []
773        Page.toolbar.push_current()
774        Page.toolbar.draw()
775    else:
776        Page.canvas.draw()
777    G2frame.Pwdr = True
778   
779################################################################################
780##### PlotDeltSig
781################################################################################
782           
783def PlotDeltSig(G2frame):
784    try:
785        plotNum = G2frame.G2plotNB.plotList.index('Error analysis')
786        Page = G2frame.G2plotNB.nb.GetPage(plotNum)
787        Page.figure.clf()
788        Plot = Page.figure.gca()          #get a fresh plot after clf()
789    except ValueError:
790        newPlot = True
791        G2frame.Cmax = 1.0
792        Plot = G2frame.G2plotNB.addMpl('Error analysis').gca()
793        plotNum = G2frame.G2plotNB.plotList.index('Error analysis')
794        Page = G2frame.G2plotNB.nb.GetPage(plotNum)
795    PatternId = G2frame.PatternId
796    Pattern = G2frame.PatternTree.GetItemPyData(PatternId)
797    Pattern.append(G2frame.PatternTree.GetItemText(PatternId))
798    limits = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Limits'))[1]
799    xye = np.array(Pattern[1])
800    xmin = np.searchsorted(xye[0],limits[0])
801    xmax = np.searchsorted(xye[0],limits[1])
802    X = xye[0][xmin:xmax]
803    DS = xye[5][xmin:xmax]*np.sqrt(xye[2][xmin:xmax])
804    Page.SetFocus()
805    G2frame.G2plotNB.status.DestroyChildren()
806    DS.sort()
807    EDS = np.zeros_like(DS)
808    DX = np.linspace(0.,1.,num=len(DS),endpoint=True)
809    oldErr = np.seterr(invalid='ignore')    #avoid problem at DX==0
810    T = np.sqrt(np.log(1.0/DX**2))
811    top = 2.515517+0.802853*T+0.010328*T**2
812    bot = 1.0+1.432788*T+0.189269*T**2+0.001308*T**3
813    EDS = np.where(DX>0,-(T-top/bot),(T-top/bot))
814    low1 = np.searchsorted(EDS,-1.)
815    hi1 = np.searchsorted(EDS,1.)
816    slp,intcp = np.polyfit(EDS[low1:hi1],DS[low1:hi1],deg=1)
817    frac = 100.*(hi1-low1)/len(DS)
818    G2frame.G2plotNB.status.SetStatusText(  \
819        'Over range -1. to 1. :'+' slope = %.3f, intercept = %.3f for %.2f%% of the fitted data'%(slp,intcp,frac),1)
820    Plot.set_title('Normal probability for '+Pattern[-1])
821    Plot.set_xlabel(r'expected $\mathsf{\Delta/\sigma}$',fontsize=14)
822    Plot.set_ylabel(r'observed $\mathsf{\Delta/\sigma}$',fontsize=14)
823    Plot.plot(EDS,DS,'r+',label='result')
824    Plot.plot([-2,2],[-2,2],'k',dashes=(5,5),label='ideal')
825    Plot.legend(loc='upper left')
826    np.seterr(invalid='warn')
827    Page.canvas.draw()
828       
829################################################################################
830##### PlotISFG
831################################################################################
832           
833def PlotISFG(G2frame,newPlot=False,type=''):
834    ''' PLotting package for PDF analysis; displays I(q), S(q), F(q) and G(r) as single
835    or multiple plots with waterfall and contour plots as options
836    '''
837    if not type:
838        type = G2frame.G2plotNB.plotList[G2frame.G2plotNB.nb.GetSelection()]
839    if type not in ['I(Q)','S(Q)','F(Q)','G(R)']:
840        return
841    superMinusOne = unichr(0xaf)+unichr(0xb9)
842   
843    def OnPlotKeyPress(event):
844        newPlot = False
845        if event.key == 'u':
846            if G2frame.Contour:
847                G2frame.Cmax = min(1.0,G2frame.Cmax*1.2)
848            elif G2frame.Offset[0] < 100.:
849                G2frame.Offset[0] += 1.
850        elif event.key == 'd':
851            if G2frame.Contour:
852                G2frame.Cmax = max(0.0,G2frame.Cmax*0.8)
853            elif G2frame.Offset[0] > 0.:
854                G2frame.Offset[0] -= 1.
855        elif event.key == 'l':
856            G2frame.Offset[1] -= 1.
857        elif event.key == 'r':
858            G2frame.Offset[1] += 1.
859        elif event.key == 'o':
860            G2frame.Offset = [0,0]
861        elif event.key == 'c':
862            newPlot = True
863            if G2frame.Contour:
864                G2frame.Contour = False
865            else:
866                G2frame.Contour = True
867                G2frame.SinglePlot = False
868                G2frame.Offset = [0.,0.]
869        elif event.key == 's':
870            if G2frame.Contour:
871                choice = [m for m in mpl.cm.datad.keys() if not m.endswith("_r")]
872                choice.sort()
873                dlg = wx.SingleChoiceDialog(G2frame,'Select','Color scheme',choice)
874                if dlg.ShowModal() == wx.ID_OK:
875                    sel = dlg.GetSelection()
876                    G2frame.ContourColor = choice[sel]
877                else:
878                    G2frame.ContourColor = 'Paired'
879                dlg.Destroy()
880            else:               
881                if G2frame.SinglePlot:
882                    G2frame.SinglePlot = False
883                else:
884                    G2frame.SinglePlot = True
885        elif event.key == 'i':                  #for smoothing contour plot
886            choice = ['nearest','bilinear','bicubic','spline16','spline36','hanning',
887               'hamming','hermite','kaiser','quadric','catrom','gaussian','bessel',
888               'mitchell','sinc','lanczos']
889            dlg = wx.SingleChoiceDialog(G2frame,'Select','Interpolation',choice)
890            if dlg.ShowModal() == wx.ID_OK:
891                sel = dlg.GetSelection()
892                G2frame.Interpolate = choice[sel]
893            else:
894                G2frame.Interpolate = 'nearest'
895            dlg.Destroy()
896        elif event.key == 't' and not G2frame.Contour:
897            if G2frame.Legend:
898                G2frame.Legend = False
899            else:
900                G2frame.Legend = True
901           
902           
903        PlotISFG(G2frame,newPlot=newPlot,type=type)
904       
905    def OnKeyBox(event):
906        if G2frame.G2plotNB.nb.GetSelection() == G2frame.G2plotNB.plotList.index(type):
907            event.key = cb.GetValue()[0]
908            cb.SetValue(' key press')
909            OnPlotKeyPress(event)
910                       
911    def OnMotion(event):
912        xpos = event.xdata
913        if xpos:                                        #avoid out of frame mouse position
914            ypos = event.ydata
915            Page.canvas.SetCursor(wx.CROSS_CURSOR)
916            try:
917                if G2frame.Contour:
918                    G2frame.G2plotNB.status.SetStatusText('R =%.3fA pattern ID =%5d'%(xpos,int(ypos)),1)
919                else:
920                    G2frame.G2plotNB.status.SetStatusText('R =%.3fA %s =%.2f'%(xpos,type,ypos),1)                   
921            except TypeError:
922                G2frame.G2plotNB.status.SetStatusText('Select '+type+' pattern first',1)
923   
924    xylim = []
925    try:
926        plotNum = G2frame.G2plotNB.plotList.index(type)
927        Page = G2frame.G2plotNB.nb.GetPage(plotNum)
928        if not newPlot:
929            Plot = Page.figure.gca()          #get previous plot & get limits
930            xylim = Plot.get_xlim(),Plot.get_ylim()
931        Page.figure.clf()
932        Plot = Page.figure.gca()
933    except ValueError:
934        newPlot = True
935        G2frame.Cmax = 1.0
936        Plot = G2frame.G2plotNB.addMpl(type).gca()
937        plotNum = G2frame.G2plotNB.plotList.index(type)
938        Page = G2frame.G2plotNB.nb.GetPage(plotNum)
939        Page.canvas.mpl_connect('key_press_event', OnPlotKeyPress)
940        Page.canvas.mpl_connect('motion_notify_event', OnMotion)
941   
942    Page.SetFocus()
943    G2frame.G2plotNB.status.DestroyChildren()
944    if G2frame.Contour:
945        Choice = (' key press','d: lower contour max','u: raise contour max',
946            'i: interpolation method','s: color scheme','c: contour off')
947    else:
948        Choice = (' key press','l: offset left','r: offset right','d: offset down','u: offset up',
949            'o: reset offset','t: toggle legend','c: contour on','s: toggle single plot')
950    cb = wx.ComboBox(G2frame.G2plotNB.status,style=wx.CB_DROPDOWN|wx.CB_READONLY,
951        choices=Choice)
952    cb.Bind(wx.EVT_COMBOBOX, OnKeyBox)
953    cb.SetValue(' key press')
954    PatternId = G2frame.PatternId
955    PickId = G2frame.PickId
956    Plot.set_title(type)
957    if type == 'G(R)':
958        Plot.set_xlabel(r'$R,\AA$',fontsize=14)
959    else:
960        Plot.set_xlabel(r'$Q,\AA$'+superMinusOne,fontsize=14)
961    Plot.set_ylabel(r''+type,fontsize=14)
962    colors=['b','g','r','c','m','k']
963    name = G2frame.PatternTree.GetItemText(PatternId)[4:]
964    Pattern = []   
965    if G2frame.SinglePlot:
966        name = G2frame.PatternTree.GetItemText(PatternId)
967        name = type+name[4:]
968        Id = G2gd.GetPatternTreeItemId(G2frame,PatternId,name)
969        Pattern = G2frame.PatternTree.GetItemPyData(Id)
970        if Pattern:
971            Pattern.append(name)
972        PlotList = [Pattern,]
973    else:
974        PlotList = []
975        item, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root)
976        while item:
977            if 'PDF' in G2frame.PatternTree.GetItemText(item):
978                name = type+G2frame.PatternTree.GetItemText(item)[4:]
979                Id = G2gd.GetPatternTreeItemId(G2frame,item,name)
980                Pattern = G2frame.PatternTree.GetItemPyData(Id)
981                if Pattern:
982                    Pattern.append(name)
983                    PlotList.append(Pattern)
984            item, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie)
985    PDFdata = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'PDF Controls'))
986    numbDen = G2pwd.GetNumDensity(PDFdata['ElList'],PDFdata['Form Vol'])
987    Xb = [0.,10.]
988    Yb = [0.,-40.*np.pi*numbDen]
989    Ymax = 1.0
990    lenX = 0
991    for Pattern in PlotList:
992        xye = Pattern[1]
993        Ymax = max(Ymax,max(xye[1]))
994    offset = G2frame.Offset[0]*Ymax/100.0
995    if G2frame.Contour:
996        ContourZ = []
997        ContourY = []
998        Nseq = 0
999    for N,Pattern in enumerate(PlotList):
1000        xye = Pattern[1]
1001        if PickId:
1002            ifpicked = Pattern[2] == G2frame.PatternTree.GetItemText(PatternId)
1003        X = xye[0]
1004        if not lenX:
1005            lenX = len(X)           
1006        Y = xye[1]+offset*N
1007        if G2frame.Contour:
1008            if lenX == len(X):
1009                ContourY.append(N)
1010                ContourZ.append(Y)
1011                ContourX = X
1012                Nseq += 1
1013                Plot.set_ylabel('Data sequence',fontsize=12)
1014        else:
1015            X = xye[0]+G2frame.Offset[1]*.005*N
1016            if ifpicked:
1017                Plot.plot(X,Y,colors[N%6]+'+',picker=3.,clip_on=False)
1018                Page.canvas.SetToolTipString('')
1019            else:
1020                if G2frame.Legend:
1021                    Plot.plot(X,Y,colors[N%6],picker=False,label='Azm:'+Pattern[2].split('=')[1])
1022                else:
1023                    Plot.plot(X,Y,colors[N%6],picker=False)
1024            if type == 'G(R)':
1025                Plot.plot(Xb,Yb,color='k',dashes=(5,5))
1026            elif type == 'F(Q)':
1027                Plot.axhline(0.,color=wx.BLACK)
1028            elif type == 'S(Q)':
1029                Plot.axhline(1.,color=wx.BLACK)
1030    if G2frame.Contour:
1031        acolor = mpl.cm.get_cmap(G2frame.ContourColor)
1032        Img = Plot.imshow(ContourZ,cmap=acolor,vmin=0,vmax=Ymax*G2frame.Cmax,interpolation=G2frame.Interpolate, 
1033            extent=[ContourX[0],ContourX[-1],ContourY[0],ContourY[-1]],aspect='auto',origin='lower')
1034        Page.figure.colorbar(Img)
1035    elif G2frame.Legend:
1036        Plot.legend(loc='best')
1037    if not newPlot:
1038        Page.toolbar.push_current()
1039        Plot.set_xlim(xylim[0])
1040        Plot.set_ylim(xylim[1])
1041        xylim = []
1042        Page.toolbar.push_current()
1043        Page.toolbar.draw()
1044    else:
1045        Page.canvas.draw()
1046       
1047################################################################################
1048##### PlotXY
1049################################################################################
1050           
1051def PlotXY(G2frame,XY,newPlot=False,type=''):
1052    '''simple plot of xy data, used for diagnostic purposes
1053    '''
1054    def OnMotion(event):
1055        xpos = event.xdata
1056        if xpos:                                        #avoid out of frame mouse position
1057            ypos = event.ydata
1058            Page.canvas.SetCursor(wx.CROSS_CURSOR)
1059            try:
1060                G2frame.G2plotNB.status.SetStatusText('X =%9.3f %s =%9.3f'%(xpos,type,ypos),1)                   
1061            except TypeError:
1062                G2frame.G2plotNB.status.SetStatusText('Select '+type+' pattern first',1)
1063
1064    try:
1065        plotNum = G2frame.G2plotNB.plotList.index(type)
1066        Page = G2frame.G2plotNB.nb.GetPage(plotNum)
1067        if not newPlot:
1068            Plot = Page.figure.gca()
1069            xylim = Plot.get_xlim(),Plot.get_ylim()
1070        Page.figure.clf()
1071        Plot = Page.figure.gca()
1072    except ValueError:
1073        newPlot = True
1074        Plot = G2frame.G2plotNB.addMpl(type).gca()
1075        plotNum = G2frame.G2plotNB.plotList.index(type)
1076        Page = G2frame.G2plotNB.nb.GetPage(plotNum)
1077        Page.canvas.mpl_connect('motion_notify_event', OnMotion)
1078   
1079    Page.SetFocus()
1080    G2frame.G2plotNB.status.DestroyChildren()
1081    Plot.set_title(type)
1082    Plot.set_xlabel(r'X',fontsize=14)
1083    Plot.set_ylabel(r''+type,fontsize=14)
1084    colors=['b','g','r','c','m','k']
1085    Ymax = 1.0
1086    lenX = 0
1087    X,Y = XY[:2]
1088    Ymax = max(Ymax,max(Y))
1089    Plot.plot(X,Y,'k',picker=False)
1090    if not newPlot:
1091        Page.toolbar.push_current()
1092        Plot.set_xlim(xylim[0])
1093        Plot.set_ylim(xylim[1])
1094        xylim = []
1095        Page.toolbar.push_current()
1096        Page.toolbar.draw()
1097    else:
1098        Page.canvas.draw()
1099
1100################################################################################
1101##### PlotPowderLines
1102################################################################################
1103           
1104def PlotPowderLines(G2frame):
1105    ''' plotting of powder lines (i.e. no powder pattern) as sticks
1106    '''
1107    global HKL
1108
1109    def OnMotion(event):
1110        xpos = event.xdata
1111        if xpos:                                        #avoid out of frame mouse position
1112            Page.canvas.SetCursor(wx.CROSS_CURSOR)
1113            G2frame.G2plotNB.status.SetFields(['','2-theta =%9.3f '%(xpos,)])
1114            if G2frame.PickId and G2frame.PatternTree.GetItemText(G2frame.PickId) in ['Index Peak List','Unit Cells List']:
1115                found = []
1116                if len(HKL):
1117                    view = Page.toolbar._views.forward()[0][:2]
1118                    wid = view[1]-view[0]
1119                    found = HKL[np.where(np.fabs(HKL.T[5]-xpos) < 0.002*wid)]
1120                if len(found):
1121                    h,k,l = found[0][:3] 
1122                    Page.canvas.SetToolTipString('%d,%d,%d'%(int(h),int(k),int(l)))
1123                else:
1124                    Page.canvas.SetToolTipString('')
1125
1126    try:
1127        plotNum = G2frame.G2plotNB.plotList.index('Powder Lines')
1128        Page = G2frame.G2plotNB.nb.GetPage(plotNum)
1129        Page.figure.clf()
1130        Plot = Page.figure.gca()
1131    except ValueError:
1132        Plot = G2frame.G2plotNB.addMpl('Powder Lines').gca()
1133        plotNum = G2frame.G2plotNB.plotList.index('Powder Lines')
1134        Page = G2frame.G2plotNB.nb.GetPage(plotNum)
1135        Page.canvas.mpl_connect('motion_notify_event', OnMotion)
1136       
1137    Page.SetFocus()
1138    Plot.set_title('Powder Pattern Lines')
1139    Plot.set_xlabel(r'$\mathsf{2\theta}$',fontsize=14)
1140    PickId = G2frame.PickId
1141    PatternId = G2frame.PatternId
1142    peaks = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Index Peak List'))
1143    for peak in peaks:
1144        Plot.axvline(peak[0],color='b')
1145    HKL = np.array(G2frame.HKL)
1146    for hkl in G2frame.HKL:
1147        Plot.axvline(hkl[5],color='r',dashes=(5,5))
1148    xmin = peaks[0][0]
1149    xmax = peaks[-1][0]
1150    delt = xmax-xmin
1151    xlim = [max(0,xmin-delt/20.),min(180.,xmax+delt/20.)]
1152    Plot.set_xlim(xlim)
1153    Page.canvas.draw()
1154    Page.toolbar.push_current()
1155
1156################################################################################
1157##### PlotPeakWidths
1158################################################################################
1159           
1160def PlotPeakWidths(G2frame):
1161    ''' Plotting of instrument broadening terms as function of 2-theta (future TOF)
1162    Seen when "Instrument Parameters" chosen from powder pattern data tree
1163    '''
1164    PatternId = G2frame.PatternId
1165    limitID = G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Limits')
1166    if limitID:
1167        limits = G2frame.PatternTree.GetItemPyData(limitID)
1168    else:
1169        return
1170    instParms = G2frame.PatternTree.GetItemPyData( \
1171        G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Instrument Parameters'))
1172    if instParms[0][0] in ['PXC','PNC']:
1173        lam = instParms[1][1]
1174        if len(instParms[1]) == 13:
1175            GU,GV,GW,LX,LY = instParms[0][6:11]
1176        else:
1177            GU,GV,GW,LX,LY = instParms[0][4:9]
1178    peakID = G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Peak List')
1179    if peakID:
1180        peaks = G2frame.PatternTree.GetItemPyData(peakID)
1181    else:
1182        peaks = []
1183   
1184    try:
1185        plotNum = G2frame.G2plotNB.plotList.index('Peak Widths')
1186        Page = G2frame.G2plotNB.nb.GetPage(plotNum)
1187        Page.figure.clf()
1188        Plot = Page.figure.gca()
1189    except ValueError:
1190        Plot = G2frame.G2plotNB.addMpl('Peak Widths').gca()
1191        plotNum = G2frame.G2plotNB.plotList.index('Peak Widths')
1192        Page = G2frame.G2plotNB.nb.GetPage(plotNum)
1193    Page.SetFocus()
1194   
1195    Page.canvas.SetToolTipString('')
1196    colors=['b','g','r','c','m','k']
1197    Xmin,Xmax = limits[1]
1198    Xmin = min(0.5,max(Xmin,1))
1199    Xmin /= 2
1200    Xmax /= 2
1201    nPts = 100
1202    delt = (Xmax-Xmin)/nPts
1203    thetas = []
1204    for i in range(nPts):
1205        thetas.append(Xmin+i*delt)
1206    X = []
1207    Y = []
1208    Z = []
1209    W = []
1210    sig = lambda Th,U,V,W: 1.17741*math.sqrt(U*tand(Th)**2+V*tand(Th)+W)*math.pi/18000.
1211    gam = lambda Th,X,Y: (X/cosd(Th)+Y*tand(Th))*math.pi/18000.
1212    gamFW = lambda s,g: math.exp(math.log(s**5+2.69269*s**4*g+2.42843*s**3*g**2+4.47163*s**2*g**3+0.07842*s*g**4+g**5)/5.)
1213#    gamFW2 = lambda s,g: math.sqrt(s**2+(0.4654996*g)**2)+.5345004*g  #Ubaldo Bafile - private communication
1214    for theta in thetas:
1215        X.append(4.0*math.pi*sind(theta)/lam)              #q
1216        s = sig(theta,GU,GV,GW)
1217        g = gam(theta,LX,LY)
1218        G = gamFW(g,s)
1219        Y.append(s/tand(theta))
1220        Z.append(g/tand(theta))
1221        W.append(G/tand(theta))
1222    Plot.set_title('Instrument and sample peak widths')
1223    Plot.set_ylabel(r'$\Delta q/q, \Delta d/d$',fontsize=14)
1224    Plot.set_xlabel(r'$q, \AA^{-1}$',fontsize=14)
1225    Plot.plot(X,Y,color='r',label='Gaussian')
1226    Plot.plot(X,Z,color='g',label='Lorentzian')
1227    Plot.plot(X,W,color='b',label='G+L')
1228    X = []
1229    Y = []
1230    Z = []
1231    W = []
1232    V = []
1233    for peak in peaks:
1234        X.append(4.0*math.pi*sind(peak[0]/2.0)/lam)
1235        try:
1236            s = 1.17741*math.sqrt(peak[4])*math.pi/18000.
1237        except ValueError:
1238            s = 0.01
1239        g = peak[6]*math.pi/18000.
1240        G = gamFW(g,s)
1241        Y.append(s/tand(peak[0]/2.))
1242        Z.append(g/tand(peak[0]/2.))
1243        W.append(G/tand(peak[0]/2.))
1244    Plot.plot(X,Y,'+',color='r',label='G peak')
1245    Plot.plot(X,Z,'+',color='g',label='L peak')
1246    Plot.plot(X,W,'+',color='b',label='G+L peak')
1247    Plot.legend(loc='best')
1248    Page.canvas.draw()
1249   
1250################################################################################
1251##### PlotSizeStrainPO
1252################################################################################
1253           
1254def PlotSizeStrainPO(G2frame,data,Start=False):
1255    '''Plot 3D mustrain/size/preferred orientation figure. In this instance data is for a phase
1256    '''
1257   
1258    PatternId = G2frame.PatternId
1259    generalData = data['General']
1260    SGData = generalData['SGData']
1261    SGLaue = SGData['SGLaue']
1262    if Start:                   #initialize the spherical harmonics qlmn arrays
1263        ptx.pyqlmninit()
1264        Start = False
1265#    MuStrKeys = G2spc.MustrainNames(SGData)
1266    cell = generalData['Cell'][1:]
1267    A,B = G2lat.cell2AB(cell[:6])
1268    Vol = cell[6]
1269    useList = data['Histograms']
1270    phase = generalData['Name']
1271    plotType = generalData['Data plot type']
1272    plotDict = {'Mustrain':'Mustrain','Size':'Size','Preferred orientation':'Pref.Ori.'}
1273    for ptype in plotDict:
1274        G2frame.G2plotNB.Delete(ptype)       
1275
1276    for item in useList:
1277        if useList[item]['Show']:
1278            break
1279    else:
1280        return            #nothing to show!!
1281   
1282    numPlots = len(useList)
1283
1284    if plotType in ['Mustrain','Size']:
1285        Plot = mp3d.Axes3D(G2frame.G2plotNB.add3D(plotType))
1286    else:
1287        Plot = G2frame.G2plotNB.addMpl(plotType).gca()       
1288    plotNum = G2frame.G2plotNB.plotList.index(plotType)
1289    Page = G2frame.G2plotNB.nb.GetPage(plotNum)
1290    Page.SetFocus()
1291    G2frame.G2plotNB.status.SetStatusText('',1)
1292    if not Page.IsShown():
1293        Page.Show()
1294   
1295    for item in useList:
1296        if useList[item]['Show']:
1297            PHI = np.linspace(0.,360.,30,True)
1298            PSI = np.linspace(0.,180.,30,True)
1299            X = np.outer(npsind(PHI),npsind(PSI))
1300            Y = np.outer(npcosd(PHI),npsind(PSI))
1301            Z = np.outer(np.ones(np.size(PHI)),npcosd(PSI))
1302            try:        #temp patch instead of 'mustrain' for old files with 'microstrain'
1303                coeff = useList[item][plotDict[plotType]]
1304            except KeyError:
1305                break
1306            if plotType in ['Mustrain','Size']:
1307                if coeff[0] == 'isotropic':
1308                    X *= coeff[1][0]
1309                    Y *= coeff[1][0]
1310                    Z *= coeff[1][0]                               
1311                elif coeff[0] == 'uniaxial':
1312                   
1313                    def uniaxCalc(xyz,iso,aniso,axes):
1314                        Z = np.array(axes)
1315                        cp = abs(np.dot(xyz,Z))
1316                        sp = np.sqrt(1.-cp**2)
1317                        R = iso*aniso/np.sqrt((iso*cp)**2+(aniso*sp)**2)
1318                        return R*xyz
1319                       
1320                    iso,aniso = coeff[1][:2]
1321                    axes = np.inner(A,np.array(coeff[3]))
1322                    axes /= nl.norm(axes)
1323                    Shkl = np.array(coeff[1])
1324                    XYZ = np.dstack((X,Y,Z))
1325                    XYZ = np.nan_to_num(np.apply_along_axis(uniaxCalc,2,XYZ,iso,aniso,axes))
1326                    X,Y,Z = np.dsplit(XYZ,3)
1327                    X = X[:,:,0]
1328                    Y = Y[:,:,0]
1329                    Z = Z[:,:,0]
1330               
1331                elif coeff[0] == 'ellipsoidal':
1332                   
1333                    def ellipseCalc(xyz,E,R):
1334                        XYZ = xyz*E.T
1335                        return np.inner(XYZ.T,R)
1336                       
1337                    S6 = coeff[4]
1338                    Sij = G2lat.U6toUij(S6)
1339                    E,R = nl.eigh(Sij)
1340                    XYZ = np.dstack((X,Y,Z))
1341                    XYZ = np.nan_to_num(np.apply_along_axis(ellipseCalc,2,XYZ,E,R))
1342                    X,Y,Z = np.dsplit(XYZ,3)
1343                    X = X[:,:,0]
1344                    Y = Y[:,:,0]
1345                    Z = Z[:,:,0]
1346                   
1347                elif coeff[0] == 'generalized':
1348                   
1349                    def genMustrain(xyz,SGData,A,Shkl):
1350                        uvw = np.inner(A.T,xyz)
1351                        Strm = np.array(G2spc.MustrainCoeff(uvw,SGData))
1352                        sum = np.sum(np.multiply(Shkl,Strm))
1353                        sum = np.where(sum > 0.01,sum,0.01)
1354                        sum = np.sqrt(sum)*math.pi/0.018      #centidegrees to radians!
1355                        return sum*xyz
1356                       
1357                    Shkl = np.array(coeff[4])
1358                    if np.any(Shkl):
1359                        XYZ = np.dstack((X,Y,Z))
1360                        XYZ = np.nan_to_num(np.apply_along_axis(genMustrain,2,XYZ,SGData,A,Shkl))
1361                        X,Y,Z = np.dsplit(XYZ,3)
1362                        X = X[:,:,0]
1363                        Y = Y[:,:,0]
1364                        Z = Z[:,:,0]
1365                           
1366                if np.any(X) and np.any(Y) and np.any(Z):
1367                    errFlags = np.seterr(all='ignore')
1368                    Plot.plot_surface(X,Y,Z,rstride=1,cstride=1,color='g',linewidth=1)
1369                    np.seterr(all='ignore')
1370                    xyzlim = np.array([Plot.get_xlim3d(),Plot.get_ylim3d(),Plot.get_zlim3d()]).T
1371                    XYZlim = [min(xyzlim[0]),max(xyzlim[1])]
1372                    Plot.set_xlim3d(XYZlim)
1373                    Plot.set_ylim3d(XYZlim)
1374                    Plot.set_zlim3d(XYZlim)
1375                    Plot.set_aspect('equal')
1376                if plotType == 'Size':
1377                    Plot.set_title('Crystallite size for '+phase+'\n'+coeff[0]+' model')
1378                    Plot.set_xlabel(r'X, $\mu$m')
1379                    Plot.set_ylabel(r'Y, $\mu$m')
1380                    Plot.set_zlabel(r'Z, $\mu$m')
1381                else:   
1382                    Plot.set_title(r'$\mu$strain for '+phase+'\n'+coeff[0]+' model')
1383                    Plot.set_xlabel(r'X, $\mu$strain')
1384                    Plot.set_ylabel(r'Y, $\mu$strain')
1385                    Plot.set_zlabel(r'Z, $\mu$strain')
1386            else:
1387                h,k,l = generalData['POhkl']
1388                if coeff[0] == 'MD':
1389                    print 'March-Dollase preferred orientation plot'
1390               
1391                else:
1392                    PH = np.array(generalData['POhkl'])
1393                    phi,beta = G2lat.CrsAng(PH,cell[:6],SGData)
1394                    SHCoef = {}
1395                    for item in coeff[5]:
1396                        L,N = eval(item.strip('C'))
1397                        SHCoef['C%d,0,%d'%(L,N)] = coeff[5][item]                       
1398                    ODFln = G2lat.Flnh(Start,SHCoef,phi,beta,SGData)
1399                    X = np.linspace(0,90.0,26)
1400                    Y = G2lat.polfcal(ODFln,'0',X,0.0)
1401                    Plot.plot(X,Y,color='k',label=str(PH))
1402                    Plot.legend(loc='best')
1403                    Plot.set_title('Axial distribution for HKL='+str(PH)+' in '+phase)
1404                    Plot.set_xlabel(r'$\psi$',fontsize=16)
1405                    Plot.set_ylabel('MRD',fontsize=14)
1406    Page.canvas.draw()
1407   
1408################################################################################
1409##### PlotTexture
1410################################################################################
1411           
1412def PlotTexture(G2frame,data,newPlot=False,Start=False):
1413    '''Pole figure, inverse pole figure, 3D pole distribution and 3D inverse pole distribution
1414    plotting.
1415    dict generalData contains all phase info needed which is in data
1416    '''
1417
1418    shModels = ['cylindrical','none','shear - 2/m','rolling - mmm']
1419    SamSym = dict(zip(shModels,['0','-1','2/m','mmm']))
1420    PatternId = G2frame.PatternId
1421    generalData = data['General']
1422    SGData = generalData['SGData']
1423    textureData = generalData['SH Texture']
1424    G2frame.G2plotNB.Delete('Texture')
1425    if not textureData['Order']:
1426        return                  #no plot!!
1427    SHData = generalData['SH Texture']
1428    SHCoef = SHData['SH Coeff'][1]
1429    cell = generalData['Cell'][1:7]
1430    Amat,Bmat = G2lat.cell2AB(cell)
1431    sq2 = 1.0/math.sqrt(2.0)
1432   
1433    def rp2xyz(r,p):
1434        z = npcosd(r)
1435        xy = np.sqrt(1.-z**2)
1436        return xy*npsind(p),xy*npcosd(p),z
1437           
1438    def OnMotion(event):
1439        SHData = data['General']['SH Texture']
1440        if event.xdata and event.ydata:                 #avoid out of frame errors
1441            xpos = event.xdata
1442            ypos = event.ydata
1443            if 'Inverse' in SHData['PlotType']:
1444                r = xpos**2+ypos**2
1445                if r <= 1.0:
1446                    if 'equal' in G2frame.Projection: 
1447                        r,p = 2.*npasind(np.sqrt(r)*sq2),npatan2d(ypos,xpos)
1448                    else:
1449                        r,p = 2.*npatand(np.sqrt(r)),npatan2d(ypos,xpos)
1450                    ipf = G2lat.invpolfcal(IODFln,SGData,np.array([r,]),np.array([p,]))
1451                    xyz = np.inner(Amat.T,np.array([rp2xyz(r,p)]))
1452                    y,x,z = list(xyz/np.max(np.abs(xyz)))
1453                   
1454                    G2frame.G2plotNB.status.SetFields(['',
1455                        'psi =%9.3f, beta =%9.3f, MRD =%9.3f hkl=%5.2f,%5.2f,%5.2f'%(r,p,ipf,x,y,z)])
1456                                   
1457            elif 'Axial' in SHData['PlotType']:
1458                pass
1459               
1460            else:                       #ordinary pole figure
1461                z = xpos**2+ypos**2
1462                if z <= 1.0:
1463                    z = np.sqrt(z)
1464                    if 'equal' in G2frame.Projection: 
1465                        r,p = 2.*npasind(z*sq2),npatan2d(ypos,xpos)
1466                    else:
1467                        r,p = 2.*npatand(z),npatan2d(ypos,xpos)
1468                    pf = G2lat.polfcal(ODFln,SamSym[textureData['Model']],np.array([r,]),np.array([p,]))
1469                    G2frame.G2plotNB.status.SetFields(['','phi =%9.3f, gam =%9.3f, MRD =%9.3f'%(r,p,pf)])
1470   
1471    if G2frame.Projection == '3D display' and 'Axial'  not in SHData['PlotType']:               
1472        Plot = mp3d.Axes3D(G2frame.G2plotNB.add3D('Texture'))
1473    else:
1474        Plot = G2frame.G2plotNB.addMpl('Texture').gca()
1475    plotNum = G2frame.G2plotNB.plotList.index('Texture')
1476    Page = G2frame.G2plotNB.nb.GetPage(plotNum)
1477    if G2frame.Projection == '3D display':
1478        pass
1479    else:
1480        Page.canvas.mpl_connect('motion_notify_event', OnMotion)
1481
1482    Page.SetFocus()
1483    G2frame.G2plotNB.status.SetFields(['',''])   
1484    PH = np.array(SHData['PFhkl'])
1485    phi,beta = G2lat.CrsAng(PH,cell,SGData)
1486    ODFln = G2lat.Flnh(Start,SHCoef,phi,beta,SGData)
1487    PX = np.array(SHData['PFxyz'])
1488    gam = atan2d(PX[0],PX[1])
1489    xy = math.sqrt(PX[0]**2+PX[1]**2)
1490    xyz = math.sqrt(PX[0]**2+PX[1]**2+PX[2]**2)
1491    psi = asind(xy/xyz)
1492    IODFln = G2lat.Glnh(Start,SHCoef,psi,gam,SamSym[textureData['Model']])
1493    if 'Axial' in SHData['PlotType']:
1494        X = np.linspace(0,90.0,26)
1495        Y = G2lat.polfcal(ODFln,SamSym[textureData['Model']],X,0.0)
1496        Plot.plot(X,Y,color='k',label=str(SHData['PFhkl']))
1497        Plot.legend(loc='best')
1498        Plot.set_title('Axial distribution for HKL='+str(SHData['PFhkl']))
1499        Plot.set_xlabel(r'$\psi$',fontsize=16)
1500        Plot.set_ylabel('MRD',fontsize=14)
1501       
1502    else:       
1503        npts = 201
1504        if 'Inverse' in SHData['PlotType']:
1505            X,Y = np.meshgrid(np.linspace(1.,-1.,npts),np.linspace(-1.,1.,npts))
1506            R,P = np.sqrt(X**2+Y**2).flatten(),npatan2d(X,Y).flatten()
1507            if 'equal' in G2frame.Projection:
1508                R = np.where(R <= 1.,2.*npasind(R*sq2),0.0)
1509            else:
1510                R = np.where(R <= 1.,2.*npatand(R),0.0)
1511            Z = np.zeros_like(R)
1512            Z = G2lat.invpolfcal(IODFln,SGData,R,P)
1513            Z = np.reshape(Z,(npts,npts))
1514            CS = Plot.contour(Y,X,Z,aspect='equal')
1515            Plot.clabel(CS,fontsize=9,inline=1)
1516            try:
1517                Img = Plot.imshow(Z.T,aspect='equal',cmap=G2frame.ContourColor,extent=[-1,1,-1,1])
1518            except ValueError:
1519                pass
1520            if newPlot:
1521#                Page.figure.colorbar(Img)    #colorbar fails - crashes gsasii
1522                newPlot = False
1523            Plot.set_title('Inverse pole figure for XYZ='+str(SHData['PFxyz']))
1524            Plot.set_xlabel(G2frame.Projection.capitalize()+' projection')
1525                       
1526        else:
1527            X,Y = np.meshgrid(np.linspace(1.,-1.,npts),np.linspace(-1.,1.,npts))
1528            R,P = np.sqrt(X**2+Y**2).flatten(),npatan2d(X,Y).flatten()
1529            if 'equal' in G2frame.Projection:
1530                R = np.where(R <= 1.,2.*npasind(R*sq2),0.0)
1531            else:
1532                R = np.where(R <= 1.,2.*npatand(R),0.0)
1533            Z = np.zeros_like(R)
1534            Z = G2lat.polfcal(ODFln,SamSym[textureData['Model']],R,P)
1535            Z = np.reshape(Z,(npts,npts))
1536            try:
1537                CS = Plot.contour(Y,X,Z,aspect='equal')
1538                Plot.clabel(CS,fontsize=9,inline=1)
1539            except ValueError:
1540                pass
1541            Img = Plot.imshow(Z.T,aspect='equal',cmap=G2frame.ContourColor,extent=[-1,1,-1,1])
1542            if newPlot:
1543#                Page.figure.colorbar(Img)    #colorbar fails - crashes gsasii
1544                newPlot = False
1545            Plot.set_title('Pole figure for HKL='+str(SHData['PFhkl']))
1546            Plot.set_xlabel(G2frame.Projection.capitalize()+' projection')
1547    Page.canvas.draw()
1548
1549################################################################################
1550##### PlotCovariance
1551################################################################################
1552           
1553def PlotCovariance(G2frame,Data={}):
1554    if not Data:
1555        Data = G2frame.PatternTree.GetItemPyData(
1556            G2gd.GetPatternTreeItemId(G2frame,G2frame.root, 'Covariance'))
1557    if not Data:
1558        print 'No covariance matrix available'
1559        return
1560    varyList = Data['varyList']
1561    values = Data['variables']
1562    Xmax = len(varyList)
1563    covMatrix = Data['covMatrix']
1564    sig = np.sqrt(np.diag(covMatrix))
1565    xvar = np.outer(sig,np.ones_like(sig))
1566    covArray = np.divide(np.divide(covMatrix,xvar),xvar.T)
1567    title = ' for\n'+Data['title']
1568    newAtomDict = Data['newAtomDict']
1569
1570    def OnPlotKeyPress(event):
1571        newPlot = False
1572        if event.key == 's':
1573            choice = [m for m in mpl.cm.datad.keys() if not m.endswith("_r")]
1574            choice.sort()
1575            dlg = wx.SingleChoiceDialog(G2frame,'Select','Color scheme',choice)
1576            if dlg.ShowModal() == wx.ID_OK:
1577                sel = dlg.GetSelection()
1578                G2frame.VcovColor = choice[sel]
1579            else:
1580                G2frame.VcovColor = 'RdYlGn'
1581            dlg.Destroy()
1582        PlotCovariance(G2frame)
1583
1584    def OnMotion(event):
1585        if event.button:
1586            ytics = imgAx.get_yticks()
1587            ytics = np.where(ytics<len(varyList),ytics,-1)
1588            ylabs = [np.where(0<=i ,varyList[int(i)],' ') for i in ytics]
1589            imgAx.set_yticklabels(ylabs)
1590           
1591        if event.xdata and event.ydata:                 #avoid out of frame errors
1592            xpos = int(event.xdata+.5)
1593            ypos = int(event.ydata+.5)
1594            if -1 < xpos < len(varyList) and -1 < ypos < len(varyList):
1595                if xpos == ypos:
1596                    value = values[xpos]
1597                    name = varyList[xpos]
1598                    if varyList[xpos] in newAtomDict:
1599                        name,value = newAtomDict[name]                       
1600                    msg = '%s value = %.4g, esd = %.4g'%(name,value,sig[xpos])
1601                else:
1602                    msg = '%s - %s: %5.3f'%(varyList[xpos],varyList[ypos],covArray[xpos][ypos])
1603                Page.canvas.SetToolTipString(msg)
1604                G2frame.G2plotNB.status.SetFields(['Key: s to change colors',msg])
1605    try:
1606        plotNum = G2frame.G2plotNB.plotList.index('Covariance')
1607        Page = G2frame.G2plotNB.nb.GetPage(plotNum)
1608        Page.figure.clf()
1609        Plot = Page.figure.gca()
1610        if not Page.IsShown():
1611            Page.Show()
1612    except ValueError:
1613        Plot = G2frame.G2plotNB.addMpl('Covariance').gca()
1614        plotNum = G2frame.G2plotNB.plotList.index('Covariance')
1615        Page = G2frame.G2plotNB.nb.GetPage(plotNum)
1616        Page.canvas.mpl_connect('motion_notify_event', OnMotion)
1617        Page.canvas.mpl_connect('key_press_event', OnPlotKeyPress)
1618
1619    Page.SetFocus()
1620    G2frame.G2plotNB.status.SetFields(['',''])   
1621    acolor = mpl.cm.get_cmap(G2frame.VcovColor)
1622    Img = Plot.imshow(covArray,aspect='equal',cmap=acolor,interpolation='nearest',origin='lower')
1623    imgAx = Img.get_axes()
1624    ytics = imgAx.get_yticks()
1625    ylabs = [varyList[int(i)] for i in ytics[:-1]]
1626    imgAx.set_yticklabels(ylabs)
1627    colorBar = Page.figure.colorbar(Img)
1628    Plot.set_title('V-Cov matrix'+title)
1629    Plot.set_xlabel('Variable number')
1630    Plot.set_ylabel('Variable name')
1631    Page.canvas.draw()
1632   
1633################################################################################
1634##### PlotSeq
1635################################################################################
1636           
1637def PlotSeq(G2frame,SeqData,SeqSig,SeqNames,sampleParm):
1638   
1639    def OnKeyPress(event):
1640        if event.key == 's' and sampleParm:
1641            if G2frame.xAxis:
1642                G2frame.xAxis = False
1643            else:
1644                G2frame.xAxis = True
1645            Draw(False)
1646    try:
1647        plotNum = G2frame.G2plotNB.plotList.index('Sequential refinement')
1648        Page = G2frame.G2plotNB.nb.GetPage(plotNum)
1649        Page.figure.clf()
1650        Plot = Page.figure.gca()
1651        if not Page.IsShown():
1652            Page.Show()
1653    except ValueError:
1654        Plot = G2frame.G2plotNB.addMpl('Sequential refinement').gca()
1655        plotNum = G2frame.G2plotNB.plotList.index('Sequential refinement')
1656        Page = G2frame.G2plotNB.nb.GetPage(plotNum)
1657        Page.canvas.mpl_connect('key_press_event', OnKeyPress)
1658        G2frame.xAxis = False
1659       
1660    def Draw(newPlot):
1661        Page.SetFocus()
1662        G2frame.G2plotNB.status.SetFields(['','press s to toggle x-axis = sample environment parameter'])
1663        if len(SeqData):
1664            Plot.clear()
1665            if G2frame.xAxis:   
1666                xName = sampleParm.keys()[0]
1667                X = sampleParm[xName]
1668            else:
1669                X = np.arange(0,len(SeqData[0]),1)
1670                xName = 'Data sequence number'
1671            for Y,sig,name in zip(SeqData,SeqSig,SeqNames):
1672                Plot.errorbar(X,Y,yerr=sig,label=name)       
1673            Plot.legend(loc='best')
1674            Plot.set_ylabel('Parameter values')
1675            Plot.set_xlabel(xName)
1676            Page.canvas.draw()           
1677    Draw(True)
1678           
1679################################################################################
1680##### PlotExposedImage & PlotImage
1681################################################################################
1682           
1683def PlotExposedImage(G2frame,newPlot=False,event=None):
1684    '''General access module for 2D image plotting
1685    '''
1686    plotNo = G2frame.G2plotNB.nb.GetSelection()
1687    if G2frame.G2plotNB.nb.GetPageText(plotNo) == '2D Powder Image':
1688        PlotImage(G2frame,newPlot,event,newImage=True)
1689    elif G2frame.G2plotNB.nb.GetPageText(plotNo) == '2D Integration':
1690        PlotIntegration(G2frame,newPlot,event)
1691
1692def PlotImage(G2frame,newPlot=False,event=None,newImage=True):
1693    '''Plot of 2D detector images as contoured plot. Also plot calibration ellipses,
1694    masks, etc.
1695    '''
1696    from matplotlib.patches import Ellipse,Arc,Circle,Polygon
1697    import numpy.ma as ma
1698    Dsp = lambda tth,wave: wave/(2.*sind(tth/2.))
1699    global Data,Masks
1700    colors=['b','g','r','c','m','k']
1701    Data = G2frame.PatternTree.GetItemPyData(
1702        G2gd.GetPatternTreeItemId(G2frame,G2frame.Image, 'Image Controls'))
1703    Masks = G2frame.PatternTree.GetItemPyData(
1704        G2gd.GetPatternTreeItemId(G2frame,G2frame.Image, 'Masks'))
1705
1706    def OnImMotion(event):
1707        Page.canvas.SetToolTipString('')
1708        sizexy = Data['size']
1709        if event.xdata and event.ydata and len(G2frame.ImageZ):                 #avoid out of frame errors
1710            Page.canvas.SetCursor(wx.CROSS_CURSOR)
1711            item = G2frame.itemPicked
1712            pixelSize = Data['pixelSize']
1713            scalex = 1000./pixelSize[0]
1714            scaley = 1000./pixelSize[1]
1715            if item and G2frame.PatternTree.GetItemText(G2frame.PickId) == 'Image Controls':
1716                if 'Text' in str(item):
1717                    Page.canvas.SetToolTipString('%8.3f %8.3fmm'%(event.xdata,event.ydata))
1718                else:
1719                    xcent,ycent = Data['center']
1720                    xpos = event.xdata-xcent
1721                    ypos = event.ydata-ycent
1722                    tth,azm = G2img.GetTthAzm(event.xdata,event.ydata,Data)
1723                    if 'line3' in  str(item) or 'line4' in str(item) and not Data['fullIntegrate']:
1724                        Page.canvas.SetToolTipString('%6d deg'%(azm))
1725                    elif 'line1' in  str(item) or 'line2' in str(item):
1726                        Page.canvas.SetToolTipString('%8.3fdeg'%(tth))                           
1727            else:
1728                xpos = event.xdata
1729                ypos = event.ydata
1730                xpix = xpos*scalex
1731                ypix = ypos*scaley
1732                Int = 0
1733                if (0 <= xpix <= sizexy[0]) and (0 <= ypix <= sizexy[1]):
1734                    Int = G2frame.ImageZ[ypix][xpix]
1735                tth,azm,dsp = G2img.GetTthAzmDsp(xpos,ypos,Data)
1736                Q = 2.*math.pi/dsp
1737                if G2frame.setPoly:
1738                    G2frame.G2plotNB.status.SetFields(['','Polygon mask pick - LB next point, RB close polygon'])
1739                else:
1740                    G2frame.G2plotNB.status.SetFields(\
1741                        ['','Detector 2-th =%9.3fdeg, dsp =%9.3fA, Q = %6.5fA-1, azm = %7.2fdeg, I = %6d'%(tth,dsp,Q,azm,Int)])
1742
1743    def OnImPlotKeyPress(event):
1744        try:
1745            PickName = G2frame.PatternTree.GetItemText(G2frame.PickId)
1746        except TypeError:
1747            return
1748        if PickName == 'Masks':
1749            Xpos = event.xdata
1750            if not Xpos:            #got point out of frame
1751                return
1752            Ypos = event.ydata
1753            if event.key == 's':
1754                Masks['Points'].append([Xpos,Ypos,1.])
1755            elif event.key == 'r':
1756                tth = G2img.GetTth(Xpos,Ypos,Data)
1757                Masks['Rings'].append([tth,0.1])
1758            elif event.key == 'a':
1759                tth,azm = G2img.GetTthAzm(Xpos,Ypos,Data)
1760                azm = int(azm)               
1761                Masks['Arcs'].append([tth,[azm-5,azm+5],0.1])
1762            elif event.key == 'p':
1763                G2frame.setPoly = True
1764                Masks['Polygons'].append([])
1765                G2frame.G2plotNB.status.SetFields(['','Polygon mask active - LB pick next point, RB close polygon'])
1766            G2imG.UpdateMasks(G2frame,Masks)
1767        elif PickName == 'Image Controls':
1768            if event.key == 'c':
1769                Xpos = event.xdata
1770                if not Xpos:            #got point out of frame
1771                    return
1772                Ypos = event.ydata
1773                dlg = wx.MessageDialog(G2frame,'Are you sure you want to change the center?',
1774                    'Center change',style=wx.OK|wx.CANCEL)
1775                try:
1776                    if dlg.ShowModal() == wx.ID_OK:
1777                        print 'move center to: ',Xpos,Ypos
1778                        Data['center'] = [Xpos,Ypos]
1779                        G2imG.UpdateImageControls(G2frame,Data,Masks)
1780                finally:
1781                    dlg.Destroy()
1782            elif event.key == 'l':
1783                if G2frame.logPlot:
1784                    G2frame.logPlot = False
1785                else:
1786                    G2frame.logPlot = True
1787        PlotImage(G2frame,newImage=True)
1788           
1789    def OnKeyBox(event):
1790        if G2frame.G2plotNB.nb.GetSelection() == G2frame.G2plotNB.plotList.index('2D Powder Image'):
1791            event.key = cb.GetValue()[0]
1792            cb.SetValue(' key press')
1793            if event.key in 'l':
1794                OnImPlotKeyPress(event)
1795                       
1796    def OnImPick(event):
1797        if G2frame.PatternTree.GetItemText(G2frame.PickId) not in ['Image Controls','Masks']:
1798            return
1799        if G2frame.setPoly:
1800            polygon = Masks['Polygons'][-1]
1801            xpos,ypos = event.mouseevent.xdata,event.mouseevent.ydata
1802            if xpos and ypos:                       #point inside image
1803                if len(polygon) > 2 and event.mouseevent.button == 3:
1804                    x0,y0 = polygon[0]
1805                    polygon.append([x0,y0])
1806                    G2frame.setPoly = False
1807                    G2frame.G2plotNB.status.SetFields(['','Polygon closed - RB drag a vertex to change shape'])
1808                else:
1809                    G2frame.G2plotNB.status.SetFields(['','New polygon point: %.1f,%.1f'%(xpos,ypos)])
1810                    polygon.append([xpos,ypos])
1811                G2imG.UpdateMasks(G2frame,Masks)
1812        else:
1813            if G2frame.itemPicked is not None: return
1814            G2frame.itemPicked = event.artist
1815            G2frame.mousePicked = event.mouseevent
1816       
1817    def OnImRelease(event):
1818        try:
1819            PickName = G2frame.PatternTree.GetItemText(G2frame.PickId)
1820        except TypeError:
1821            return
1822        if PickName not in ['Image Controls','Masks']:
1823            return
1824        pixelSize = Data['pixelSize']
1825        scalex = 1000./pixelSize[0]
1826        scaley = 1000./pixelSize[1]
1827        pixLimit = Data['pixLimit']
1828        if G2frame.itemPicked is None and PickName == 'Image Controls' and len(G2frame.ImageZ):
1829#            sizexy = Data['size']
1830            Xpos = event.xdata
1831            if not (Xpos and G2frame.ifGetRing):                   #got point out of frame
1832                return
1833            Ypos = event.ydata
1834            if Ypos and not Page.toolbar._active:         #make sure zoom/pan not selected
1835                if event.button == 1:
1836                    Xpix = Xpos*scalex
1837                    Ypix = Ypos*scaley
1838                    xpos,ypos,I,J = G2img.ImageLocalMax(G2frame.ImageZ,pixLimit,Xpix,Ypix)
1839                    if I and J:
1840                        xpos += .5                              #shift to pixel center
1841                        ypos += .5
1842                        xpos /= scalex                          #convert to mm
1843                        ypos /= scaley
1844                        Data['ring'].append([xpos,ypos])
1845                elif event.button == 3:
1846                    G2frame.dataFrame.GetStatusBar().SetStatusText('Calibrating...')
1847                    if G2img.ImageCalibrate(G2frame,Data):
1848                        G2frame.dataFrame.GetStatusBar().SetStatusText('Calibration successful - Show ring picks to check')
1849                        print 'Calibration successful'
1850                    else:
1851                        G2frame.dataFrame.GetStatusBar().SetStatusText('Calibration failed - Show ring picks to diagnose')
1852                        print 'Calibration failed'
1853                    G2frame.ifGetRing = False
1854                    G2imG.UpdateImageControls(G2frame,Data,Masks)
1855                    return
1856                PlotImage(G2frame,newImage=False)
1857            return
1858        else:
1859            xpos = event.xdata
1860            if xpos:                                        #avoid out of frame mouse position
1861                ypos = event.ydata
1862                if G2frame.ifGetRing:                          #delete a calibration ring pick
1863                    xypos = [xpos,ypos]
1864                    rings = Data['ring']
1865                    for ring in rings:
1866                        if np.allclose(ring,xypos,.01,0):
1867                            rings.remove(ring)                                                                       
1868                else:
1869                    tth,azm,dsp = G2img.GetTthAzmDsp(xpos,ypos,Data)
1870                    itemPicked = str(G2frame.itemPicked)
1871                    if 'Line2D' in itemPicked and PickName == 'Image Controls':
1872                        if 'line1' in itemPicked:
1873                            Data['IOtth'][0] = max(tth,0.001)
1874                        elif 'line2' in itemPicked:
1875                            Data['IOtth'][1] = tth
1876                        elif 'line3' in itemPicked:
1877                            Data['LRazimuth'][0] = int(azm)
1878                            if Data['fullIntegrate']:
1879                                Data['LRazimuth'][1] = Data['LRazimuth'][0]+360
1880                        elif 'line4' in itemPicked and not Data['fullIntegrate']:
1881                            Data['LRazimuth'][1] = int(azm)
1882                           
1883                        if Data['LRazimuth'][0] > Data['LRazimuth'][1]:
1884                            Data['LRazimuth'][0] -= 360
1885                           
1886                        azLim = np.array(Data['LRazimuth'])   
1887                        if np.any(azLim>360):
1888                            azLim -= 360
1889                            Data['LRazimuth'] = list(azLim)
1890                           
1891                        if  Data['IOtth'][0] > Data['IOtth'][1]:
1892                            Data['IOtth'][0],Data['IOtth'][1] = Data['IOtth'][1],Data['IOtth'][0]
1893                           
1894                        G2frame.InnerTth.SetValue("%8.2f" % (Data['IOtth'][0]))
1895                        G2frame.OuterTth.SetValue("%8.2f" % (Data['IOtth'][1]))
1896                        G2frame.Lazim.SetValue("%6d" % (Data['LRazimuth'][0]))
1897                        G2frame.Razim.SetValue("%6d" % (Data['LRazimuth'][1]))
1898                    elif 'Circle' in itemPicked and PickName == 'Masks':
1899                        spots = Masks['Points']
1900                        newPos = itemPicked.split(')')[0].split('(')[2].split(',')
1901                        newPos = np.array([float(newPos[0]),float(newPos[1])])
1902                        for spot in spots:
1903                            if np.allclose(np.array([spot[:2]]),newPos):
1904                                spot[:2] = xpos,ypos
1905                        G2imG.UpdateMasks(G2frame,Masks)
1906                    elif 'Line2D' in itemPicked and PickName == 'Masks':
1907                        Obj = G2frame.itemPicked.findobj()
1908                        rings = Masks['Rings']
1909                        arcs = Masks['Arcs']
1910                        polygons = Masks['Polygons']
1911                        for ring in G2frame.ringList:
1912                            if Obj == ring[0]:
1913                                rN = ring[1]
1914                                if ring[2] == 'o':
1915                                    rings[rN][0] = G2img.GetTth(xpos,ypos,Data)-rings[rN][1]/2.
1916                                else:
1917                                    rings[rN][0] = G2img.GetTth(xpos,ypos,Data)+rings[rN][1]/2.
1918                        for arc in G2frame.arcList:
1919                            if Obj == arc[0]:
1920                                aN = arc[1]
1921                                if arc[2] == 'o':
1922                                    arcs[aN][0] = G2img.GetTth(xpos,ypos,Data)-arcs[aN][2]/2
1923                                elif arc[2] == 'i':
1924                                    arcs[aN][0] = G2img.GetTth(xpos,ypos,Data)+arcs[aN][2]/2
1925                                elif arc[2] == 'l':
1926                                    arcs[aN][1][0] = int(G2img.GetAzm(xpos,ypos,Data))
1927                                else:
1928                                    arcs[aN][1][1] = int(G2img.GetAzm(xpos,ypos,Data))
1929                        for poly in G2frame.polyList:
1930                            if Obj == poly[0]:
1931                                ind = G2frame.itemPicked.contains(G2frame.mousePicked)[1]['ind'][0]
1932                                oldPos = np.array([G2frame.mousePicked.xdata,G2frame.mousePicked.ydata])
1933                                pN = poly[1]
1934                                for i,xy in enumerate(polygons[pN]):
1935                                    if np.allclose(np.array([xy]),oldPos,atol=1.0):
1936                                        polygons[pN][i] = xpos,ypos
1937                        G2imG.UpdateMasks(G2frame,Masks)
1938#                    else:                  #keep for future debugging
1939#                        print str(G2frame.itemPicked),event.xdata,event.ydata,event.button
1940                PlotImage(G2frame,newImage=True)
1941            G2frame.itemPicked = None
1942           
1943    try:
1944        plotNum = G2frame.G2plotNB.plotList.index('2D Powder Image')
1945        Page = G2frame.G2plotNB.nb.GetPage(plotNum)
1946        if not newPlot:
1947            Plot = Page.figure.gca()          #get previous powder plot & get limits
1948            xylim = Plot.get_xlim(),Plot.get_ylim()
1949        if newImage:
1950            Page.figure.clf()
1951            Plot = Page.figure.gca()          #get a fresh plot after clf()
1952       
1953    except ValueError:
1954        Plot = G2frame.G2plotNB.addMpl('2D Powder Image').gca()
1955        plotNum = G2frame.G2plotNB.plotList.index('2D Powder Image')
1956        Page = G2frame.G2plotNB.nb.GetPage(plotNum)
1957        Page.canvas.mpl_connect('key_press_event', OnImPlotKeyPress)
1958        Page.canvas.mpl_connect('motion_notify_event', OnImMotion)
1959        Page.canvas.mpl_connect('pick_event', OnImPick)
1960        Page.canvas.mpl_connect('button_release_event', OnImRelease)
1961        xylim = []
1962    if not event:                       #event from GUI TextCtrl - don't want focus to change to plot!!!
1963        Page.SetFocus()
1964    Title = G2frame.PatternTree.GetItemText(G2frame.Image)[4:]
1965    G2frame.G2plotNB.status.DestroyChildren()
1966    if G2frame.logPlot:
1967        Title = 'log('+Title+')'
1968    Plot.set_title(Title)
1969    try:
1970        if G2frame.PatternTree.GetItemText(G2frame.PickId) in ['Image Controls',]:
1971            Choice = (' key press','l: log(I) on',)
1972            if G2frame.logPlot:
1973                Choice[1] = 'l: log(I) off'
1974            cb = wx.ComboBox(G2frame.G2plotNB.status,style=wx.CB_DROPDOWN|wx.CB_READONLY,
1975                choices=Choice)
1976            cb.Bind(wx.EVT_COMBOBOX, OnKeyBox)
1977            cb.SetValue(' key press')
1978    except TypeError:
1979        pass
1980    size,imagefile = G2frame.PatternTree.GetItemPyData(G2frame.Image)
1981    if imagefile != G2frame.oldImagefile:
1982        imagefile = G2IO.CheckImageFile(G2frame,imagefile)
1983        if not imagefile:
1984            G2frame.G2plotNB.Delete('2D Powder Image')
1985            return
1986        G2frame.PatternTree.SetItemPyData(G2frame.Image,[size,imagefile])
1987        G2frame.ImageZ = G2IO.GetImageData(G2frame,imagefile,imageOnly=True)
1988        G2frame.oldImagefile = imagefile
1989
1990    imScale = 1
1991    if len(G2frame.ImageZ) > 1024:
1992        imScale = len(G2frame.ImageZ)/1024
1993    sizexy = Data['size']
1994    pixelSize = Data['pixelSize']
1995    scalex = 1000./pixelSize[0]
1996    scaley = 1000./pixelSize[1]
1997    Xmax = sizexy[0]*pixelSize[0]/1000.
1998    Ymax = sizexy[1]*pixelSize[1]/1000.
1999    xlim = (0,Xmax)
2000    ylim = (Ymax,0)
2001    Imin,Imax = Data['range'][1]
2002    acolor = mpl.cm.get_cmap(Data['color'])
2003    xcent,ycent = Data['center']
2004    Plot.set_xlabel('Image x-axis, mm',fontsize=12)
2005    Plot.set_ylabel('Image y-axis, mm',fontsize=12)
2006    #do threshold mask - "real" mask - others are just bondaries
2007    Zlim = Masks['Thresholds'][1]
2008    wx.BeginBusyCursor()
2009    try:
2010           
2011        if newImage:                   
2012            MA = ma.masked_greater(ma.masked_less(G2frame.ImageZ,Zlim[0]),Zlim[1])
2013            MaskA = ma.getmaskarray(MA)
2014            A = G2img.ImageCompress(MA,imScale)
2015            AM = G2img.ImageCompress(MaskA,imScale)
2016            if G2frame.logPlot:
2017                A = np.where(A>0,np.log(A),0)
2018                AM = np.where(AM>0,np.log(AM),0)
2019                Imin,Imax = [np.amin(A),np.amax(A)]
2020            ImgM = Plot.imshow(AM,aspect='equal',cmap='Reds',
2021                interpolation='nearest',vmin=0,vmax=2,extent=[0,Xmax,Ymax,0])
2022            Img = Plot.imshow(A,aspect='equal',cmap=acolor,
2023                interpolation='nearest',vmin=Imin,vmax=Imax,extent=[0,Xmax,Ymax,0])
2024            if G2frame.setPoly:
2025                Img.set_picker(True)
2026   
2027        Plot.plot(xcent,ycent,'x')
2028        if Data['showLines']:
2029            LRAzim = Data['LRazimuth']                  #NB: integers
2030            Nazm = Data['outAzimuths']
2031            delAzm = float(LRAzim[1]-LRAzim[0])/Nazm
2032            AzmthOff = Data['azmthOff']
2033            IOtth = Data['IOtth']
2034            wave = Data['wavelength']
2035            dspI = wave/(2.0*sind(IOtth[0]/2.0))
2036            ellI = G2img.GetEllipse(dspI,Data)           #=False if dsp didn't yield an ellipse (ugh! a parabola or a hyperbola)
2037            dspO = wave/(2.0*sind(IOtth[1]/2.0))
2038            ellO = G2img.GetEllipse(dspO,Data)           #Ditto & more likely for outer ellipse
2039            Azm = np.array(range(LRAzim[0],LRAzim[1]+1))-AzmthOff
2040            if ellI:
2041                xyI = []
2042                for azm in Azm:
2043                    xyI.append(G2img.GetDetectorXY(dspI,azm-90.,Data))
2044                xyI = np.array(xyI)
2045                arcxI,arcyI = xyI.T
2046                Plot.plot(arcxI,arcyI,picker=3)
2047            if ellO:
2048                xyO = []
2049                for azm in Azm:
2050                    xyO.append(G2img.GetDetectorXY(dspO,azm-90.,Data))
2051                xyO = np.array(xyO)
2052                arcxO,arcyO = xyO.T
2053                Plot.plot(arcxO,arcyO,picker=3)
2054            if ellO and ellI:
2055                Plot.plot([arcxI[0],arcxO[0]],[arcyI[0],arcyO[0]],picker=3)
2056                Plot.plot([arcxI[-1],arcxO[-1]],[arcyI[-1],arcyO[-1]],picker=3)
2057            for i in range(Nazm):
2058                cake = LRAzim[0]+i*delAzm-AzmthOff
2059                if Data['centerAzm']:
2060                    cake += delAzm/2.
2061                ind = np.searchsorted(Azm,cake)
2062                Plot.plot([arcxI[ind],arcxO[ind]],[arcyI[ind],arcyO[ind]],color='k',dashes=(5,5))
2063                   
2064        for xring,yring in Data['ring']:
2065            Plot.plot(xring,yring,'r+',picker=3)
2066        if Data['setRings']:
2067#            rings = np.concatenate((Data['rings']),axis=0)
2068            N = 0
2069            for ring in Data['rings']:
2070                xring,yring = np.array(ring).T[:2]
2071                Plot.plot(xring,yring,'+',color=colors[N%6])
2072                N += 1           
2073        for ellipse in Data['ellipses']:
2074            cent,phi,[width,height],col = ellipse
2075            Plot.add_artist(Ellipse([cent[0],cent[1]],2*width,2*height,phi,ec=col,fc='none'))
2076            Plot.text(cent[0],cent[1],'+',color=col,ha='center',va='center')
2077        #masks - mask lines numbered after integration limit lines
2078        spots = Masks['Points']
2079        rings = Masks['Rings']
2080        arcs = Masks['Arcs']
2081        polygons = Masks['Polygons']
2082        for x,y,d in spots:
2083            Plot.add_artist(Circle((x,y),radius=d/2,fc='none',ec='r',picker=3))
2084        G2frame.ringList = []
2085        for iring,(tth,thick) in enumerate(rings):
2086            wave = Data['wavelength']
2087            x1,y1 = np.hsplit(np.array(G2img.makeIdealRing(G2img.GetEllipse(Dsp(tth+thick/2.,wave),Data))),2)
2088            x2,y2 = np.hsplit(np.array(G2img.makeIdealRing(G2img.GetEllipse(Dsp(tth-thick/2.,wave),Data))),2)
2089            G2frame.ringList.append([Plot.plot(x1,y1,'r',picker=3),iring,'o'])           
2090            G2frame.ringList.append([Plot.plot(x2,y2,'r',picker=3),iring,'i'])
2091        G2frame.arcList = []
2092        for iarc,(tth,azm,thick) in enumerate(arcs):           
2093            wave = Data['wavelength']
2094            x1,y1 = np.hsplit(np.array(G2img.makeIdealRing(G2img.GetEllipse(Dsp(tth+thick/2.,wave),Data),azm)),2)
2095            x2,y2 = np.hsplit(np.array(G2img.makeIdealRing(G2img.GetEllipse(Dsp(max(0.01,tth-thick/2.),wave),Data),azm)),2)
2096            G2frame.arcList.append([Plot.plot(x1,y1,'r',picker=3),iarc,'o'])           
2097            G2frame.arcList.append([Plot.plot(x2,y2,'r',picker=3),iarc,'i'])
2098            G2frame.arcList.append([Plot.plot([x1[0],x2[0]],[y1[0],y2[0]],'r',picker=3),iarc,'l'])
2099            G2frame.arcList.append([Plot.plot([x1[-1],x2[-1]],[y1[-1],y2[-1]],'r',picker=3),iarc,'u'])
2100        G2frame.polyList = []
2101        for ipoly,polygon in enumerate(polygons):
2102            x,y = np.hsplit(np.array(polygon),2)
2103            G2frame.polyList.append([Plot.plot(x,y,'r+',picker=10),ipoly])
2104            Plot.plot(x,y,'r')           
2105        if newImage:
2106            colorBar = Page.figure.colorbar(Img)
2107        Plot.set_xlim(xlim)
2108        Plot.set_ylim(ylim)
2109        Plot.invert_yaxis()
2110        if not newPlot and xylim:
2111            Page.toolbar.push_current()
2112            Plot.set_xlim(xylim[0])
2113            Plot.set_ylim(xylim[1])
2114            xylim = []
2115            Page.toolbar.push_current()
2116            Page.toolbar.draw()
2117        else:
2118            Page.canvas.draw()
2119    finally:
2120        wx.EndBusyCursor()
2121       
2122################################################################################
2123##### PlotIntegration
2124################################################################################
2125           
2126def PlotIntegration(G2frame,newPlot=False,event=None):
2127    '''Plot of 2D image after image integration with 2-theta and azimuth as coordinates
2128    '''
2129           
2130    def OnMotion(event):
2131        Page.canvas.SetToolTipString('')
2132        Page.canvas.SetCursor(wx.CROSS_CURSOR)
2133        azm = event.ydata
2134        tth = event.xdata
2135        if azm and tth:
2136            G2frame.G2plotNB.status.SetFields(\
2137                ['','Detector 2-th =%9.3fdeg, azm = %7.2fdeg'%(tth,azm)])
2138                               
2139    try:
2140        plotNum = G2frame.G2plotNB.plotList.index('2D Integration')
2141        Page = G2frame.G2plotNB.nb.GetPage(plotNum)
2142        if not newPlot:
2143            Plot = Page.figure.gca()          #get previous plot & get limits
2144            xylim = Plot.get_xlim(),Plot.get_ylim()
2145        Page.figure.clf()
2146        Plot = Page.figure.gca()          #get a fresh plot after clf()
2147       
2148    except ValueError:
2149        Plot = G2frame.G2plotNB.addMpl('2D Integration').gca()
2150        plotNum = G2frame.G2plotNB.plotList.index('2D Integration')
2151        Page = G2frame.G2plotNB.nb.GetPage(plotNum)
2152        Page.canvas.mpl_connect('motion_notify_event', OnMotion)
2153        Page.views = False
2154        view = False
2155    if not event:
2156        Page.SetFocus()
2157       
2158    Data = G2frame.PatternTree.GetItemPyData(
2159        G2gd.GetPatternTreeItemId(G2frame,G2frame.Image, 'Image Controls'))
2160    image = G2frame.Integrate[0]
2161    xsc = G2frame.Integrate[1]
2162    ysc = G2frame.Integrate[2]
2163    Imin,Imax = Data['range'][1]
2164    acolor = mpl.cm.get_cmap(Data['color'])
2165    Plot.set_title(G2frame.PatternTree.GetItemText(G2frame.Image)[4:])
2166    Plot.set_ylabel('azimuth',fontsize=12)
2167    Plot.set_xlabel('2-theta',fontsize=12)
2168    Img = Plot.imshow(image,cmap=acolor,vmin=Imin,vmax=Imax,interpolation='nearest', \
2169        extent=[ysc[0],ysc[-1],xsc[-1],xsc[0]],aspect='auto')
2170    colorBar = Page.figure.colorbar(Img)
2171    if Data['ellipses']:           
2172        for ellipse in Data['ellipses']:
2173            ring = np.array(G2img.makeIdealRing(ellipse[:3])) #skip color
2174            x,y = np.hsplit(ring,2)
2175            tth,azm = G2img.GetTthAzm(x,y,Data)
2176#            azm = np.where(azm < 0.,azm+360,azm)
2177            Plot.plot(tth,azm,'b,')
2178    if not newPlot:
2179        Page.toolbar.push_current()
2180        Plot.set_xlim(xylim[0])
2181        Plot.set_ylim(xylim[1])
2182        xylim = []
2183        Page.toolbar.push_current()
2184        Page.toolbar.draw()
2185    else:
2186        Page.canvas.draw()
2187               
2188################################################################################
2189##### PlotTRImage
2190################################################################################
2191           
2192def PlotTRImage(G2frame,tax,tay,taz,newPlot=False):
2193    '''a test plot routine - not normally used
2194    ''' 
2195           
2196    def OnMotion(event):
2197        Page.canvas.SetToolTipString('')
2198        Page.canvas.SetCursor(wx.CROSS_CURSOR)
2199        azm = event.xdata
2200        tth = event.ydata
2201        if azm and tth:
2202            G2frame.G2plotNB.status.SetFields(\
2203                ['','Detector 2-th =%9.3fdeg, azm = %7.2fdeg'%(tth,azm)])
2204                               
2205    try:
2206        plotNum = G2frame.G2plotNB.plotList.index('2D Transformed Powder Image')
2207        Page = G2frame.G2plotNB.nb.GetPage(plotNum)
2208        if not newPlot:
2209            Plot = Page.figure.gca()          #get previous plot & get limits
2210            xylim = Plot.get_xlim(),Plot.get_ylim()
2211        Page.figure.clf()
2212        Plot = Page.figure.gca()          #get a fresh plot after clf()
2213       
2214    except ValueError:
2215        Plot = G2frame.G2plotNB.addMpl('2D Transformed Powder Image').gca()
2216        plotNum = G2frame.G2plotNB.plotList.index('2D Transformed Powder Image')
2217        Page = G2frame.G2plotNB.nb.GetPage(plotNum)
2218        Page.canvas.mpl_connect('motion_notify_event', OnMotion)
2219        Page.views = False
2220        view = False
2221    Page.SetFocus()
2222       
2223    Data = G2frame.PatternTree.GetItemPyData(
2224        G2gd.GetPatternTreeItemId(G2frame,G2frame.Image, 'Image Controls'))
2225    Imin,Imax = Data['range'][1]
2226    step = (Imax-Imin)/5.
2227    V = np.arange(Imin,Imax,step)
2228    acolor = mpl.cm.get_cmap(Data['color'])
2229    Plot.set_title(G2frame.PatternTree.GetItemText(G2frame.Image)[4:])
2230    Plot.set_xlabel('azimuth',fontsize=12)
2231    Plot.set_ylabel('2-theta',fontsize=12)
2232    Plot.contour(tax,tay,taz,V,cmap=acolor)
2233    if Data['showLines']:
2234        IOtth = Data['IOtth']
2235        if Data['fullIntegrate']:
2236            LRAzim = [-180,180]
2237        else:
2238            LRAzim = Data['LRazimuth']                  #NB: integers
2239        Plot.plot([LRAzim[0],LRAzim[1]],[IOtth[0],IOtth[0]],picker=True)
2240        Plot.plot([LRAzim[0],LRAzim[1]],[IOtth[1],IOtth[1]],picker=True)
2241        if not Data['fullIntegrate']:
2242            Plot.plot([LRAzim[0],LRAzim[0]],[IOtth[0],IOtth[1]],picker=True)
2243            Plot.plot([LRAzim[1],LRAzim[1]],[IOtth[0],IOtth[1]],picker=True)
2244    if Data['setRings']:
2245        rings = np.concatenate((Data['rings']),axis=0)
2246        for xring,yring,dsp in rings:
2247            x,y = G2img.GetTthAzm(xring,yring,Data)
2248            Plot.plot(y,x,'r+')           
2249    if Data['ellipses']:           
2250        for ellipse in Data['ellipses']:
2251            ring = np.array(G2img.makeIdealRing(ellipse[:3])) #skip color
2252            x,y = np.hsplit(ring,2)
2253            tth,azm = G2img.GetTthAzm(x,y,Data)
2254            Plot.plot(azm,tth,'b,')
2255    if not newPlot:
2256        Page.toolbar.push_current()
2257        Plot.set_xlim(xylim[0])
2258        Plot.set_ylim(xylim[1])
2259        xylim = []
2260        Page.toolbar.push_current()
2261        Page.toolbar.draw()
2262    else:
2263        Page.canvas.draw()
2264       
2265################################################################################
2266##### PlotStructure
2267################################################################################
2268           
2269def PlotStructure(G2frame,data):
2270    '''Crystal structure plotting package. Can show structures as balls, sticks, lines,
2271    thermal motion ellipsoids and polyhedra
2272    '''
2273    ForthirdPI = 4.0*math.pi/3.0
2274    generalData = data['General']
2275    cell = generalData['Cell'][1:7]
2276    Vol = generalData['Cell'][7:8][0]
2277    Amat,Bmat = G2lat.cell2AB(cell)         #Amat - crystal to cartesian, Bmat - inverse
2278    A4mat = np.concatenate((np.concatenate((Amat,[[0],[0],[0]]),axis=1),[[0,0,0,1],]),axis=0)
2279    B4mat = np.concatenate((np.concatenate((Bmat,[[0],[0],[0]]),axis=1),[[0,0,0,1],]),axis=0)
2280    Mydir = generalData['Mydir']
2281    atomData = data['Atoms']
2282    mapPeaks = []
2283    if 'Map Peaks' in data:
2284        mapPeaks = data['Map Peaks']                       
2285    drawingData = data['Drawing']
2286    drawAtoms = drawingData['Atoms']
2287    mapData = {}
2288    rhoXYZ = []
2289    if 'Map' in generalData:
2290        mapData = generalData['Map']
2291    cx,ct,cs = drawingData['atomPtrs']
2292    Wt = np.array([255,255,255])
2293    Rd = np.array([255,0,0])
2294    Gr = np.array([0,255,0])
2295    Bl = np.array([0,0,255])
2296    uBox = np.array([[0,0,0],[1,0,0],[1,1,0],[0,1,0],[0,0,1],[1,0,1],[1,1,1],[0,1,1]])
2297    uEdges = np.array([
2298        [uBox[0],uBox[1]],[uBox[0],uBox[3]],[uBox[0],uBox[4]],[uBox[1],uBox[2]], 
2299        [uBox[2],uBox[3]],[uBox[1],uBox[5]],[uBox[2],uBox[6]],[uBox[3],uBox[7]], 
2300        [uBox[4],uBox[5]],[uBox[5],uBox[6]],[uBox[6],uBox[7]],[uBox[7],uBox[4]]])
2301    uColors = [Rd,Gr,Bl,Wt, Wt,Wt,Wt,Wt, Wt,Wt,Wt,Wt]
2302    altDown = False
2303    shiftDown = False
2304    ctrlDown = False
2305   
2306    def OnKeyBox(event):
2307        import Image
2308        Draw()                          #make sure plot is fresh!!
2309        mode = cb.GetValue()
2310        Fname = Mydir+'\\'+generalData['Name']+'.'+mode
2311        size = Page.canvas.GetSize()
2312        glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
2313        if mode in ['jpeg',]:
2314            Pix = glReadPixels(0,0,size[0],size[1],GL_RGBA, GL_UNSIGNED_BYTE)
2315            im = Image.new("RGBA", (size[0],size[1]))
2316        else:
2317            Pix = glReadPixels(0,0,size[0],size[1],GL_RGB, GL_UNSIGNED_BYTE)
2318            im = Image.new("RGB", (size[0],size[1]))
2319        im.fromstring(Pix)
2320        im.save(Fname,mode)
2321        cb.SetValue(' Save as:')
2322        G2frame.G2plotNB.status.SetStatusText('Drawing saved to: '+Fname,1)
2323   
2324    def GetTruePosition(xy,Add=False):
2325        View = glGetIntegerv(GL_VIEWPORT)
2326        Proj = glGetDoublev(GL_PROJECTION_MATRIX)
2327        Model = glGetDoublev(GL_MODELVIEW_MATRIX)
2328        Zmax = 1.
2329        if Add:
2330            Indx = GetSelectedAtoms()
2331        if G2frame.dataDisplay.GetPageText(getSelection()) == 'Map peaks':
2332            for i,peak in enumerate(mapPeaks):
2333                x,y,z = peak[1:]
2334                X,Y,Z = gluProject(x,y,z,Model,Proj,View)
2335                XY = [int(X),int(View[3]-Y)]
2336                if np.allclose(xy,XY,atol=10) and Z < Zmax:
2337                    Zmax = Z
2338                    try:
2339                        Indx.remove(i)
2340                        ClearSelectedAtoms()
2341                        for id in Indx:
2342                            SetSelectedAtoms(id,Add)
2343                    except:
2344                        SetSelectedAtoms(i,Add)
2345        else:
2346            for i,atom in enumerate(drawAtoms):
2347                x,y,z = atom[cx:cx+3]
2348                X,Y,Z = gluProject(x,y,z,Model,Proj,View)
2349                XY = [int(X),int(View[3]-Y)]
2350                if np.allclose(xy,XY,atol=10) and Z < Zmax:
2351                    Zmax = Z
2352                    try:
2353                        Indx.remove(i)
2354                        ClearSelectedAtoms()
2355                        for id in Indx:
2356                            SetSelectedAtoms(id,Add)
2357                    except:
2358                        SetSelectedAtoms(i,Add)
2359                                       
2360    def OnMouseDown(event):
2361        xy = event.GetPosition()
2362        if event.ShiftDown():
2363            if event.LeftIsDown():
2364                GetTruePosition(xy)
2365            elif event.RightIsDown():
2366                GetTruePosition(xy,True)
2367        else:
2368            drawingData['Rotation'][3] = list(xy)
2369        Draw()
2370       
2371    def OnMouseMove(event):
2372        if event.ShiftDown():
2373            return       
2374        newxy = event.GetPosition()
2375        page = getSelection()
2376        if event.ControlDown() and drawingData['showABC']:
2377            if event.LeftIsDown():
2378                SetTestRot(newxy)
2379            elif event.RightIsDown():
2380                SetTestPos(newxy)
2381            elif event.MiddleIsDown():
2382                SetTestRotZ(newxy)
2383            x,y,z = drawingData['testPos'][0]
2384            G2frame.G2plotNB.status.SetStatusText('moving test point %.4f,%.4f,%.4f'%(x,y,z),1)
2385            Draw()
2386                               
2387        if event.Dragging() and not event.ControlDown():
2388            if event.LeftIsDown():
2389                SetRotation(newxy)
2390                angX,angY,angZ = drawingData['Rotation'][:3]
2391                G2frame.G2plotNB.status.SetStatusText('New rotation: %.2f, %.2f ,%.2f'%(angX,angY,angZ),1)
2392            elif event.RightIsDown():
2393                SetTranslation(newxy)
2394                Tx,Ty,Tz = drawingData['viewPoint'][0]
2395                G2frame.G2plotNB.status.SetStatusText('New view point: %.4f, %.4f, %.4f'%(Tx,Ty,Tz),1)
2396            elif event.MiddleIsDown():
2397                SetRotationZ(newxy)
2398                angX,angY,angZ = drawingData['Rotation'][:3]
2399                G2frame.G2plotNB.status.SetStatusText('New rotation: %.2f, %.2f, %.2f'%(angX,angY,angZ),1)
2400            Draw()
2401       
2402    def OnMouseWheel(event):
2403        if event.ShiftDown():
2404            return
2405        drawingData['cameraPos'] += event.GetWheelRotation()/24
2406        drawingData['cameraPos'] = max(10,min(500,drawingData['cameraPos']))
2407        G2frame.G2plotNB.status.SetStatusText('New camera distance: %.2f'%(drawingData['cameraPos']),1)
2408        page = getSelection()
2409        if page:
2410            if G2frame.dataDisplay.GetPageText(page) == 'Draw Options':
2411                panel = G2frame.dataDisplay.GetPage(page).GetChildren()[0].GetChildren()
2412                names = [child.GetName() for child in panel]
2413                panel[names.index('cameraPos')].SetLabel('Camera Position: '+'%.2f'%(drawingData['cameraPos']))
2414                panel[names.index('cameraSlider')].SetValue(drawingData['cameraPos'])
2415            Draw()
2416       
2417    def getSelection():
2418        try:
2419            return G2frame.dataDisplay.GetSelection()
2420        except AttributeError:
2421            G2frame.G2plotNB.status.SetStatusText('Select this from Phase data window!')
2422            return 0
2423           
2424    def SetViewPointText(VP):
2425        page = getSelection()
2426        if page:
2427            if G2frame.dataDisplay.GetPageText(page) == 'Draw Options':
2428                panel = G2frame.dataDisplay.GetPage(page).GetChildren()[0].GetChildren()
2429                names = [child.GetName() for child in panel]
2430                panel[names.index('viewPoint')].SetValue('%.3f, %.3f, %.3f'%(VP[0],VP[1],VP[2]))
2431           
2432    def ClearSelectedAtoms():
2433        page = getSelection()
2434        if page:
2435            if G2frame.dataDisplay.GetPageText(page) == 'Draw Atoms':
2436                G2frame.dataDisplay.GetPage(page).ClearSelection()      #this is the Atoms grid in Draw Atoms
2437            elif G2frame.dataDisplay.GetPageText(page) == 'Map peaks':
2438                G2frame.dataDisplay.GetPage(page).ClearSelection()      #this is the Atoms grid in Atoms
2439            elif G2frame.dataDisplay.GetPageText(page) == 'Atoms':
2440                G2frame.dataDisplay.GetPage(page).ClearSelection()      #this is the Atoms grid in Atoms
2441               
2442                   
2443    def SetSelectedAtoms(ind,Add=False):
2444        page = getSelection()
2445        if page:
2446            if G2frame.dataDisplay.GetPageText(page) == 'Draw Atoms':
2447                G2frame.dataDisplay.GetPage(page).SelectRow(ind,Add)      #this is the Atoms grid in Draw Atoms
2448            elif G2frame.dataDisplay.GetPageText(page) == 'Map peaks':
2449                G2frame.dataDisplay.GetPage(page).SelectRow(ind,Add)                 
2450            elif G2frame.dataDisplay.GetPageText(page) == 'Atoms':
2451                Id = drawAtoms[ind][-2]
2452                for i,atom in enumerate(atomData):
2453                    if atom[-1] == Id:
2454                        G2frame.dataDisplay.GetPage(page).SelectRow(i)      #this is the Atoms grid in Atoms
2455                 
2456    def GetSelectedAtoms():
2457        page = getSelection()
2458        Ind = []
2459        if page:
2460            if G2frame.dataDisplay.GetPageText(page) == 'Draw Atoms':
2461                Ind = G2frame.dataDisplay.GetPage(page).GetSelectedRows()      #this is the Atoms grid in Draw Atoms
2462            elif G2frame.dataDisplay.GetPageText(page) == 'Map peaks':
2463                Ind = G2frame.dataDisplay.GetPage(page).GetSelectedRows()
2464            elif G2frame.dataDisplay.GetPageText(page) == 'Atoms':
2465                Ind = G2frame.dataDisplay.GetPage(page).GetSelectedRows()      #this is the Atoms grid in Atoms
2466        return Ind
2467                                       
2468    def OnKey(event):           #on key UP!!
2469        keyCode = event.GetKeyCode()
2470        if keyCode > 255:
2471            keyCode = 0
2472        key,xyz = chr(keyCode),event.GetPosition()
2473        indx = drawingData['selectedAtoms']
2474        if key in ['c','C']:
2475            drawingData['viewPoint'] = [[.5,.5,.5],[0,0]]
2476            drawingData['testPos'] = [[-.1,-.1,-.1],[0.0,0.0,0.0],[0,0]]
2477            drawingData['Rotation'] = [0.0,0.0,0.0,[]]
2478            SetViewPointText(drawingData['viewPoint'][0])
2479        elif key in ['n','N']:
2480            drawAtoms = drawingData['Atoms']
2481            pI = drawingData['viewPoint'][1]
2482            if indx:
2483                pI[0] = indx[pI[1]]
2484                Tx,Ty,Tz = drawAtoms[pI[0]][cx:cx+3]
2485                pI[1] += 1
2486                if pI[1] >= len(indx):
2487                    pI[1] = 0
2488            else:
2489                Tx,Ty,Tz = drawAtoms[pI[0]][cx:cx+3]               
2490                pI[0] += 1
2491                if pI[0] >= len(drawAtoms):
2492                    pI[0] = 0
2493            drawingData['viewPoint'] = [[Tx,Ty,Tz],pI]
2494            SetViewPointText(drawingData['viewPoint'][0])
2495            G2frame.G2plotNB.status.SetStatusText('View point at atom '+drawAtoms[pI[0]][ct-1]+str(pI),1)
2496               
2497        elif key in ['p','P']:
2498            drawAtoms = drawingData['Atoms']
2499            pI = drawingData['viewPoint'][1]
2500            if indx:
2501                pI[0] = indx[pI[1]]
2502                Tx,Ty,Tz = drawAtoms[pI[0]][cx:cx+3]
2503                pI[1] -= 1
2504                if pI[1] < 0:
2505                    pI[1] = len(indx)-1
2506            else:
2507                Tx,Ty,Tz = drawAtoms[pI[0]][cx:cx+3]               
2508                pI[0] -= 1
2509                if pI[0] < 0:
2510                    pI[0] = len(drawAtoms)-1
2511            drawingData['viewPoint'] = [[Tx,Ty,Tz],pI]
2512            SetViewPointText(drawingData['viewPoint'][0])           
2513            G2frame.G2plotNB.status.SetStatusText('View point at atom '+drawAtoms[pI[0]][ct-1]+str(pI),1)
2514        Draw()
2515           
2516    def SetBackground():
2517        R,G,B,A = Page.camera['backColor']
2518        glClearColor(R,G,B,A)
2519        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
2520       
2521    def SetLights():
2522        glEnable(GL_DEPTH_TEST)
2523        glShadeModel(GL_SMOOTH)
2524        glEnable(GL_LIGHTING)
2525        glEnable(GL_LIGHT0)
2526        glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,0)
2527        glLightfv(GL_LIGHT0,GL_AMBIENT,[1,1,1,.8])
2528        glLightfv(GL_LIGHT0,GL_DIFFUSE,[1,1,1,1])
2529       
2530    def SetTranslation(newxy):
2531        Tx,Ty,Tz = drawingData['viewPoint'][0]
2532        anglex,angley,anglez,oldxy = drawingData['Rotation']
2533        if not len(oldxy): oldxy = list(newxy)
2534        Rx = G2lat.rotdMat(anglex,0)
2535        Ry = G2lat.rotdMat(angley,1)
2536        Rz = G2lat.rotdMat(anglez,2)
2537        dxy = list(newxy-oldxy)+[0,]
2538        dxy = np.inner(Bmat,np.inner(Rz,np.inner(Ry,np.inner(Rx,dxy))))
2539        Tx -= dxy[0]*0.01
2540        Ty += dxy[1]*0.01
2541        Tz -= dxy[2]*0.01
2542        drawingData['Rotation'][3] = list(newxy)
2543        drawingData['viewPoint'][0] =  Tx,Ty,Tz
2544        SetViewPointText([Tx,Ty,Tz])
2545       
2546    def SetTestPos(newxy):
2547        Tx,Ty,Tz = drawingData['testPos'][0]
2548        anglex,angley,anglez,oldxy = drawingData['Rotation']
2549        if not len(oldxy): oldxy = list(newxy)
2550        Rx = G2lat.rotdMat(anglex,0)
2551        Ry = G2lat.rotdMat(angley,1)
2552        Rz = G2lat.rotdMat(anglez,2)
2553        dxy = list(newxy-oldxy)+[0,]
2554        dxy = np.inner(Rz,np.inner(Ry,np.inner(Rx,dxy)))
2555        Tx += dxy[0]*0.001
2556        Ty -= dxy[1]*0.001
2557        Tz += dxy[2]*0.001
2558        drawingData['Rotation'][3] = list(newxy)
2559        drawingData['testPos'][0] =  Tx,Ty,Tz
2560       
2561    def SetTestRot(newxy):
2562        Txyz = np.array(drawingData['testPos'][0])
2563        oldxy = drawingData['testPos'][2]
2564        Ax,Ay,Az = drawingData['testPos'][1]
2565        Vxyz = np.array(drawingData['viewPoint'][0])
2566        Dxyz = np.inner(Amat,Txyz-Vxyz)
2567        dxy = list(newxy-oldxy)+[0,]
2568        Ax += dxy[1]*0.01
2569        Ay += dxy[0]*0.01
2570        Rx = G2lat.rotdMat(Ax,0)
2571        Ry = G2lat.rotdMat(Ay,1)
2572        Dxyz = np.inner(Ry,np.inner(Rx,Dxyz))       
2573        Dxyz = np.inner(Bmat,Dxyz)+Vxyz
2574        drawingData['testPos'][1] = [Ax,Ay,Az]
2575        drawingData['testPos'][2] = newxy
2576        drawingData['testPos'][0] = Dxyz
2577       
2578    def SetTestRotZ(newxy):
2579        Txyz = np.array(drawingData['testPos'][0])
2580        oldxy = drawingData['testPos'][2]
2581        Ax,Ay,Az = drawingData['testPos'][1]
2582        Vxyz = np.array(drawingData['viewPoint'][0])
2583        Dxyz = np.inner(Amat,Txyz-Vxyz)       
2584        dxy = list(newxy-oldxy)+[0,]
2585        Az += (dxy[0]+dxy[1])*.01
2586        Rz = G2lat.rotdMat(Az,2)
2587        Dxyz = np.inner(Rz,Dxyz)       
2588        Dxyz = np.inner(Bmat,Dxyz)+Vxyz
2589        drawingData['testPos'][1] = [Ax,Ay,Az]
2590        drawingData['testPos'][2] = newxy
2591        drawingData['testPos'][0] = Dxyz
2592                             
2593    def SetRotation(newxy):       
2594        anglex,angley,anglez,oldxy = drawingData['Rotation']
2595        if not len(oldxy): oldxy = list(newxy)
2596        dxy = newxy-oldxy
2597        anglex += dxy[1]*.25
2598        angley += dxy[0]*.25
2599        oldxy = newxy
2600        drawingData['Rotation'] = [anglex,angley,anglez,list(oldxy)]
2601       
2602    def SetRotationZ(newxy):                       
2603        anglex,angley,anglez,oldxy = drawingData['Rotation']
2604        if not len(oldxy): oldxy = list(newxy)
2605        dxy = newxy-oldxy
2606        anglez += (dxy[0]+dxy[1])*.25
2607        oldxy = newxy
2608        drawingData['Rotation'] = [anglex,angley,anglez,list(oldxy)]
2609       
2610    def RenderBox():
2611        glEnable(GL_COLOR_MATERIAL)
2612        glLineWidth(2)
2613        glEnable(GL_BLEND)
2614        glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA)
2615        glEnable(GL_LINE_SMOOTH)
2616        glBegin(GL_LINES)
2617        for line,color in zip(uEdges,uColors):
2618            glColor3ubv(color)
2619            glVertex3fv(line[0])
2620            glVertex3fv(line[1])
2621        glEnd()
2622        glColor4ubv([0,0,0,0])
2623        glDisable(GL_LINE_SMOOTH)
2624        glDisable(GL_BLEND)
2625        glDisable(GL_COLOR_MATERIAL)
2626       
2627    def RenderUnitVectors(x,y,z):
2628        xyz = np.array([x,y,z])
2629        glEnable(GL_COLOR_MATERIAL)
2630        glLineWidth(1)
2631        glPushMatrix()
2632        glTranslate(x,y,z)
2633        glScalef(1/cell[0],1/cell[1],1/cell[2])
2634        glBegin(GL_LINES)
2635        for line,color in zip(uEdges,uColors)[:3]:
2636            glColor3ubv(color)
2637            glVertex3fv(line[0])
2638            glVertex3fv(line[1])
2639        glEnd()
2640        glPopMatrix()
2641        glColor4ubv([0,0,0,0])
2642        glDisable(GL_COLOR_MATERIAL)
2643               
2644    def RenderSphere(x,y,z,radius,color):
2645        glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,color)
2646        glPushMatrix()
2647        glTranslate(x,y,z)
2648        glMultMatrixf(B4mat.T)
2649        q = gluNewQuadric()
2650        gluSphere(q,radius,20,10)
2651        glPopMatrix()
2652       
2653    def RenderSmallSphere(x,y,z,radius,color):
2654        glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,color)
2655        glPushMatrix()
2656        glTranslate(x,y,z)
2657        glMultMatrixf(B4mat.T)
2658        q = gluNewQuadric()
2659        gluSphere(q,radius,4,2)
2660        glPopMatrix()
2661       
2662    def RenderEllipsoid(x,y,z,ellipseProb,E,R4,color):
2663        s1,s2,s3 = E
2664        glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,color)
2665        glPushMatrix()
2666        glTranslate(x,y,z)
2667        glMultMatrixf(B4mat.T)
2668        glMultMatrixf(R4.T)
2669        glEnable(GL_NORMALIZE)
2670        glScale(s1,s2,s3)
2671        q = gluNewQuadric()
2672        gluSphere(q,ellipseProb,20,10)
2673        glDisable(GL_NORMALIZE)
2674        glPopMatrix()
2675       
2676    def RenderBonds(x,y,z,Bonds,radius,color,slice=20):
2677        glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,color)
2678        glPushMatrix()
2679        glTranslate(x,y,z)
2680        glMultMatrixf(B4mat.T)
2681        for bond in Bonds:
2682            glPushMatrix()
2683            Dx = np.inner(Amat,bond)
2684            Z = np.sqrt(np.sum(Dx**2))
2685            if Z:
2686                azm = atan2d(-Dx[1],-Dx[0])
2687                phi = acosd(Dx[2]/Z)
2688                glRotate(-azm,0,0,1)
2689                glRotate(phi,1,0,0)
2690                q = gluNewQuadric()
2691                gluCylinder(q,radius,radius,Z,slice,2)
2692            glPopMatrix()           
2693        glPopMatrix()
2694               
2695    def RenderLines(x,y,z,Bonds,color):
2696        xyz = np.array([x,y,z])
2697        glEnable(GL_COLOR_MATERIAL)
2698        glLineWidth(1)
2699        glColor3fv(color)
2700        glPushMatrix()
2701        glBegin(GL_LINES)
2702        for bond in Bonds:
2703            glVertex3fv(xyz)
2704            glVertex3fv(xyz+bond)
2705        glEnd()
2706        glColor4ubv([0,0,0,0])
2707        glPopMatrix()
2708        glDisable(GL_COLOR_MATERIAL)
2709       
2710    def RenderPolyhedra(x,y,z,Faces,color):
2711        glPushMatrix()
2712        glTranslate(x,y,z)
2713        glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,color)
2714        glShadeModel(GL_SMOOTH)
2715        glMultMatrixf(B4mat.T)
2716        for face,norm in Faces:
2717            glPolygonMode(GL_FRONT_AND_BACK,GL_FILL)
2718            glFrontFace(GL_CW)
2719            glNormal3fv(norm)
2720            glBegin(GL_TRIANGLES)
2721            for vert in face:
2722                glVertex3fv(vert)
2723            glEnd()
2724        glPopMatrix()
2725
2726    def RenderMapPeak(x,y,z,color):
2727        vecs = np.array([[[-.01,0,0],[.01,0,0]],[[0,-.01,0],[0,.01,0]],[[0,0,-.01],[0,0,.01]]])
2728        xyz = np.array([x,y,z])
2729        glEnable(GL_COLOR_MATERIAL)
2730        glLineWidth(3)
2731        glColor3fv(color)
2732        glPushMatrix()
2733        glBegin(GL_LINES)
2734        for vec in vecs:
2735            glVertex3fv(vec[0]+xyz)
2736            glVertex3fv(vec[1]+xyz)
2737        glEnd()
2738        glColor4ubv([0,0,0,0])
2739        glPopMatrix()
2740        glDisable(GL_COLOR_MATERIAL)
2741       
2742    def RenderBackbone(Backbone,BackboneColor,radius):
2743        glPushMatrix()
2744        glMultMatrixf(B4mat.T)
2745        glEnable(GL_COLOR_MATERIAL)
2746        glShadeModel(GL_SMOOTH)
2747        gleSetJoinStyle(TUBE_NORM_EDGE | TUBE_JN_ANGLE | TUBE_JN_CAP)
2748        glePolyCylinder(Backbone,BackboneColor,radius)
2749        glPopMatrix()       
2750        glDisable(GL_COLOR_MATERIAL)
2751       
2752    def RenderLabel(x,y,z,label,r):       
2753        glPushMatrix()
2754        glTranslate(x,y,z)
2755        glMultMatrixf(B4mat.T)
2756        glDisable(GL_LIGHTING)
2757        glColor3f(0,1.,0)
2758        glRasterPos3f(r,r,r)
2759        for c in list(label):
2760            glutBitmapCharacter(GLUT_BITMAP_8_BY_13,ord(c))
2761        glEnable(GL_LIGHTING)
2762        glPopMatrix()
2763       
2764    def RenderMap(rho,rhoXYZ,indx,Rok):
2765        cLevel = drawingData['contourLevel']
2766        for i,xyz in enumerate(rhoXYZ):
2767            if not Rok[i]:
2768                x,y,z = xyz
2769                I,J,K = indx[i]
2770                alpha = 1.0
2771                if cLevel < 1.:
2772                    alpha = (abs(rho[I,J,K])/mapData['rhoMax']-cLevel)/(1.-cLevel)
2773                if rho[I,J,K] < 0.:
2774                    RenderSmallSphere(x,y,z,0.1*alpha,Rd)
2775                else:
2776                    RenderSmallSphere(x,y,z,0.1*alpha,Bl)
2777                           
2778    def Draw():
2779        mapData = generalData['Map']
2780        pageName = ''
2781        page = getSelection()
2782        if page:
2783            pageName = G2frame.dataDisplay.GetPageText(page)
2784        rhoXYZ = []
2785        if len(mapData['rho']):
2786            VP = np.array(drawingData['viewPoint'][0])-np.array([.5,.5,.5])
2787            contLevel = drawingData['contourLevel']*mapData['rhoMax']
2788            if 'delt-F' in mapData['MapType']:
2789                rho = ma.array(mapData['rho'],mask=(np.abs(mapData['rho'])<contLevel))
2790            else:
2791                rho = ma.array(mapData['rho'],mask=(mapData['rho']<contLevel))
2792            steps = 1./np.array(rho.shape)
2793            incre = np.where(VP>0,VP%steps,VP%steps-steps)
2794            Vsteps = -np.array(VP/steps,dtype='i')
2795            rho = np.roll(np.roll(np.roll(rho,Vsteps[0],axis=0),Vsteps[1],axis=1),Vsteps[2],axis=2)
2796            indx = np.array(ma.nonzero(rho)).T
2797            rhoXYZ = indx*steps+VP-incre
2798            Nc = len(rhoXYZ)
2799            rcube = 2000.*Vol/(ForthirdPI*Nc)
2800            rmax = math.exp(math.log(rcube)/3.)**2
2801            radius = min(drawingData['mapSize']**2,rmax)
2802            view = np.array(drawingData['viewPoint'][0])
2803            Rok = np.sum(np.inner(Amat,rhoXYZ-view).T**2,axis=1)>radius
2804        Ind = GetSelectedAtoms()
2805        VS = np.array(Page.canvas.GetSize())
2806        aspect = float(VS[0])/float(VS[1])
2807        cPos = drawingData['cameraPos']
2808        Zclip = drawingData['Zclip']*cPos/200.
2809        anglex,angley,anglez = drawingData['Rotation'][:3]
2810        Tx,Ty,Tz = drawingData['viewPoint'][0]
2811        cx,ct,cs = drawingData['atomPtrs']
2812        bondR = drawingData['bondRadius']
2813        G,g = G2lat.cell2Gmat(cell)
2814        GS = G
2815        GS[0][1] = GS[1][0] = math.sqrt(GS[0][0]*GS[1][1])
2816        GS[0][2] = GS[2][0] = math.sqrt(GS[0][0]*GS[2][2])
2817        GS[1][2] = GS[2][1] = math.sqrt(GS[1][1]*GS[2][2])
2818        ellipseProb = G2lat.criticalEllipse(drawingData['ellipseProb']/100.)
2819       
2820        SetBackground()
2821        glInitNames()
2822        glPushName(0)
2823       
2824        glMatrixMode(GL_PROJECTION)
2825        glLoadIdentity()
2826        glViewport(0,0,VS[0],VS[1])
2827        gluPerspective(20.,aspect,cPos-Zclip,cPos+Zclip)
2828        gluLookAt(0,0,cPos,0,0,0,0,1,0)
2829        SetLights()           
2830           
2831        glMatrixMode(GL_MODELVIEW)
2832        glLoadIdentity()
2833        glRotate(anglez,0,0,1)
2834        glRotate(anglex,cosd(anglez),-sind(anglez),0)
2835        glRotate(angley,sind(anglez),cosd(anglez),0)
2836        glMultMatrixf(A4mat.T)
2837        glTranslate(-Tx,-Ty,-Tz)
2838        if drawingData['unitCellBox']:
2839            RenderBox()
2840        if drawingData['showABC']:
2841            x,y,z = drawingData['testPos'][0]
2842#            if altDown:
2843#                G2frame.G2plotNB.status.SetStatusText('moving test point %.4f,%.4f,%.4f'%(x,y,z),1)
2844#            else:
2845#                G2frame.G2plotNB.status.SetStatusText('test point %.4f,%.4f,%.4f'%(x,y,z),1)           
2846            RenderUnitVectors(x,y,z)
2847        Backbone = []
2848        BackboneColor = []
2849        time0 = time.time()
2850#        glEnable(GL_BLEND)
2851#        glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA)
2852        for iat,atom in enumerate(drawingData['Atoms']):
2853            x,y,z = atom[cx:cx+3]
2854            Bonds = atom[-2]
2855            Faces = atom[-1]
2856            try:
2857                atNum = generalData['AtomTypes'].index(atom[ct])
2858            except ValueError:
2859                atNum = -1
2860            CL = atom[cs+2]
2861            color = np.array(CL)/255.
2862            if iat in Ind and G2frame.dataDisplay.GetPageText(getSelection()) != 'Map peaks':
2863                color = np.array(Gr)/255.
2864#            color += [.25,]
2865            radius = 0.5
2866            if atom[cs] != '':
2867                try:
2868                    glLoadName(atom[-3])
2869                except: #problem with old files - missing code
2870                    pass                   
2871            if 'balls' in atom[cs]:
2872                vdwScale = drawingData['vdwScale']
2873                ballScale = drawingData['ballScale']
2874                if atNum < 0:
2875                    radius = 0.2
2876                elif 'H' == atom[ct]:
2877                    if drawingData['showHydrogen']:
2878                        if 'vdW' in atom[cs] and atNum >= 0:
2879                            radius = vdwScale*generalData['vdWRadii'][atNum]
2880                        else:
2881                            radius = ballScale*drawingData['sizeH']
2882                    else:
2883                        radius = 0.0
2884                else:
2885                    if 'vdW' in atom[cs]:
2886                        radius = vdwScale*generalData['vdWRadii'][atNum]
2887                    else:
2888                        radius = ballScale*generalData['BondRadii'][atNum]
2889                RenderSphere(x,y,z,radius,color)
2890                if 'sticks' in atom[cs]:
2891                    RenderBonds(x,y,z,Bonds,bondR,color)
2892            elif 'ellipsoids' in atom[cs]:
2893                RenderBonds(x,y,z,Bonds,bondR,color)
2894                if atom[cs+3] == 'A':                   
2895                    Uij = atom[cs+5:cs+11]
2896                    U = np.multiply(G2spc.Uij2U(Uij),GS)
2897                    U = np.inner(Amat,np.inner(U,Amat).T)
2898                    E,R = nl.eigh(U)
2899                    R4 = np.concatenate((np.concatenate((R,[[0],[0],[0]]),axis=1),[[0,0,0,1],]),axis=0)
2900                    E = np.sqrt(E)
2901                    if atom[ct] == 'H' and not drawingData['showHydrogen']:
2902                        pass
2903                    else:
2904                        RenderEllipsoid(x,y,z,ellipseProb,E,R4,color)                   
2905                else:
2906                    if atom[ct] == 'H' and not drawingData['showHydrogen']:
2907                        pass
2908                    else:
2909                        radius = ellipseProb*math.sqrt(abs(atom[cs+4]))
2910                        RenderSphere(x,y,z,radius,color)
2911            elif 'lines' in atom[cs]:
2912                radius = 0.1
2913                RenderLines(x,y,z,Bonds,color)
2914#                RenderBonds(x,y,z,Bonds,0.05,color,6)
2915            elif atom[cs] == 'sticks':
2916                radius = 0.1
2917                RenderBonds(x,y,z,Bonds,bondR,color)
2918            elif atom[cs] == 'polyhedra':
2919                RenderPolyhedra(x,y,z,Faces,color)
2920            elif atom[cs] == 'backbone':
2921                if atom[ct-1].split()[0] in ['C','N']:
2922                    Backbone.append(list(np.inner(Amat,np.array([x,y,z]))))
2923                    BackboneColor.append(list(color))
2924                   
2925            if atom[cs+1] == 'type':
2926                RenderLabel(x,y,z,atom[ct],radius)
2927            elif atom[cs+1] == 'name':
2928                RenderLabel(x,y,z,atom[ct-1],radius)
2929            elif atom[cs+1] == 'number':
2930                RenderLabel(x,y,z,str(iat),radius)
2931            elif atom[cs+1] == 'residue' and atom[ct-1] == 'CA':
2932                RenderLabel(x,y,z,atom[ct-4],radius)
2933            elif atom[cs+1] == '1-letter' and atom[ct-1] == 'CA':
2934                RenderLabel(x,y,z,atom[ct-3],radius)
2935            elif atom[cs+1] == 'chain' and atom[ct-1] == 'CA':
2936                RenderLabel(x,y,z,atom[ct-2],radius)
2937#        glDisable(GL_BLEND)
2938        if len(rhoXYZ):
2939            RenderMap(rho,rhoXYZ,indx,Rok)
2940        if len(mapPeaks):
2941            for ind,[mag,x,y,z] in enumerate(mapPeaks):
2942                if ind in Ind and pageName == 'Map peaks':
2943                    RenderMapPeak(x,y,z,Gr)
2944                else:
2945                    RenderMapPeak(x,y,z,Wt)
2946        if Backbone:
2947            RenderBackbone(Backbone,BackboneColor,bondR)
2948#        print time.time()-time0
2949        Page.canvas.SwapBuffers()
2950       
2951    def OnSize(event):
2952        Draw()
2953       
2954    def OnFocus(event):
2955        Draw()
2956       
2957    try:
2958        plotNum = G2frame.G2plotNB.plotList.index(generalData['Name'])
2959        Page = G2frame.G2plotNB.nb.GetPage(plotNum)       
2960    except ValueError:
2961        Plot = G2frame.G2plotNB.addOgl(generalData['Name'])
2962        plotNum = G2frame.G2plotNB.plotList.index(generalData['Name'])
2963        Page = G2frame.G2plotNB.nb.GetPage(plotNum)
2964        Page.views = False
2965        view = False
2966        altDown = False
2967    Page.SetFocus()
2968    cb = wx.ComboBox(G2frame.G2plotNB.status,style=wx.CB_DROPDOWN|wx.CB_READONLY,
2969        choices=(' save as:','jpeg','tiff','bmp'))
2970    cb.Bind(wx.EVT_COMBOBOX, OnKeyBox)
2971    cb.SetValue(' save as:')
2972    Page.canvas.Bind(wx.EVT_MOUSEWHEEL, OnMouseWheel)
2973    Page.canvas.Bind(wx.EVT_LEFT_DOWN, OnMouseDown)
2974    Page.canvas.Bind(wx.EVT_RIGHT_DOWN, OnMouseDown)
2975    Page.canvas.Bind(wx.EVT_MIDDLE_DOWN, OnMouseDown)
2976    Page.canvas.Bind(wx.EVT_KEY_UP, OnKey)
2977    Page.canvas.Bind(wx.EVT_MOTION, OnMouseMove)
2978    Page.canvas.Bind(wx.EVT_SIZE, OnSize)
2979    Page.canvas.Bind(wx.EVT_SET_FOCUS, OnFocus)
2980    Page.camera['position'] = drawingData['cameraPos']
2981    Page.camera['viewPoint'] = np.inner(Amat,drawingData['viewPoint'][0])
2982    Page.camera['backColor'] = np.array(list(drawingData['backColor'])+[0,])/255.
2983    Page.canvas.SetCurrent()
2984    Draw()
2985       
Note: See TracBrowser for help on using the repository browser.