source: trunk/GSASIIplot.py @ 573

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

add 'None' as one of the phase data plot options
trap failed charge flipping errors
add atom modify commands
add a new class - SingleFloatDialog? to GSASIIphsGUI.py
can now roll in place charge flip maps with u,d,l,r keys

  • Property svn:keywords set to Date Author Revision URL Id
File size: 129.7 KB
Line 
1#GSASII plotting routines
2########### SVN repository information ###################
3# $Date: 2012-04-25 16:54:23 +0000 (Wed, 25 Apr 2012) $
4# $Author: vondreele $
5# $Revision: 573 $
6# $URL: trunk/GSASIIplot.py $
7# $Id: GSASIIplot.py 573 2012-04-25 16:54:23Z 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    if plotType in ['None']:
1276        return       
1277
1278    for item in useList:
1279        if useList[item]['Show']:
1280            break
1281    else:
1282        return            #nothing to show!!
1283   
1284    numPlots = len(useList)
1285
1286    if plotType in ['Mustrain','Size']:
1287        Plot = mp3d.Axes3D(G2frame.G2plotNB.add3D(plotType))
1288    else:
1289        Plot = G2frame.G2plotNB.addMpl(plotType).gca()       
1290    plotNum = G2frame.G2plotNB.plotList.index(plotType)
1291    Page = G2frame.G2plotNB.nb.GetPage(plotNum)
1292    Page.SetFocus()
1293    G2frame.G2plotNB.status.SetStatusText('',1)
1294    if not Page.IsShown():
1295        Page.Show()
1296   
1297    for item in useList:
1298        if useList[item]['Show']:
1299            PHI = np.linspace(0.,360.,30,True)
1300            PSI = np.linspace(0.,180.,30,True)
1301            X = np.outer(npsind(PHI),npsind(PSI))
1302            Y = np.outer(npcosd(PHI),npsind(PSI))
1303            Z = np.outer(np.ones(np.size(PHI)),npcosd(PSI))
1304            try:        #temp patch instead of 'mustrain' for old files with 'microstrain'
1305                coeff = useList[item][plotDict[plotType]]
1306            except KeyError:
1307                break
1308            if plotType in ['Mustrain','Size']:
1309                if coeff[0] == 'isotropic':
1310                    X *= coeff[1][0]
1311                    Y *= coeff[1][0]
1312                    Z *= coeff[1][0]                               
1313                elif coeff[0] == 'uniaxial':
1314                   
1315                    def uniaxCalc(xyz,iso,aniso,axes):
1316                        Z = np.array(axes)
1317                        cp = abs(np.dot(xyz,Z))
1318                        sp = np.sqrt(1.-cp**2)
1319                        R = iso*aniso/np.sqrt((iso*cp)**2+(aniso*sp)**2)
1320                        return R*xyz
1321                       
1322                    iso,aniso = coeff[1][:2]
1323                    axes = np.inner(A,np.array(coeff[3]))
1324                    axes /= nl.norm(axes)
1325                    Shkl = np.array(coeff[1])
1326                    XYZ = np.dstack((X,Y,Z))
1327                    XYZ = np.nan_to_num(np.apply_along_axis(uniaxCalc,2,XYZ,iso,aniso,axes))
1328                    X,Y,Z = np.dsplit(XYZ,3)
1329                    X = X[:,:,0]
1330                    Y = Y[:,:,0]
1331                    Z = Z[:,:,0]
1332               
1333                elif coeff[0] == 'ellipsoidal':
1334                   
1335                    def ellipseCalc(xyz,E,R):
1336                        XYZ = xyz*E.T
1337                        return np.inner(XYZ.T,R)
1338                       
1339                    S6 = coeff[4]
1340                    Sij = G2lat.U6toUij(S6)
1341                    E,R = nl.eigh(Sij)
1342                    XYZ = np.dstack((X,Y,Z))
1343                    XYZ = np.nan_to_num(np.apply_along_axis(ellipseCalc,2,XYZ,E,R))
1344                    X,Y,Z = np.dsplit(XYZ,3)
1345                    X = X[:,:,0]
1346                    Y = Y[:,:,0]
1347                    Z = Z[:,:,0]
1348                   
1349                elif coeff[0] == 'generalized':
1350                   
1351                    def genMustrain(xyz,SGData,A,Shkl):
1352                        uvw = np.inner(A.T,xyz)
1353                        Strm = np.array(G2spc.MustrainCoeff(uvw,SGData))
1354                        sum = np.sum(np.multiply(Shkl,Strm))
1355                        sum = np.where(sum > 0.01,sum,0.01)
1356                        sum = np.sqrt(sum)*math.pi/0.018      #centidegrees to radians!
1357                        return sum*xyz
1358                       
1359                    Shkl = np.array(coeff[4])
1360                    if np.any(Shkl):
1361                        XYZ = np.dstack((X,Y,Z))
1362                        XYZ = np.nan_to_num(np.apply_along_axis(genMustrain,2,XYZ,SGData,A,Shkl))
1363                        X,Y,Z = np.dsplit(XYZ,3)
1364                        X = X[:,:,0]
1365                        Y = Y[:,:,0]
1366                        Z = Z[:,:,0]
1367                           
1368                if np.any(X) and np.any(Y) and np.any(Z):
1369                    errFlags = np.seterr(all='ignore')
1370                    Plot.plot_surface(X,Y,Z,rstride=1,cstride=1,color='g',linewidth=1)
1371                    np.seterr(all='ignore')
1372                    xyzlim = np.array([Plot.get_xlim3d(),Plot.get_ylim3d(),Plot.get_zlim3d()]).T
1373                    XYZlim = [min(xyzlim[0]),max(xyzlim[1])]
1374                    Plot.set_xlim3d(XYZlim)
1375                    Plot.set_ylim3d(XYZlim)
1376                    Plot.set_zlim3d(XYZlim)
1377                    Plot.set_aspect('equal')
1378                if plotType == 'Size':
1379                    Plot.set_title('Crystallite size for '+phase+'\n'+coeff[0]+' model')
1380                    Plot.set_xlabel(r'X, $\mu$m')
1381                    Plot.set_ylabel(r'Y, $\mu$m')
1382                    Plot.set_zlabel(r'Z, $\mu$m')
1383                else:   
1384                    Plot.set_title(r'$\mu$strain for '+phase+'\n'+coeff[0]+' model')
1385                    Plot.set_xlabel(r'X, $\mu$strain')
1386                    Plot.set_ylabel(r'Y, $\mu$strain')
1387                    Plot.set_zlabel(r'Z, $\mu$strain')
1388            else:
1389                h,k,l = generalData['POhkl']
1390                if coeff[0] == 'MD':
1391                    print 'March-Dollase preferred orientation plot'
1392               
1393                else:
1394                    PH = np.array(generalData['POhkl'])
1395                    phi,beta = G2lat.CrsAng(PH,cell[:6],SGData)
1396                    SHCoef = {}
1397                    for item in coeff[5]:
1398                        L,N = eval(item.strip('C'))
1399                        SHCoef['C%d,0,%d'%(L,N)] = coeff[5][item]                       
1400                    ODFln = G2lat.Flnh(Start,SHCoef,phi,beta,SGData)
1401                    X = np.linspace(0,90.0,26)
1402                    Y = G2lat.polfcal(ODFln,'0',X,0.0)
1403                    Plot.plot(X,Y,color='k',label=str(PH))
1404                    Plot.legend(loc='best')
1405                    Plot.set_title('Axial distribution for HKL='+str(PH)+' in '+phase)
1406                    Plot.set_xlabel(r'$\psi$',fontsize=16)
1407                    Plot.set_ylabel('MRD',fontsize=14)
1408    Page.canvas.draw()
1409   
1410################################################################################
1411##### PlotTexture
1412################################################################################
1413           
1414def PlotTexture(G2frame,data,newPlot=False,Start=False):
1415    '''Pole figure, inverse pole figure, 3D pole distribution and 3D inverse pole distribution
1416    plotting.
1417    dict generalData contains all phase info needed which is in data
1418    '''
1419
1420    shModels = ['cylindrical','none','shear - 2/m','rolling - mmm']
1421    SamSym = dict(zip(shModels,['0','-1','2/m','mmm']))
1422    PatternId = G2frame.PatternId
1423    generalData = data['General']
1424    SGData = generalData['SGData']
1425    textureData = generalData['SH Texture']
1426    G2frame.G2plotNB.Delete('Texture')
1427    if not textureData['Order']:
1428        return                  #no plot!!
1429    SHData = generalData['SH Texture']
1430    SHCoef = SHData['SH Coeff'][1]
1431    cell = generalData['Cell'][1:7]
1432    Amat,Bmat = G2lat.cell2AB(cell)
1433    sq2 = 1.0/math.sqrt(2.0)
1434   
1435    def rp2xyz(r,p):
1436        z = npcosd(r)
1437        xy = np.sqrt(1.-z**2)
1438        return xy*npsind(p),xy*npcosd(p),z
1439           
1440    def OnMotion(event):
1441        SHData = data['General']['SH Texture']
1442        if event.xdata and event.ydata:                 #avoid out of frame errors
1443            xpos = event.xdata
1444            ypos = event.ydata
1445            if 'Inverse' in SHData['PlotType']:
1446                r = xpos**2+ypos**2
1447                if r <= 1.0:
1448                    if 'equal' in G2frame.Projection: 
1449                        r,p = 2.*npasind(np.sqrt(r)*sq2),npatan2d(ypos,xpos)
1450                    else:
1451                        r,p = 2.*npatand(np.sqrt(r)),npatan2d(ypos,xpos)
1452                    ipf = G2lat.invpolfcal(IODFln,SGData,np.array([r,]),np.array([p,]))
1453                    xyz = np.inner(Amat.T,np.array([rp2xyz(r,p)]))
1454                    y,x,z = list(xyz/np.max(np.abs(xyz)))
1455                   
1456                    G2frame.G2plotNB.status.SetFields(['',
1457                        'psi =%9.3f, beta =%9.3f, MRD =%9.3f hkl=%5.2f,%5.2f,%5.2f'%(r,p,ipf,x,y,z)])
1458                                   
1459            elif 'Axial' in SHData['PlotType']:
1460                pass
1461               
1462            else:                       #ordinary pole figure
1463                z = xpos**2+ypos**2
1464                if z <= 1.0:
1465                    z = np.sqrt(z)
1466                    if 'equal' in G2frame.Projection: 
1467                        r,p = 2.*npasind(z*sq2),npatan2d(ypos,xpos)
1468                    else:
1469                        r,p = 2.*npatand(z),npatan2d(ypos,xpos)
1470                    pf = G2lat.polfcal(ODFln,SamSym[textureData['Model']],np.array([r,]),np.array([p,]))
1471                    G2frame.G2plotNB.status.SetFields(['','phi =%9.3f, gam =%9.3f, MRD =%9.3f'%(r,p,pf)])
1472   
1473    if G2frame.Projection == '3D display' and 'Axial'  not in SHData['PlotType']:               
1474        Plot = mp3d.Axes3D(G2frame.G2plotNB.add3D('Texture'))
1475    else:
1476        Plot = G2frame.G2plotNB.addMpl('Texture').gca()
1477    plotNum = G2frame.G2plotNB.plotList.index('Texture')
1478    Page = G2frame.G2plotNB.nb.GetPage(plotNum)
1479    if G2frame.Projection == '3D display':
1480        pass
1481    else:
1482        Page.canvas.mpl_connect('motion_notify_event', OnMotion)
1483
1484    Page.SetFocus()
1485    G2frame.G2plotNB.status.SetFields(['',''])   
1486    PH = np.array(SHData['PFhkl'])
1487    phi,beta = G2lat.CrsAng(PH,cell,SGData)
1488    ODFln = G2lat.Flnh(Start,SHCoef,phi,beta,SGData)
1489    PX = np.array(SHData['PFxyz'])
1490    gam = atan2d(PX[0],PX[1])
1491    xy = math.sqrt(PX[0]**2+PX[1]**2)
1492    xyz = math.sqrt(PX[0]**2+PX[1]**2+PX[2]**2)
1493    psi = asind(xy/xyz)
1494    IODFln = G2lat.Glnh(Start,SHCoef,psi,gam,SamSym[textureData['Model']])
1495    if 'Axial' in SHData['PlotType']:
1496        X = np.linspace(0,90.0,26)
1497        Y = G2lat.polfcal(ODFln,SamSym[textureData['Model']],X,0.0)
1498        Plot.plot(X,Y,color='k',label=str(SHData['PFhkl']))
1499        Plot.legend(loc='best')
1500        Plot.set_title('Axial distribution for HKL='+str(SHData['PFhkl']))
1501        Plot.set_xlabel(r'$\psi$',fontsize=16)
1502        Plot.set_ylabel('MRD',fontsize=14)
1503       
1504    else:       
1505        npts = 201
1506        if 'Inverse' in SHData['PlotType']:
1507            X,Y = np.meshgrid(np.linspace(1.,-1.,npts),np.linspace(-1.,1.,npts))
1508            R,P = np.sqrt(X**2+Y**2).flatten(),npatan2d(X,Y).flatten()
1509            if 'equal' in G2frame.Projection:
1510                R = np.where(R <= 1.,2.*npasind(R*sq2),0.0)
1511            else:
1512                R = np.where(R <= 1.,2.*npatand(R),0.0)
1513            Z = np.zeros_like(R)
1514            Z = G2lat.invpolfcal(IODFln,SGData,R,P)
1515            Z = np.reshape(Z,(npts,npts))
1516            CS = Plot.contour(Y,X,Z,aspect='equal')
1517            Plot.clabel(CS,fontsize=9,inline=1)
1518            try:
1519                Img = Plot.imshow(Z.T,aspect='equal',cmap=G2frame.ContourColor,extent=[-1,1,-1,1])
1520            except ValueError:
1521                pass
1522            if newPlot:
1523#                Page.figure.colorbar(Img)    #colorbar fails - crashes gsasii
1524                newPlot = False
1525            Plot.set_title('Inverse pole figure for XYZ='+str(SHData['PFxyz']))
1526            Plot.set_xlabel(G2frame.Projection.capitalize()+' projection')
1527                       
1528        else:
1529            X,Y = np.meshgrid(np.linspace(1.,-1.,npts),np.linspace(-1.,1.,npts))
1530            R,P = np.sqrt(X**2+Y**2).flatten(),npatan2d(X,Y).flatten()
1531            if 'equal' in G2frame.Projection:
1532                R = np.where(R <= 1.,2.*npasind(R*sq2),0.0)
1533            else:
1534                R = np.where(R <= 1.,2.*npatand(R),0.0)
1535            Z = np.zeros_like(R)
1536            Z = G2lat.polfcal(ODFln,SamSym[textureData['Model']],R,P)
1537            Z = np.reshape(Z,(npts,npts))
1538            try:
1539                CS = Plot.contour(Y,X,Z,aspect='equal')
1540                Plot.clabel(CS,fontsize=9,inline=1)
1541            except ValueError:
1542                pass
1543            Img = Plot.imshow(Z.T,aspect='equal',cmap=G2frame.ContourColor,extent=[-1,1,-1,1])
1544            if newPlot:
1545#                Page.figure.colorbar(Img)    #colorbar fails - crashes gsasii
1546                newPlot = False
1547            Plot.set_title('Pole figure for HKL='+str(SHData['PFhkl']))
1548            Plot.set_xlabel(G2frame.Projection.capitalize()+' projection')
1549    Page.canvas.draw()
1550
1551################################################################################
1552##### PlotCovariance
1553################################################################################
1554           
1555def PlotCovariance(G2frame,Data={}):
1556    if not Data:
1557        Data = G2frame.PatternTree.GetItemPyData(
1558            G2gd.GetPatternTreeItemId(G2frame,G2frame.root, 'Covariance'))
1559    if not Data:
1560        print 'No covariance matrix available'
1561        return
1562    varyList = Data['varyList']
1563    values = Data['variables']
1564    Xmax = len(varyList)
1565    covMatrix = Data['covMatrix']
1566    sig = np.sqrt(np.diag(covMatrix))
1567    xvar = np.outer(sig,np.ones_like(sig))
1568    covArray = np.divide(np.divide(covMatrix,xvar),xvar.T)
1569    title = ' for\n'+Data['title']
1570    newAtomDict = Data['newAtomDict']
1571
1572    def OnPlotKeyPress(event):
1573        newPlot = False
1574        if event.key == 's':
1575            choice = [m for m in mpl.cm.datad.keys() if not m.endswith("_r")]
1576            choice.sort()
1577            dlg = wx.SingleChoiceDialog(G2frame,'Select','Color scheme',choice)
1578            if dlg.ShowModal() == wx.ID_OK:
1579                sel = dlg.GetSelection()
1580                G2frame.VcovColor = choice[sel]
1581            else:
1582                G2frame.VcovColor = 'RdYlGn'
1583            dlg.Destroy()
1584        PlotCovariance(G2frame)
1585
1586    def OnMotion(event):
1587        if event.button:
1588            ytics = imgAx.get_yticks()
1589            ytics = np.where(ytics<len(varyList),ytics,-1)
1590            ylabs = [np.where(0<=i ,varyList[int(i)],' ') for i in ytics]
1591            imgAx.set_yticklabels(ylabs)
1592           
1593        if event.xdata and event.ydata:                 #avoid out of frame errors
1594            xpos = int(event.xdata+.5)
1595            ypos = int(event.ydata+.5)
1596            if -1 < xpos < len(varyList) and -1 < ypos < len(varyList):
1597                if xpos == ypos:
1598                    value = values[xpos]
1599                    name = varyList[xpos]
1600                    if varyList[xpos] in newAtomDict:
1601                        name,value = newAtomDict[name]                       
1602                    msg = '%s value = %.4g, esd = %.4g'%(name,value,sig[xpos])
1603                else:
1604                    msg = '%s - %s: %5.3f'%(varyList[xpos],varyList[ypos],covArray[xpos][ypos])
1605                Page.canvas.SetToolTipString(msg)
1606                G2frame.G2plotNB.status.SetFields(['Key: s to change colors',msg])
1607    try:
1608        plotNum = G2frame.G2plotNB.plotList.index('Covariance')
1609        Page = G2frame.G2plotNB.nb.GetPage(plotNum)
1610        Page.figure.clf()
1611        Plot = Page.figure.gca()
1612        if not Page.IsShown():
1613            Page.Show()
1614    except ValueError:
1615        Plot = G2frame.G2plotNB.addMpl('Covariance').gca()
1616        plotNum = G2frame.G2plotNB.plotList.index('Covariance')
1617        Page = G2frame.G2plotNB.nb.GetPage(plotNum)
1618        Page.canvas.mpl_connect('motion_notify_event', OnMotion)
1619        Page.canvas.mpl_connect('key_press_event', OnPlotKeyPress)
1620
1621    Page.SetFocus()
1622    G2frame.G2plotNB.status.SetFields(['',''])   
1623    acolor = mpl.cm.get_cmap(G2frame.VcovColor)
1624    Img = Plot.imshow(covArray,aspect='equal',cmap=acolor,interpolation='nearest',origin='lower')
1625    imgAx = Img.get_axes()
1626    ytics = imgAx.get_yticks()
1627    ylabs = [varyList[int(i)] for i in ytics[:-1]]
1628    imgAx.set_yticklabels(ylabs)
1629    colorBar = Page.figure.colorbar(Img)
1630    Plot.set_title('V-Cov matrix'+title)
1631    Plot.set_xlabel('Variable number')
1632    Plot.set_ylabel('Variable name')
1633    Page.canvas.draw()
1634   
1635################################################################################
1636##### PlotSeq
1637################################################################################
1638           
1639def PlotSeq(G2frame,SeqData,SeqSig,SeqNames,sampleParm):
1640   
1641    def OnKeyPress(event):
1642        if event.key == 's' and sampleParm:
1643            if G2frame.xAxis:
1644                G2frame.xAxis = False
1645            else:
1646                G2frame.xAxis = True
1647            Draw(False)
1648    try:
1649        plotNum = G2frame.G2plotNB.plotList.index('Sequential refinement')
1650        Page = G2frame.G2plotNB.nb.GetPage(plotNum)
1651        Page.figure.clf()
1652        Plot = Page.figure.gca()
1653        if not Page.IsShown():
1654            Page.Show()
1655    except ValueError:
1656        Plot = G2frame.G2plotNB.addMpl('Sequential refinement').gca()
1657        plotNum = G2frame.G2plotNB.plotList.index('Sequential refinement')
1658        Page = G2frame.G2plotNB.nb.GetPage(plotNum)
1659        Page.canvas.mpl_connect('key_press_event', OnKeyPress)
1660        G2frame.xAxis = False
1661       
1662    def Draw(newPlot):
1663        Page.SetFocus()
1664        G2frame.G2plotNB.status.SetFields(['','press s to toggle x-axis = sample environment parameter'])
1665        if len(SeqData):
1666            Plot.clear()
1667            if G2frame.xAxis:   
1668                xName = sampleParm.keys()[0]
1669                X = sampleParm[xName]
1670            else:
1671                X = np.arange(0,len(SeqData[0]),1)
1672                xName = 'Data sequence number'
1673            for Y,sig,name in zip(SeqData,SeqSig,SeqNames):
1674                Plot.errorbar(X,Y,yerr=sig,label=name)       
1675            Plot.legend(loc='best')
1676            Plot.set_ylabel('Parameter values')
1677            Plot.set_xlabel(xName)
1678            Page.canvas.draw()           
1679    Draw(True)
1680           
1681################################################################################
1682##### PlotExposedImage & PlotImage
1683################################################################################
1684           
1685def PlotExposedImage(G2frame,newPlot=False,event=None):
1686    '''General access module for 2D image plotting
1687    '''
1688    plotNo = G2frame.G2plotNB.nb.GetSelection()
1689    if G2frame.G2plotNB.nb.GetPageText(plotNo) == '2D Powder Image':
1690        PlotImage(G2frame,newPlot,event,newImage=True)
1691    elif G2frame.G2plotNB.nb.GetPageText(plotNo) == '2D Integration':
1692        PlotIntegration(G2frame,newPlot,event)
1693
1694def PlotImage(G2frame,newPlot=False,event=None,newImage=True):
1695    '''Plot of 2D detector images as contoured plot. Also plot calibration ellipses,
1696    masks, etc.
1697    '''
1698    from matplotlib.patches import Ellipse,Arc,Circle,Polygon
1699    import numpy.ma as ma
1700    Dsp = lambda tth,wave: wave/(2.*sind(tth/2.))
1701    global Data,Masks
1702    colors=['b','g','r','c','m','k']
1703    Data = G2frame.PatternTree.GetItemPyData(
1704        G2gd.GetPatternTreeItemId(G2frame,G2frame.Image, 'Image Controls'))
1705    Masks = G2frame.PatternTree.GetItemPyData(
1706        G2gd.GetPatternTreeItemId(G2frame,G2frame.Image, 'Masks'))
1707
1708    def OnImMotion(event):
1709        Page.canvas.SetToolTipString('')
1710        sizexy = Data['size']
1711        if event.xdata and event.ydata and len(G2frame.ImageZ):                 #avoid out of frame errors
1712            Page.canvas.SetCursor(wx.CROSS_CURSOR)
1713            item = G2frame.itemPicked
1714            pixelSize = Data['pixelSize']
1715            scalex = 1000./pixelSize[0]
1716            scaley = 1000./pixelSize[1]
1717            if item and G2frame.PatternTree.GetItemText(G2frame.PickId) == 'Image Controls':
1718                if 'Text' in str(item):
1719                    Page.canvas.SetToolTipString('%8.3f %8.3fmm'%(event.xdata,event.ydata))
1720                else:
1721                    xcent,ycent = Data['center']
1722                    xpos = event.xdata-xcent
1723                    ypos = event.ydata-ycent
1724                    tth,azm = G2img.GetTthAzm(event.xdata,event.ydata,Data)
1725                    if 'line3' in  str(item) or 'line4' in str(item) and not Data['fullIntegrate']:
1726                        Page.canvas.SetToolTipString('%6d deg'%(azm))
1727                    elif 'line1' in  str(item) or 'line2' in str(item):
1728                        Page.canvas.SetToolTipString('%8.3fdeg'%(tth))                           
1729            else:
1730                xpos = event.xdata
1731                ypos = event.ydata
1732                xpix = xpos*scalex
1733                ypix = ypos*scaley
1734                Int = 0
1735                if (0 <= xpix <= sizexy[0]) and (0 <= ypix <= sizexy[1]):
1736                    Int = G2frame.ImageZ[ypix][xpix]
1737                tth,azm,dsp = G2img.GetTthAzmDsp(xpos,ypos,Data)
1738                Q = 2.*math.pi/dsp
1739                if G2frame.setPoly:
1740                    G2frame.G2plotNB.status.SetFields(['','Polygon mask pick - LB next point, RB close polygon'])
1741                else:
1742                    G2frame.G2plotNB.status.SetFields(\
1743                        ['','Detector 2-th =%9.3fdeg, dsp =%9.3fA, Q = %6.5fA-1, azm = %7.2fdeg, I = %6d'%(tth,dsp,Q,azm,Int)])
1744
1745    def OnImPlotKeyPress(event):
1746        try:
1747            PickName = G2frame.PatternTree.GetItemText(G2frame.PickId)
1748        except TypeError:
1749            return
1750        if PickName == 'Masks':
1751            Xpos = event.xdata
1752            if not Xpos:            #got point out of frame
1753                return
1754            Ypos = event.ydata
1755            if event.key == 's':
1756                Masks['Points'].append([Xpos,Ypos,1.])
1757            elif event.key == 'r':
1758                tth = G2img.GetTth(Xpos,Ypos,Data)
1759                Masks['Rings'].append([tth,0.1])
1760            elif event.key == 'a':
1761                tth,azm = G2img.GetTthAzm(Xpos,Ypos,Data)
1762                azm = int(azm)               
1763                Masks['Arcs'].append([tth,[azm-5,azm+5],0.1])
1764            elif event.key == 'p':
1765                G2frame.setPoly = True
1766                Masks['Polygons'].append([])
1767                G2frame.G2plotNB.status.SetFields(['','Polygon mask active - LB pick next point, RB close polygon'])
1768            G2imG.UpdateMasks(G2frame,Masks)
1769        elif PickName == 'Image Controls':
1770            if event.key == 'c':
1771                Xpos = event.xdata
1772                if not Xpos:            #got point out of frame
1773                    return
1774                Ypos = event.ydata
1775                dlg = wx.MessageDialog(G2frame,'Are you sure you want to change the center?',
1776                    'Center change',style=wx.OK|wx.CANCEL)
1777                try:
1778                    if dlg.ShowModal() == wx.ID_OK:
1779                        print 'move center to: ',Xpos,Ypos
1780                        Data['center'] = [Xpos,Ypos]
1781                        G2imG.UpdateImageControls(G2frame,Data,Masks)
1782                finally:
1783                    dlg.Destroy()
1784            elif event.key == 'l':
1785                if G2frame.logPlot:
1786                    G2frame.logPlot = False
1787                else:
1788                    G2frame.logPlot = True
1789        PlotImage(G2frame,newImage=True)
1790           
1791    def OnKeyBox(event):
1792        if G2frame.G2plotNB.nb.GetSelection() == G2frame.G2plotNB.plotList.index('2D Powder Image'):
1793            event.key = cb.GetValue()[0]
1794            cb.SetValue(' key press')
1795            if event.key in 'l':
1796                OnImPlotKeyPress(event)
1797                       
1798    def OnImPick(event):
1799        if G2frame.PatternTree.GetItemText(G2frame.PickId) not in ['Image Controls','Masks']:
1800            return
1801        if G2frame.setPoly:
1802            polygon = Masks['Polygons'][-1]
1803            xpos,ypos = event.mouseevent.xdata,event.mouseevent.ydata
1804            if xpos and ypos:                       #point inside image
1805                if len(polygon) > 2 and event.mouseevent.button == 3:
1806                    x0,y0 = polygon[0]
1807                    polygon.append([x0,y0])
1808                    G2frame.setPoly = False
1809                    G2frame.G2plotNB.status.SetFields(['','Polygon closed - RB drag a vertex to change shape'])
1810                else:
1811                    G2frame.G2plotNB.status.SetFields(['','New polygon point: %.1f,%.1f'%(xpos,ypos)])
1812                    polygon.append([xpos,ypos])
1813                G2imG.UpdateMasks(G2frame,Masks)
1814        else:
1815            if G2frame.itemPicked is not None: return
1816            G2frame.itemPicked = event.artist
1817            G2frame.mousePicked = event.mouseevent
1818       
1819    def OnImRelease(event):
1820        try:
1821            PickName = G2frame.PatternTree.GetItemText(G2frame.PickId)
1822        except TypeError:
1823            return
1824        if PickName not in ['Image Controls','Masks']:
1825            return
1826        pixelSize = Data['pixelSize']
1827        scalex = 1000./pixelSize[0]
1828        scaley = 1000./pixelSize[1]
1829        pixLimit = Data['pixLimit']
1830        if G2frame.itemPicked is None and PickName == 'Image Controls' and len(G2frame.ImageZ):
1831#            sizexy = Data['size']
1832            Xpos = event.xdata
1833            if not (Xpos and G2frame.ifGetRing):                   #got point out of frame
1834                return
1835            Ypos = event.ydata
1836            if Ypos and not Page.toolbar._active:         #make sure zoom/pan not selected
1837                if event.button == 1:
1838                    Xpix = Xpos*scalex
1839                    Ypix = Ypos*scaley
1840                    xpos,ypos,I,J = G2img.ImageLocalMax(G2frame.ImageZ,pixLimit,Xpix,Ypix)
1841                    if I and J:
1842                        xpos += .5                              #shift to pixel center
1843                        ypos += .5
1844                        xpos /= scalex                          #convert to mm
1845                        ypos /= scaley
1846                        Data['ring'].append([xpos,ypos])
1847                elif event.button == 3:
1848                    G2frame.dataFrame.GetStatusBar().SetStatusText('Calibrating...')
1849                    if G2img.ImageCalibrate(G2frame,Data):
1850                        G2frame.dataFrame.GetStatusBar().SetStatusText('Calibration successful - Show ring picks to check')
1851                        print 'Calibration successful'
1852                    else:
1853                        G2frame.dataFrame.GetStatusBar().SetStatusText('Calibration failed - Show ring picks to diagnose')
1854                        print 'Calibration failed'
1855                    G2frame.ifGetRing = False
1856                    G2imG.UpdateImageControls(G2frame,Data,Masks)
1857                    return
1858                PlotImage(G2frame,newImage=False)
1859            return
1860        else:
1861            xpos = event.xdata
1862            if xpos:                                        #avoid out of frame mouse position
1863                ypos = event.ydata
1864                if G2frame.ifGetRing:                          #delete a calibration ring pick
1865                    xypos = [xpos,ypos]
1866                    rings = Data['ring']
1867                    for ring in rings:
1868                        if np.allclose(ring,xypos,.01,0):
1869                            rings.remove(ring)                                                                       
1870                else:
1871                    tth,azm,dsp = G2img.GetTthAzmDsp(xpos,ypos,Data)
1872                    itemPicked = str(G2frame.itemPicked)
1873                    if 'Line2D' in itemPicked and PickName == 'Image Controls':
1874                        if 'line1' in itemPicked:
1875                            Data['IOtth'][0] = max(tth,0.001)
1876                        elif 'line2' in itemPicked:
1877                            Data['IOtth'][1] = tth
1878                        elif 'line3' in itemPicked:
1879                            Data['LRazimuth'][0] = int(azm)
1880                            if Data['fullIntegrate']:
1881                                Data['LRazimuth'][1] = Data['LRazimuth'][0]+360
1882                        elif 'line4' in itemPicked and not Data['fullIntegrate']:
1883                            Data['LRazimuth'][1] = int(azm)
1884                           
1885                        if Data['LRazimuth'][0] > Data['LRazimuth'][1]:
1886                            Data['LRazimuth'][0] -= 360
1887                           
1888                        azLim = np.array(Data['LRazimuth'])   
1889                        if np.any(azLim>360):
1890                            azLim -= 360
1891                            Data['LRazimuth'] = list(azLim)
1892                           
1893                        if  Data['IOtth'][0] > Data['IOtth'][1]:
1894                            Data['IOtth'][0],Data['IOtth'][1] = Data['IOtth'][1],Data['IOtth'][0]
1895                           
1896                        G2frame.InnerTth.SetValue("%8.2f" % (Data['IOtth'][0]))
1897                        G2frame.OuterTth.SetValue("%8.2f" % (Data['IOtth'][1]))
1898                        G2frame.Lazim.SetValue("%6d" % (Data['LRazimuth'][0]))
1899                        G2frame.Razim.SetValue("%6d" % (Data['LRazimuth'][1]))
1900                    elif 'Circle' in itemPicked and PickName == 'Masks':
1901                        spots = Masks['Points']
1902                        newPos = itemPicked.split(')')[0].split('(')[2].split(',')
1903                        newPos = np.array([float(newPos[0]),float(newPos[1])])
1904                        for spot in spots:
1905                            if np.allclose(np.array([spot[:2]]),newPos):
1906                                spot[:2] = xpos,ypos
1907                        G2imG.UpdateMasks(G2frame,Masks)
1908                    elif 'Line2D' in itemPicked and PickName == 'Masks':
1909                        Obj = G2frame.itemPicked.findobj()
1910                        rings = Masks['Rings']
1911                        arcs = Masks['Arcs']
1912                        polygons = Masks['Polygons']
1913                        for ring in G2frame.ringList:
1914                            if Obj == ring[0]:
1915                                rN = ring[1]
1916                                if ring[2] == 'o':
1917                                    rings[rN][0] = G2img.GetTth(xpos,ypos,Data)-rings[rN][1]/2.
1918                                else:
1919                                    rings[rN][0] = G2img.GetTth(xpos,ypos,Data)+rings[rN][1]/2.
1920                        for arc in G2frame.arcList:
1921                            if Obj == arc[0]:
1922                                aN = arc[1]
1923                                if arc[2] == 'o':
1924                                    arcs[aN][0] = G2img.GetTth(xpos,ypos,Data)-arcs[aN][2]/2
1925                                elif arc[2] == 'i':
1926                                    arcs[aN][0] = G2img.GetTth(xpos,ypos,Data)+arcs[aN][2]/2
1927                                elif arc[2] == 'l':
1928                                    arcs[aN][1][0] = int(G2img.GetAzm(xpos,ypos,Data))
1929                                else:
1930                                    arcs[aN][1][1] = int(G2img.GetAzm(xpos,ypos,Data))
1931                        for poly in G2frame.polyList:
1932                            if Obj == poly[0]:
1933                                ind = G2frame.itemPicked.contains(G2frame.mousePicked)[1]['ind'][0]
1934                                oldPos = np.array([G2frame.mousePicked.xdata,G2frame.mousePicked.ydata])
1935                                pN = poly[1]
1936                                for i,xy in enumerate(polygons[pN]):
1937                                    if np.allclose(np.array([xy]),oldPos,atol=1.0):
1938                                        polygons[pN][i] = xpos,ypos
1939                        G2imG.UpdateMasks(G2frame,Masks)
1940#                    else:                  #keep for future debugging
1941#                        print str(G2frame.itemPicked),event.xdata,event.ydata,event.button
1942                PlotImage(G2frame,newImage=True)
1943            G2frame.itemPicked = None
1944           
1945    try:
1946        plotNum = G2frame.G2plotNB.plotList.index('2D Powder Image')
1947        Page = G2frame.G2plotNB.nb.GetPage(plotNum)
1948        if not newPlot:
1949            Plot = Page.figure.gca()          #get previous powder plot & get limits
1950            xylim = Plot.get_xlim(),Plot.get_ylim()
1951        if newImage:
1952            Page.figure.clf()
1953            Plot = Page.figure.gca()          #get a fresh plot after clf()
1954       
1955    except ValueError:
1956        Plot = G2frame.G2plotNB.addMpl('2D Powder Image').gca()
1957        plotNum = G2frame.G2plotNB.plotList.index('2D Powder Image')
1958        Page = G2frame.G2plotNB.nb.GetPage(plotNum)
1959        Page.canvas.mpl_connect('key_press_event', OnImPlotKeyPress)
1960        Page.canvas.mpl_connect('motion_notify_event', OnImMotion)
1961        Page.canvas.mpl_connect('pick_event', OnImPick)
1962        Page.canvas.mpl_connect('button_release_event', OnImRelease)
1963        xylim = []
1964    if not event:                       #event from GUI TextCtrl - don't want focus to change to plot!!!
1965        Page.SetFocus()
1966    Title = G2frame.PatternTree.GetItemText(G2frame.Image)[4:]
1967    G2frame.G2plotNB.status.DestroyChildren()
1968    if G2frame.logPlot:
1969        Title = 'log('+Title+')'
1970    Plot.set_title(Title)
1971    try:
1972        if G2frame.PatternTree.GetItemText(G2frame.PickId) in ['Image Controls',]:
1973            Choice = (' key press','l: log(I) on',)
1974            if G2frame.logPlot:
1975                Choice[1] = 'l: log(I) off'
1976            cb = wx.ComboBox(G2frame.G2plotNB.status,style=wx.CB_DROPDOWN|wx.CB_READONLY,
1977                choices=Choice)
1978            cb.Bind(wx.EVT_COMBOBOX, OnKeyBox)
1979            cb.SetValue(' key press')
1980    except TypeError:
1981        pass
1982    size,imagefile = G2frame.PatternTree.GetItemPyData(G2frame.Image)
1983    if imagefile != G2frame.oldImagefile:
1984        imagefile = G2IO.CheckImageFile(G2frame,imagefile)
1985        if not imagefile:
1986            G2frame.G2plotNB.Delete('2D Powder Image')
1987            return
1988        G2frame.PatternTree.SetItemPyData(G2frame.Image,[size,imagefile])
1989        G2frame.ImageZ = G2IO.GetImageData(G2frame,imagefile,imageOnly=True)
1990        G2frame.oldImagefile = imagefile
1991
1992    imScale = 1
1993    if len(G2frame.ImageZ) > 1024:
1994        imScale = len(G2frame.ImageZ)/1024
1995    sizexy = Data['size']
1996    pixelSize = Data['pixelSize']
1997    scalex = 1000./pixelSize[0]
1998    scaley = 1000./pixelSize[1]
1999    Xmax = sizexy[0]*pixelSize[0]/1000.
2000    Ymax = sizexy[1]*pixelSize[1]/1000.
2001    xlim = (0,Xmax)
2002    ylim = (Ymax,0)
2003    Imin,Imax = Data['range'][1]
2004    acolor = mpl.cm.get_cmap(Data['color'])
2005    xcent,ycent = Data['center']
2006    Plot.set_xlabel('Image x-axis, mm',fontsize=12)
2007    Plot.set_ylabel('Image y-axis, mm',fontsize=12)
2008    #do threshold mask - "real" mask - others are just bondaries
2009    Zlim = Masks['Thresholds'][1]
2010    wx.BeginBusyCursor()
2011    try:
2012           
2013        if newImage:                   
2014            MA = ma.masked_greater(ma.masked_less(G2frame.ImageZ,Zlim[0]),Zlim[1])
2015            MaskA = ma.getmaskarray(MA)
2016            A = G2img.ImageCompress(MA,imScale)
2017            AM = G2img.ImageCompress(MaskA,imScale)
2018            if G2frame.logPlot:
2019                A = np.where(A>0,np.log(A),0)
2020                AM = np.where(AM>0,np.log(AM),0)
2021                Imin,Imax = [np.amin(A),np.amax(A)]
2022            ImgM = Plot.imshow(AM,aspect='equal',cmap='Reds',
2023                interpolation='nearest',vmin=0,vmax=2,extent=[0,Xmax,Ymax,0])
2024            Img = Plot.imshow(A,aspect='equal',cmap=acolor,
2025                interpolation='nearest',vmin=Imin,vmax=Imax,extent=[0,Xmax,Ymax,0])
2026            if G2frame.setPoly:
2027                Img.set_picker(True)
2028   
2029        Plot.plot(xcent,ycent,'x')
2030        if Data['showLines']:
2031            LRAzim = Data['LRazimuth']                  #NB: integers
2032            Nazm = Data['outAzimuths']
2033            delAzm = float(LRAzim[1]-LRAzim[0])/Nazm
2034            AzmthOff = Data['azmthOff']
2035            IOtth = Data['IOtth']
2036            wave = Data['wavelength']
2037            dspI = wave/(2.0*sind(IOtth[0]/2.0))
2038            ellI = G2img.GetEllipse(dspI,Data)           #=False if dsp didn't yield an ellipse (ugh! a parabola or a hyperbola)
2039            dspO = wave/(2.0*sind(IOtth[1]/2.0))
2040            ellO = G2img.GetEllipse(dspO,Data)           #Ditto & more likely for outer ellipse
2041            Azm = np.array(range(LRAzim[0],LRAzim[1]+1))-AzmthOff
2042            if ellI:
2043                xyI = []
2044                for azm in Azm:
2045                    xyI.append(G2img.GetDetectorXY(dspI,azm-90.,Data))
2046                xyI = np.array(xyI)
2047                arcxI,arcyI = xyI.T
2048                Plot.plot(arcxI,arcyI,picker=3)
2049            if ellO:
2050                xyO = []
2051                for azm in Azm:
2052                    xyO.append(G2img.GetDetectorXY(dspO,azm-90.,Data))
2053                xyO = np.array(xyO)
2054                arcxO,arcyO = xyO.T
2055                Plot.plot(arcxO,arcyO,picker=3)
2056            if ellO and ellI:
2057                Plot.plot([arcxI[0],arcxO[0]],[arcyI[0],arcyO[0]],picker=3)
2058                Plot.plot([arcxI[-1],arcxO[-1]],[arcyI[-1],arcyO[-1]],picker=3)
2059            for i in range(Nazm):
2060                cake = LRAzim[0]+i*delAzm-AzmthOff
2061                if Data['centerAzm']:
2062                    cake += delAzm/2.
2063                ind = np.searchsorted(Azm,cake)
2064                Plot.plot([arcxI[ind],arcxO[ind]],[arcyI[ind],arcyO[ind]],color='k',dashes=(5,5))
2065                   
2066        for xring,yring in Data['ring']:
2067            Plot.plot(xring,yring,'r+',picker=3)
2068        if Data['setRings']:
2069#            rings = np.concatenate((Data['rings']),axis=0)
2070            N = 0
2071            for ring in Data['rings']:
2072                xring,yring = np.array(ring).T[:2]
2073                Plot.plot(xring,yring,'+',color=colors[N%6])
2074                N += 1           
2075        for ellipse in Data['ellipses']:
2076            cent,phi,[width,height],col = ellipse
2077            Plot.add_artist(Ellipse([cent[0],cent[1]],2*width,2*height,phi,ec=col,fc='none'))
2078            Plot.text(cent[0],cent[1],'+',color=col,ha='center',va='center')
2079        #masks - mask lines numbered after integration limit lines
2080        spots = Masks['Points']
2081        rings = Masks['Rings']
2082        arcs = Masks['Arcs']
2083        polygons = Masks['Polygons']
2084        for x,y,d in spots:
2085            Plot.add_artist(Circle((x,y),radius=d/2,fc='none',ec='r',picker=3))
2086        G2frame.ringList = []
2087        for iring,(tth,thick) in enumerate(rings):
2088            wave = Data['wavelength']
2089            x1,y1 = np.hsplit(np.array(G2img.makeIdealRing(G2img.GetEllipse(Dsp(tth+thick/2.,wave),Data))),2)
2090            x2,y2 = np.hsplit(np.array(G2img.makeIdealRing(G2img.GetEllipse(Dsp(tth-thick/2.,wave),Data))),2)
2091            G2frame.ringList.append([Plot.plot(x1,y1,'r',picker=3),iring,'o'])           
2092            G2frame.ringList.append([Plot.plot(x2,y2,'r',picker=3),iring,'i'])
2093        G2frame.arcList = []
2094        for iarc,(tth,azm,thick) in enumerate(arcs):           
2095            wave = Data['wavelength']
2096            x1,y1 = np.hsplit(np.array(G2img.makeIdealRing(G2img.GetEllipse(Dsp(tth+thick/2.,wave),Data),azm)),2)
2097            x2,y2 = np.hsplit(np.array(G2img.makeIdealRing(G2img.GetEllipse(Dsp(max(0.01,tth-thick/2.),wave),Data),azm)),2)
2098            G2frame.arcList.append([Plot.plot(x1,y1,'r',picker=3),iarc,'o'])           
2099            G2frame.arcList.append([Plot.plot(x2,y2,'r',picker=3),iarc,'i'])
2100            G2frame.arcList.append([Plot.plot([x1[0],x2[0]],[y1[0],y2[0]],'r',picker=3),iarc,'l'])
2101            G2frame.arcList.append([Plot.plot([x1[-1],x2[-1]],[y1[-1],y2[-1]],'r',picker=3),iarc,'u'])
2102        G2frame.polyList = []
2103        for ipoly,polygon in enumerate(polygons):
2104            x,y = np.hsplit(np.array(polygon),2)
2105            G2frame.polyList.append([Plot.plot(x,y,'r+',picker=10),ipoly])
2106            Plot.plot(x,y,'r')           
2107        if newImage:
2108            colorBar = Page.figure.colorbar(Img)
2109        Plot.set_xlim(xlim)
2110        Plot.set_ylim(ylim)
2111        Plot.invert_yaxis()
2112        if not newPlot and xylim:
2113            Page.toolbar.push_current()
2114            Plot.set_xlim(xylim[0])
2115            Plot.set_ylim(xylim[1])
2116            xylim = []
2117            Page.toolbar.push_current()
2118            Page.toolbar.draw()
2119        else:
2120            Page.canvas.draw()
2121    finally:
2122        wx.EndBusyCursor()
2123       
2124################################################################################
2125##### PlotIntegration
2126################################################################################
2127           
2128def PlotIntegration(G2frame,newPlot=False,event=None):
2129    '''Plot of 2D image after image integration with 2-theta and azimuth as coordinates
2130    '''
2131           
2132    def OnMotion(event):
2133        Page.canvas.SetToolTipString('')
2134        Page.canvas.SetCursor(wx.CROSS_CURSOR)
2135        azm = event.ydata
2136        tth = event.xdata
2137        if azm and tth:
2138            G2frame.G2plotNB.status.SetFields(\
2139                ['','Detector 2-th =%9.3fdeg, azm = %7.2fdeg'%(tth,azm)])
2140                               
2141    try:
2142        plotNum = G2frame.G2plotNB.plotList.index('2D Integration')
2143        Page = G2frame.G2plotNB.nb.GetPage(plotNum)
2144        if not newPlot:
2145            Plot = Page.figure.gca()          #get previous plot & get limits
2146            xylim = Plot.get_xlim(),Plot.get_ylim()
2147        Page.figure.clf()
2148        Plot = Page.figure.gca()          #get a fresh plot after clf()
2149       
2150    except ValueError:
2151        Plot = G2frame.G2plotNB.addMpl('2D Integration').gca()
2152        plotNum = G2frame.G2plotNB.plotList.index('2D Integration')
2153        Page = G2frame.G2plotNB.nb.GetPage(plotNum)
2154        Page.canvas.mpl_connect('motion_notify_event', OnMotion)
2155        Page.views = False
2156        view = False
2157    if not event:
2158        Page.SetFocus()
2159       
2160    Data = G2frame.PatternTree.GetItemPyData(
2161        G2gd.GetPatternTreeItemId(G2frame,G2frame.Image, 'Image Controls'))
2162    image = G2frame.Integrate[0]
2163    xsc = G2frame.Integrate[1]
2164    ysc = G2frame.Integrate[2]
2165    Imin,Imax = Data['range'][1]
2166    acolor = mpl.cm.get_cmap(Data['color'])
2167    Plot.set_title(G2frame.PatternTree.GetItemText(G2frame.Image)[4:])
2168    Plot.set_ylabel('azimuth',fontsize=12)
2169    Plot.set_xlabel('2-theta',fontsize=12)
2170    Img = Plot.imshow(image,cmap=acolor,vmin=Imin,vmax=Imax,interpolation='nearest', \
2171        extent=[ysc[0],ysc[-1],xsc[-1],xsc[0]],aspect='auto')
2172    colorBar = Page.figure.colorbar(Img)
2173    if Data['ellipses']:           
2174        for ellipse in Data['ellipses']:
2175            ring = np.array(G2img.makeIdealRing(ellipse[:3])) #skip color
2176            x,y = np.hsplit(ring,2)
2177            tth,azm = G2img.GetTthAzm(x,y,Data)
2178#            azm = np.where(azm < 0.,azm+360,azm)
2179            Plot.plot(tth,azm,'b,')
2180    if not newPlot:
2181        Page.toolbar.push_current()
2182        Plot.set_xlim(xylim[0])
2183        Plot.set_ylim(xylim[1])
2184        xylim = []
2185        Page.toolbar.push_current()
2186        Page.toolbar.draw()
2187    else:
2188        Page.canvas.draw()
2189               
2190################################################################################
2191##### PlotTRImage
2192################################################################################
2193           
2194def PlotTRImage(G2frame,tax,tay,taz,newPlot=False):
2195    '''a test plot routine - not normally used
2196    ''' 
2197           
2198    def OnMotion(event):
2199        Page.canvas.SetToolTipString('')
2200        Page.canvas.SetCursor(wx.CROSS_CURSOR)
2201        azm = event.xdata
2202        tth = event.ydata
2203        if azm and tth:
2204            G2frame.G2plotNB.status.SetFields(\
2205                ['','Detector 2-th =%9.3fdeg, azm = %7.2fdeg'%(tth,azm)])
2206                               
2207    try:
2208        plotNum = G2frame.G2plotNB.plotList.index('2D Transformed Powder Image')
2209        Page = G2frame.G2plotNB.nb.GetPage(plotNum)
2210        if not newPlot:
2211            Plot = Page.figure.gca()          #get previous plot & get limits
2212            xylim = Plot.get_xlim(),Plot.get_ylim()
2213        Page.figure.clf()
2214        Plot = Page.figure.gca()          #get a fresh plot after clf()
2215       
2216    except ValueError:
2217        Plot = G2frame.G2plotNB.addMpl('2D Transformed Powder Image').gca()
2218        plotNum = G2frame.G2plotNB.plotList.index('2D Transformed Powder Image')
2219        Page = G2frame.G2plotNB.nb.GetPage(plotNum)
2220        Page.canvas.mpl_connect('motion_notify_event', OnMotion)
2221        Page.views = False
2222        view = False
2223    Page.SetFocus()
2224       
2225    Data = G2frame.PatternTree.GetItemPyData(
2226        G2gd.GetPatternTreeItemId(G2frame,G2frame.Image, 'Image Controls'))
2227    Imin,Imax = Data['range'][1]
2228    step = (Imax-Imin)/5.
2229    V = np.arange(Imin,Imax,step)
2230    acolor = mpl.cm.get_cmap(Data['color'])
2231    Plot.set_title(G2frame.PatternTree.GetItemText(G2frame.Image)[4:])
2232    Plot.set_xlabel('azimuth',fontsize=12)
2233    Plot.set_ylabel('2-theta',fontsize=12)
2234    Plot.contour(tax,tay,taz,V,cmap=acolor)
2235    if Data['showLines']:
2236        IOtth = Data['IOtth']
2237        if Data['fullIntegrate']:
2238            LRAzim = [-180,180]
2239        else:
2240            LRAzim = Data['LRazimuth']                  #NB: integers
2241        Plot.plot([LRAzim[0],LRAzim[1]],[IOtth[0],IOtth[0]],picker=True)
2242        Plot.plot([LRAzim[0],LRAzim[1]],[IOtth[1],IOtth[1]],picker=True)
2243        if not Data['fullIntegrate']:
2244            Plot.plot([LRAzim[0],LRAzim[0]],[IOtth[0],IOtth[1]],picker=True)
2245            Plot.plot([LRAzim[1],LRAzim[1]],[IOtth[0],IOtth[1]],picker=True)
2246    if Data['setRings']:
2247        rings = np.concatenate((Data['rings']),axis=0)
2248        for xring,yring,dsp in rings:
2249            x,y = G2img.GetTthAzm(xring,yring,Data)
2250            Plot.plot(y,x,'r+')           
2251    if Data['ellipses']:           
2252        for ellipse in Data['ellipses']:
2253            ring = np.array(G2img.makeIdealRing(ellipse[:3])) #skip color
2254            x,y = np.hsplit(ring,2)
2255            tth,azm = G2img.GetTthAzm(x,y,Data)
2256            Plot.plot(azm,tth,'b,')
2257    if not newPlot:
2258        Page.toolbar.push_current()
2259        Plot.set_xlim(xylim[0])
2260        Plot.set_ylim(xylim[1])
2261        xylim = []
2262        Page.toolbar.push_current()
2263        Page.toolbar.draw()
2264    else:
2265        Page.canvas.draw()
2266       
2267################################################################################
2268##### PlotStructure
2269################################################################################
2270           
2271def PlotStructure(G2frame,data):
2272    '''Crystal structure plotting package. Can show structures as balls, sticks, lines,
2273    thermal motion ellipsoids and polyhedra
2274    '''
2275    ForthirdPI = 4.0*math.pi/3.0
2276    generalData = data['General']
2277    cell = generalData['Cell'][1:7]
2278    Vol = generalData['Cell'][7:8][0]
2279    Amat,Bmat = G2lat.cell2AB(cell)         #Amat - crystal to cartesian, Bmat - inverse
2280    A4mat = np.concatenate((np.concatenate((Amat,[[0],[0],[0]]),axis=1),[[0,0,0,1],]),axis=0)
2281    B4mat = np.concatenate((np.concatenate((Bmat,[[0],[0],[0]]),axis=1),[[0,0,0,1],]),axis=0)
2282    Mydir = generalData['Mydir']
2283    atomData = data['Atoms']
2284    mapPeaks = []
2285    if 'Map Peaks' in data:
2286        mapPeaks = data['Map Peaks']
2287    drawingData = data['Drawing']
2288    drawAtoms = drawingData['Atoms']
2289    mapData = {}
2290    flipData = {}
2291    rhoXYZ = []
2292    if 'Map' in generalData:
2293        mapData = generalData['Map']
2294    if 'Flip' in generalData:
2295        flipData = generalData['Flip']                       
2296        flipData['mapRoll'] = [0,0,0]
2297    cx,ct,cs = drawingData['atomPtrs']
2298    Wt = np.array([255,255,255])
2299    Rd = np.array([255,0,0])
2300    Gr = np.array([0,255,0])
2301    Bl = np.array([0,0,255])
2302    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]])
2303    uEdges = np.array([
2304        [uBox[0],uBox[1]],[uBox[0],uBox[3]],[uBox[0],uBox[4]],[uBox[1],uBox[2]], 
2305        [uBox[2],uBox[3]],[uBox[1],uBox[5]],[uBox[2],uBox[6]],[uBox[3],uBox[7]], 
2306        [uBox[4],uBox[5]],[uBox[5],uBox[6]],[uBox[6],uBox[7]],[uBox[7],uBox[4]]])
2307    uColors = [Rd,Gr,Bl,Wt, Wt,Wt,Wt,Wt, Wt,Wt,Wt,Wt]
2308    altDown = False
2309    shiftDown = False
2310    ctrlDown = False
2311   
2312    def OnKeyBox(event):
2313        import Image
2314        Draw()                          #make sure plot is fresh!!
2315        mode = cb.GetValue()
2316        Fname = Mydir+'\\'+generalData['Name']+'.'+mode
2317        size = Page.canvas.GetSize()
2318        glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
2319        if mode in ['jpeg',]:
2320            Pix = glReadPixels(0,0,size[0],size[1],GL_RGBA, GL_UNSIGNED_BYTE)
2321            im = Image.new("RGBA", (size[0],size[1]))
2322        else:
2323            Pix = glReadPixels(0,0,size[0],size[1],GL_RGB, GL_UNSIGNED_BYTE)
2324            im = Image.new("RGB", (size[0],size[1]))
2325        im.fromstring(Pix)
2326        im.save(Fname,mode)
2327        cb.SetValue(' Save as:')
2328        G2frame.G2plotNB.status.SetStatusText('Drawing saved to: '+Fname,1)
2329   
2330    def GetTruePosition(xy,Add=False):
2331        View = glGetIntegerv(GL_VIEWPORT)
2332        Proj = glGetDoublev(GL_PROJECTION_MATRIX)
2333        Model = glGetDoublev(GL_MODELVIEW_MATRIX)
2334        Zmax = 1.
2335        if Add:
2336            Indx = GetSelectedAtoms()
2337        if G2frame.dataDisplay.GetPageText(getSelection()) == 'Map peaks':
2338            for i,peak in enumerate(mapPeaks):
2339                x,y,z = peak[1:]
2340                X,Y,Z = gluProject(x,y,z,Model,Proj,View)
2341                XY = [int(X),int(View[3]-Y)]
2342                if np.allclose(xy,XY,atol=10) and Z < Zmax:
2343                    Zmax = Z
2344                    try:
2345                        Indx.remove(i)
2346                        ClearSelectedAtoms()
2347                        for id in Indx:
2348                            SetSelectedAtoms(id,Add)
2349                    except:
2350                        SetSelectedAtoms(i,Add)
2351        else:
2352            for i,atom in enumerate(drawAtoms):
2353                x,y,z = atom[cx:cx+3]
2354                X,Y,Z = gluProject(x,y,z,Model,Proj,View)
2355                XY = [int(X),int(View[3]-Y)]
2356                if np.allclose(xy,XY,atol=10) and Z < Zmax:
2357                    Zmax = Z
2358                    try:
2359                        Indx.remove(i)
2360                        ClearSelectedAtoms()
2361                        for id in Indx:
2362                            SetSelectedAtoms(id,Add)
2363                    except:
2364                        SetSelectedAtoms(i,Add)
2365                                       
2366    def OnMouseDown(event):
2367        xy = event.GetPosition()
2368        if event.ShiftDown():
2369            if event.LeftIsDown():
2370                GetTruePosition(xy)
2371            elif event.RightIsDown():
2372                GetTruePosition(xy,True)
2373        else:
2374            drawingData['Rotation'][3] = list(xy)
2375        Draw()
2376       
2377    def OnMouseMove(event):
2378        newxy = event.GetPosition()
2379        page = getSelection()
2380        if event.ControlDown() and drawingData['showABC']:
2381            if event.LeftIsDown():
2382                SetTestRot(newxy)
2383            elif event.RightIsDown():
2384                SetTestPos(newxy)
2385            elif event.MiddleIsDown():
2386                SetTestRotZ(newxy)
2387            x,y,z = drawingData['testPos'][0]
2388            G2frame.G2plotNB.status.SetStatusText('moving test point %.4f,%.4f,%.4f'%(x,y,z),1)
2389            Draw()
2390                               
2391        if event.Dragging() and not event.ControlDown():
2392            if event.LeftIsDown():
2393                SetRotation(newxy)
2394                angX,angY,angZ = drawingData['Rotation'][:3]
2395                G2frame.G2plotNB.status.SetStatusText('New rotation: %.2f, %.2f ,%.2f'%(angX,angY,angZ),1)
2396            elif event.RightIsDown():
2397                SetTranslation(newxy)
2398                Tx,Ty,Tz = drawingData['viewPoint'][0]
2399                G2frame.G2plotNB.status.SetStatusText('New view point: %.4f, %.4f, %.4f'%(Tx,Ty,Tz),1)
2400            elif event.MiddleIsDown():
2401                SetRotationZ(newxy)
2402                angX,angY,angZ = drawingData['Rotation'][:3]
2403                G2frame.G2plotNB.status.SetStatusText('New rotation: %.2f, %.2f, %.2f'%(angX,angY,angZ),1)
2404            Draw()
2405       
2406    def OnMouseWheel(event):
2407        if event.ShiftDown():
2408            return
2409        drawingData['cameraPos'] += event.GetWheelRotation()/24
2410        drawingData['cameraPos'] = max(10,min(500,drawingData['cameraPos']))
2411        G2frame.G2plotNB.status.SetStatusText('New camera distance: %.2f'%(drawingData['cameraPos']),1)
2412        page = getSelection()
2413        if page:
2414            if G2frame.dataDisplay.GetPageText(page) == 'Draw Options':
2415                panel = G2frame.dataDisplay.GetPage(page).GetChildren()[0].GetChildren()
2416                names = [child.GetName() for child in panel]
2417                panel[names.index('cameraPos')].SetLabel('Camera Position: '+'%.2f'%(drawingData['cameraPos']))
2418                panel[names.index('cameraSlider')].SetValue(drawingData['cameraPos'])
2419            Draw()
2420       
2421    def getSelection():
2422        try:
2423            return G2frame.dataDisplay.GetSelection()
2424        except AttributeError:
2425            G2frame.G2plotNB.status.SetStatusText('Select this from Phase data window!')
2426            return 0
2427           
2428    def SetViewPointText(VP):
2429        page = getSelection()
2430        if page:
2431            if G2frame.dataDisplay.GetPageText(page) == 'Draw Options':
2432                panel = G2frame.dataDisplay.GetPage(page).GetChildren()[0].GetChildren()
2433                names = [child.GetName() for child in panel]
2434                panel[names.index('viewPoint')].SetValue('%.3f, %.3f, %.3f'%(VP[0],VP[1],VP[2]))
2435           
2436    def ClearSelectedAtoms():
2437        page = getSelection()
2438        if page:
2439            if G2frame.dataDisplay.GetPageText(page) == 'Draw Atoms':
2440                G2frame.dataDisplay.GetPage(page).ClearSelection()      #this is the Atoms grid in Draw Atoms
2441            elif G2frame.dataDisplay.GetPageText(page) == 'Map peaks':
2442                G2frame.dataDisplay.GetPage(page).ClearSelection()      #this is the Atoms grid in Atoms
2443            elif G2frame.dataDisplay.GetPageText(page) == 'Atoms':
2444                G2frame.dataDisplay.GetPage(page).ClearSelection()      #this is the Atoms grid in Atoms
2445               
2446                   
2447    def SetSelectedAtoms(ind,Add=False):
2448        page = getSelection()
2449        if page:
2450            if G2frame.dataDisplay.GetPageText(page) == 'Draw Atoms':
2451                G2frame.dataDisplay.GetPage(page).SelectRow(ind,Add)      #this is the Atoms grid in Draw Atoms
2452            elif G2frame.dataDisplay.GetPageText(page) == 'Map peaks':
2453                G2frame.dataDisplay.GetPage(page).SelectRow(ind,Add)                 
2454            elif G2frame.dataDisplay.GetPageText(page) == 'Atoms':
2455                Id = drawAtoms[ind][-2]
2456                for i,atom in enumerate(atomData):
2457                    if atom[-1] == Id:
2458                        G2frame.dataDisplay.GetPage(page).SelectRow(i)      #this is the Atoms grid in Atoms
2459                 
2460    def GetSelectedAtoms():
2461        page = getSelection()
2462        Ind = []
2463        if page:
2464            if G2frame.dataDisplay.GetPageText(page) == 'Draw Atoms':
2465                Ind = G2frame.dataDisplay.GetPage(page).GetSelectedRows()      #this is the Atoms grid in Draw Atoms
2466            elif G2frame.dataDisplay.GetPageText(page) == 'Map peaks':
2467                Ind = G2frame.dataDisplay.GetPage(page).GetSelectedRows()
2468            elif G2frame.dataDisplay.GetPageText(page) == 'Atoms':
2469                Ind = G2frame.dataDisplay.GetPage(page).GetSelectedRows()      #this is the Atoms grid in Atoms
2470        return Ind
2471                                       
2472    def OnKey(event):           #on key UP!!
2473        keyCode = event.GetKeyCode()
2474        if keyCode > 255:
2475            keyCode = 0
2476        key,xyz = chr(keyCode),event.GetPosition()
2477        indx = drawingData['selectedAtoms']
2478        if key in ['C']:
2479            drawingData['viewPoint'] = [[.5,.5,.5],[0,0]]
2480            drawingData['testPos'] = [[-.1,-.1,-.1],[0.0,0.0,0.0],[0,0]]
2481            drawingData['Rotation'] = [0.0,0.0,0.0,[]]
2482            SetViewPointText(drawingData['viewPoint'][0])
2483        elif key in ['N']:
2484            drawAtoms = drawingData['Atoms']
2485            pI = drawingData['viewPoint'][1]
2486            if indx:
2487                pI[0] = indx[pI[1]]
2488                Tx,Ty,Tz = drawAtoms[pI[0]][cx:cx+3]
2489                pI[1] += 1
2490                if pI[1] >= len(indx):
2491                    pI[1] = 0
2492            else:
2493                Tx,Ty,Tz = drawAtoms[pI[0]][cx:cx+3]               
2494                pI[0] += 1
2495                if pI[0] >= len(drawAtoms):
2496                    pI[0] = 0
2497            drawingData['viewPoint'] = [[Tx,Ty,Tz],pI]
2498            SetViewPointText(drawingData['viewPoint'][0])
2499            G2frame.G2plotNB.status.SetStatusText('View point at atom '+drawAtoms[pI[0]][ct-1]+str(pI),1)
2500               
2501        elif key in ['P']:
2502            drawAtoms = drawingData['Atoms']
2503            pI = drawingData['viewPoint'][1]
2504            if indx:
2505                pI[0] = indx[pI[1]]
2506                Tx,Ty,Tz = drawAtoms[pI[0]][cx:cx+3]
2507                pI[1] -= 1
2508                if pI[1] < 0:
2509                    pI[1] = len(indx)-1
2510            else:
2511                Tx,Ty,Tz = drawAtoms[pI[0]][cx:cx+3]               
2512                pI[0] -= 1
2513                if pI[0] < 0:
2514                    pI[0] = len(drawAtoms)-1
2515            drawingData['viewPoint'] = [[Tx,Ty,Tz],pI]
2516            SetViewPointText(drawingData['viewPoint'][0])           
2517            G2frame.G2plotNB.status.SetStatusText('View point at atom '+drawAtoms[pI[0]][ct-1]+str(pI),1)
2518        elif key in ['U','D','L','R'] and mapData['Flip'] == True:
2519            dirDict = {'U':[0,1],'D':[0,-1],'L':[-1,0],'R':[1,0]}
2520            SetMapRoll(dirDict[key])
2521        Draw()
2522           
2523    def SetBackground():
2524        R,G,B,A = Page.camera['backColor']
2525        glClearColor(R,G,B,A)
2526        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
2527       
2528    def SetLights():
2529        glEnable(GL_DEPTH_TEST)
2530        glShadeModel(GL_SMOOTH)
2531        glEnable(GL_LIGHTING)
2532        glEnable(GL_LIGHT0)
2533        glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,0)
2534        glLightfv(GL_LIGHT0,GL_AMBIENT,[1,1,1,.8])
2535        glLightfv(GL_LIGHT0,GL_DIFFUSE,[1,1,1,1])
2536       
2537    def SetMapRoll(newxy):
2538        anglex,angley,anglez,oldxy = drawingData['Rotation']
2539        Rx = G2lat.rotdMat(anglex,0)
2540        Ry = G2lat.rotdMat(angley,1)
2541        Rz = G2lat.rotdMat(anglez,2)
2542        dxy = np.inner(Bmat,np.inner(Rz,np.inner(Ry,np.inner(Rx,newxy+[0,]))))
2543        dxy *= np.array([-1,-1,1])
2544        rho = mapData['rho']
2545        dxy = np.array(dxy*rho.shape)
2546        roll = np.where(dxy>0.5,1,np.where(dxy<-.5,-1,0))
2547        mapData['rho'] = np.roll(np.roll(np.roll(rho,roll[0],axis=0),roll[1],axis=1),roll[2],axis=2)
2548        drawingData['Rotation'][3] = list(newxy)
2549       
2550    def SetTranslation(newxy):
2551        Tx,Ty,Tz = drawingData['viewPoint'][0]
2552        anglex,angley,anglez,oldxy = drawingData['Rotation']
2553        if not len(oldxy): oldxy = list(newxy)
2554        Rx = G2lat.rotdMat(anglex,0)
2555        Ry = G2lat.rotdMat(angley,1)
2556        Rz = G2lat.rotdMat(anglez,2)
2557        dxy = list(newxy-oldxy)+[0,]
2558        dxy = np.inner(Bmat,np.inner(Rz,np.inner(Ry,np.inner(Rx,dxy))))
2559        Tx -= dxy[0]*0.01
2560        Ty += dxy[1]*0.01
2561        Tz -= dxy[2]*0.01
2562        drawingData['Rotation'][3] = list(newxy)
2563        drawingData['viewPoint'][0] =  Tx,Ty,Tz
2564        SetViewPointText([Tx,Ty,Tz])
2565       
2566    def SetTestPos(newxy):
2567        Tx,Ty,Tz = drawingData['testPos'][0]
2568        anglex,angley,anglez,oldxy = drawingData['Rotation']
2569        if not len(oldxy): oldxy = list(newxy)
2570        Rx = G2lat.rotdMat(anglex,0)
2571        Ry = G2lat.rotdMat(angley,1)
2572        Rz = G2lat.rotdMat(anglez,2)
2573        dxy = list(newxy-oldxy)+[0,]
2574        dxy = np.inner(Rz,np.inner(Ry,np.inner(Rx,dxy)))
2575        Tx += dxy[0]*0.001
2576        Ty -= dxy[1]*0.001
2577        Tz += dxy[2]*0.001
2578        drawingData['Rotation'][3] = list(newxy)
2579        drawingData['testPos'][0] =  Tx,Ty,Tz
2580       
2581    def SetTestRot(newxy):
2582        Txyz = np.array(drawingData['testPos'][0])
2583        oldxy = drawingData['testPos'][2]
2584        Ax,Ay,Az = drawingData['testPos'][1]
2585        Vxyz = np.array(drawingData['viewPoint'][0])
2586        Dxyz = np.inner(Amat,Txyz-Vxyz)
2587        dxy = list(newxy-oldxy)+[0,]
2588        Ax += dxy[1]*0.01
2589        Ay += dxy[0]*0.01
2590        Rx = G2lat.rotdMat(Ax,0)
2591        Ry = G2lat.rotdMat(Ay,1)
2592        Dxyz = np.inner(Ry,np.inner(Rx,Dxyz))       
2593        Dxyz = np.inner(Bmat,Dxyz)+Vxyz
2594        drawingData['testPos'][1] = [Ax,Ay,Az]
2595        drawingData['testPos'][2] = newxy
2596        drawingData['testPos'][0] = Dxyz
2597       
2598    def SetTestRotZ(newxy):
2599        Txyz = np.array(drawingData['testPos'][0])
2600        oldxy = drawingData['testPos'][2]
2601        Ax,Ay,Az = drawingData['testPos'][1]
2602        Vxyz = np.array(drawingData['viewPoint'][0])
2603        Dxyz = np.inner(Amat,Txyz-Vxyz)       
2604        dxy = list(newxy-oldxy)+[0,]
2605        Az += (dxy[0]+dxy[1])*.01
2606        Rz = G2lat.rotdMat(Az,2)
2607        Dxyz = np.inner(Rz,Dxyz)       
2608        Dxyz = np.inner(Bmat,Dxyz)+Vxyz
2609        drawingData['testPos'][1] = [Ax,Ay,Az]
2610        drawingData['testPos'][2] = newxy
2611        drawingData['testPos'][0] = Dxyz
2612                             
2613    def SetRotation(newxy):       
2614        anglex,angley,anglez,oldxy = drawingData['Rotation']
2615        if not len(oldxy): oldxy = list(newxy)
2616        dxy = newxy-oldxy
2617        anglex += dxy[1]*.25
2618        angley += dxy[0]*.25
2619        oldxy = newxy
2620        drawingData['Rotation'] = [anglex,angley,anglez,list(oldxy)]
2621       
2622    def SetRotationZ(newxy):                       
2623        anglex,angley,anglez,oldxy = drawingData['Rotation']
2624        if not len(oldxy): oldxy = list(newxy)
2625        dxy = newxy-oldxy
2626        anglez += (dxy[0]+dxy[1])*.25
2627        oldxy = newxy
2628        drawingData['Rotation'] = [anglex,angley,anglez,list(oldxy)]
2629       
2630    def RenderBox():
2631        glEnable(GL_COLOR_MATERIAL)
2632        glLineWidth(2)
2633        glEnable(GL_BLEND)
2634        glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA)
2635        glEnable(GL_LINE_SMOOTH)
2636        glBegin(GL_LINES)
2637        for line,color in zip(uEdges,uColors):
2638            glColor3ubv(color)
2639            glVertex3fv(line[0])
2640            glVertex3fv(line[1])
2641        glEnd()
2642        glColor4ubv([0,0,0,0])
2643        glDisable(GL_LINE_SMOOTH)
2644        glDisable(GL_BLEND)
2645        glDisable(GL_COLOR_MATERIAL)
2646       
2647    def RenderUnitVectors(x,y,z):
2648        xyz = np.array([x,y,z])
2649        glEnable(GL_COLOR_MATERIAL)
2650        glLineWidth(1)
2651        glPushMatrix()
2652        glTranslate(x,y,z)
2653        glScalef(1/cell[0],1/cell[1],1/cell[2])
2654        glBegin(GL_LINES)
2655        for line,color in zip(uEdges,uColors)[:3]:
2656            glColor3ubv(color)
2657            glVertex3fv(line[0])
2658            glVertex3fv(line[1])
2659        glEnd()
2660        glPopMatrix()
2661        glColor4ubv([0,0,0,0])
2662        glDisable(GL_COLOR_MATERIAL)
2663               
2664    def RenderSphere(x,y,z,radius,color):
2665        glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,color)
2666        glPushMatrix()
2667        glTranslate(x,y,z)
2668        glMultMatrixf(B4mat.T)
2669        q = gluNewQuadric()
2670        gluSphere(q,radius,20,10)
2671        glPopMatrix()
2672       
2673    def RenderSmallSphere(x,y,z,radius,color):
2674        glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,color)
2675        glPushMatrix()
2676        glTranslate(x,y,z)
2677        glMultMatrixf(B4mat.T)
2678        q = gluNewQuadric()
2679        gluSphere(q,radius,4,2)
2680        glPopMatrix()
2681       
2682    def RenderEllipsoid(x,y,z,ellipseProb,E,R4,color):
2683        s1,s2,s3 = E
2684        glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,color)
2685        glPushMatrix()
2686        glTranslate(x,y,z)
2687        glMultMatrixf(B4mat.T)
2688        glMultMatrixf(R4.T)
2689        glEnable(GL_NORMALIZE)
2690        glScale(s1,s2,s3)
2691        q = gluNewQuadric()
2692        gluSphere(q,ellipseProb,20,10)
2693        glDisable(GL_NORMALIZE)
2694        glPopMatrix()
2695       
2696    def RenderBonds(x,y,z,Bonds,radius,color,slice=20):
2697        glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,color)
2698        glPushMatrix()
2699        glTranslate(x,y,z)
2700        glMultMatrixf(B4mat.T)
2701        for bond in Bonds:
2702            glPushMatrix()
2703            Dx = np.inner(Amat,bond)
2704            Z = np.sqrt(np.sum(Dx**2))
2705            if Z:
2706                azm = atan2d(-Dx[1],-Dx[0])
2707                phi = acosd(Dx[2]/Z)
2708                glRotate(-azm,0,0,1)
2709                glRotate(phi,1,0,0)
2710                q = gluNewQuadric()
2711                gluCylinder(q,radius,radius,Z,slice,2)
2712            glPopMatrix()           
2713        glPopMatrix()
2714               
2715    def RenderLines(x,y,z,Bonds,color):
2716        xyz = np.array([x,y,z])
2717        glEnable(GL_COLOR_MATERIAL)
2718        glLineWidth(1)
2719        glColor3fv(color)
2720        glPushMatrix()
2721        glBegin(GL_LINES)
2722        for bond in Bonds:
2723            glVertex3fv(xyz)
2724            glVertex3fv(xyz+bond)
2725        glEnd()
2726        glColor4ubv([0,0,0,0])
2727        glPopMatrix()
2728        glDisable(GL_COLOR_MATERIAL)
2729       
2730    def RenderPolyhedra(x,y,z,Faces,color):
2731        glPushMatrix()
2732        glTranslate(x,y,z)
2733        glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,color)
2734        glShadeModel(GL_SMOOTH)
2735        glMultMatrixf(B4mat.T)
2736        for face,norm in Faces:
2737            glPolygonMode(GL_FRONT_AND_BACK,GL_FILL)
2738            glFrontFace(GL_CW)
2739            glNormal3fv(norm)
2740            glBegin(GL_TRIANGLES)
2741            for vert in face:
2742                glVertex3fv(vert)
2743            glEnd()
2744        glPopMatrix()
2745
2746    def RenderMapPeak(x,y,z,color):
2747        vecs = np.array([[[-.01,0,0],[.01,0,0]],[[0,-.01,0],[0,.01,0]],[[0,0,-.01],[0,0,.01]]])
2748        xyz = np.array([x,y,z])
2749        glEnable(GL_COLOR_MATERIAL)
2750        glLineWidth(3)
2751        glColor3fv(color)
2752        glPushMatrix()
2753        glBegin(GL_LINES)
2754        for vec in vecs:
2755            glVertex3fv(vec[0]+xyz)
2756            glVertex3fv(vec[1]+xyz)
2757        glEnd()
2758        glColor4ubv([0,0,0,0])
2759        glPopMatrix()
2760        glDisable(GL_COLOR_MATERIAL)
2761       
2762    def RenderBackbone(Backbone,BackboneColor,radius):
2763        glPushMatrix()
2764        glMultMatrixf(B4mat.T)
2765        glEnable(GL_COLOR_MATERIAL)
2766        glShadeModel(GL_SMOOTH)
2767        gleSetJoinStyle(TUBE_NORM_EDGE | TUBE_JN_ANGLE | TUBE_JN_CAP)
2768        glePolyCylinder(Backbone,BackboneColor,radius)
2769        glPopMatrix()       
2770        glDisable(GL_COLOR_MATERIAL)
2771       
2772    def RenderLabel(x,y,z,label,r):       
2773        glPushMatrix()
2774        glTranslate(x,y,z)
2775        glMultMatrixf(B4mat.T)
2776        glDisable(GL_LIGHTING)
2777        glColor3f(0,1.,0)
2778        glRasterPos3f(r,r,r)
2779        for c in list(label):
2780            glutBitmapCharacter(GLUT_BITMAP_8_BY_13,ord(c))
2781        glEnable(GL_LIGHTING)
2782        glPopMatrix()
2783       
2784    def RenderMap(rho,rhoXYZ,indx,Rok):
2785        cLevel = drawingData['contourLevel']
2786        for i,xyz in enumerate(rhoXYZ):
2787            if not Rok[i]:
2788                x,y,z = xyz
2789                I,J,K = indx[i]
2790                alpha = 1.0
2791                if cLevel < 1.:
2792                    alpha = (abs(rho[I,J,K])/mapData['rhoMax']-cLevel)/(1.-cLevel)
2793                if rho[I,J,K] < 0.:
2794                    RenderSmallSphere(x,y,z,0.1*alpha,Rd)
2795                else:
2796                    RenderSmallSphere(x,y,z,0.1*alpha,Bl)
2797                           
2798    def Draw():
2799        mapData = generalData['Map']
2800        pageName = ''
2801        page = getSelection()
2802        if page:
2803            pageName = G2frame.dataDisplay.GetPageText(page)
2804        rhoXYZ = []
2805        if len(mapData['rho']):
2806            VP = np.array(drawingData['viewPoint'][0])-np.array([.5,.5,.5])
2807            contLevel = drawingData['contourLevel']*mapData['rhoMax']
2808            if 'delt-F' in mapData['MapType']:
2809                rho = ma.array(mapData['rho'],mask=(np.abs(mapData['rho'])<contLevel))
2810            else:
2811                rho = ma.array(mapData['rho'],mask=(mapData['rho']<contLevel))
2812            steps = 1./np.array(rho.shape)
2813            incre = np.where(VP>0,VP%steps,VP%steps-steps)
2814            Vsteps = -np.array(VP/steps,dtype='i')
2815            rho = np.roll(np.roll(np.roll(rho,Vsteps[0],axis=0),Vsteps[1],axis=1),Vsteps[2],axis=2)
2816            indx = np.array(ma.nonzero(rho)).T
2817            rhoXYZ = indx*steps+VP-incre
2818            Nc = len(rhoXYZ)
2819            rcube = 2000.*Vol/(ForthirdPI*Nc)
2820            rmax = math.exp(math.log(rcube)/3.)**2
2821            radius = min(drawingData['mapSize']**2,rmax)
2822            view = np.array(drawingData['viewPoint'][0])
2823            Rok = np.sum(np.inner(Amat,rhoXYZ-view).T**2,axis=1)>radius
2824        Ind = GetSelectedAtoms()
2825        VS = np.array(Page.canvas.GetSize())
2826        aspect = float(VS[0])/float(VS[1])
2827        cPos = drawingData['cameraPos']
2828        Zclip = drawingData['Zclip']*cPos/200.
2829        anglex,angley,anglez = drawingData['Rotation'][:3]
2830        Tx,Ty,Tz = drawingData['viewPoint'][0]
2831        cx,ct,cs = drawingData['atomPtrs']
2832        bondR = drawingData['bondRadius']
2833        G,g = G2lat.cell2Gmat(cell)
2834        GS = G
2835        GS[0][1] = GS[1][0] = math.sqrt(GS[0][0]*GS[1][1])
2836        GS[0][2] = GS[2][0] = math.sqrt(GS[0][0]*GS[2][2])
2837        GS[1][2] = GS[2][1] = math.sqrt(GS[1][1]*GS[2][2])
2838        ellipseProb = G2lat.criticalEllipse(drawingData['ellipseProb']/100.)
2839       
2840        SetBackground()
2841        glInitNames()
2842        glPushName(0)
2843       
2844        glMatrixMode(GL_PROJECTION)
2845        glLoadIdentity()
2846        glViewport(0,0,VS[0],VS[1])
2847        gluPerspective(20.,aspect,cPos-Zclip,cPos+Zclip)
2848        gluLookAt(0,0,cPos,0,0,0,0,1,0)
2849        SetLights()           
2850           
2851        glMatrixMode(GL_MODELVIEW)
2852        glLoadIdentity()
2853        glRotate(anglez,0,0,1)
2854        glRotate(anglex,cosd(anglez),-sind(anglez),0)
2855        glRotate(angley,sind(anglez),cosd(anglez),0)
2856        glMultMatrixf(A4mat.T)
2857        glTranslate(-Tx,-Ty,-Tz)
2858        if drawingData['unitCellBox']:
2859            RenderBox()
2860        if drawingData['showABC']:
2861            x,y,z = drawingData['testPos'][0]
2862#            if altDown:
2863#                G2frame.G2plotNB.status.SetStatusText('moving test point %.4f,%.4f,%.4f'%(x,y,z),1)
2864#            else:
2865#                G2frame.G2plotNB.status.SetStatusText('test point %.4f,%.4f,%.4f'%(x,y,z),1)           
2866            RenderUnitVectors(x,y,z)
2867        Backbone = []
2868        BackboneColor = []
2869        time0 = time.time()
2870#        glEnable(GL_BLEND)
2871#        glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA)
2872        for iat,atom in enumerate(drawingData['Atoms']):
2873            x,y,z = atom[cx:cx+3]
2874            Bonds = atom[-2]
2875            Faces = atom[-1]
2876            try:
2877                atNum = generalData['AtomTypes'].index(atom[ct])
2878            except ValueError:
2879                atNum = -1
2880            CL = atom[cs+2]
2881            color = np.array(CL)/255.
2882            if iat in Ind and G2frame.dataDisplay.GetPageText(getSelection()) != 'Map peaks':
2883                color = np.array(Gr)/255.
2884#            color += [.25,]
2885            radius = 0.5
2886            if atom[cs] != '':
2887                try:
2888                    glLoadName(atom[-3])
2889                except: #problem with old files - missing code
2890                    pass                   
2891            if 'balls' in atom[cs]:
2892                vdwScale = drawingData['vdwScale']
2893                ballScale = drawingData['ballScale']
2894                if atNum < 0:
2895                    radius = 0.2
2896                elif 'H' == atom[ct]:
2897                    if drawingData['showHydrogen']:
2898                        if 'vdW' in atom[cs] and atNum >= 0:
2899                            radius = vdwScale*generalData['vdWRadii'][atNum]
2900                        else:
2901                            radius = ballScale*drawingData['sizeH']
2902                    else:
2903                        radius = 0.0
2904                else:
2905                    if 'vdW' in atom[cs]:
2906                        radius = vdwScale*generalData['vdWRadii'][atNum]
2907                    else:
2908                        radius = ballScale*generalData['BondRadii'][atNum]
2909                RenderSphere(x,y,z,radius,color)
2910                if 'sticks' in atom[cs]:
2911                    RenderBonds(x,y,z,Bonds,bondR,color)
2912            elif 'ellipsoids' in atom[cs]:
2913                RenderBonds(x,y,z,Bonds,bondR,color)
2914                if atom[cs+3] == 'A':                   
2915                    Uij = atom[cs+5:cs+11]
2916                    U = np.multiply(G2spc.Uij2U(Uij),GS)
2917                    U = np.inner(Amat,np.inner(U,Amat).T)
2918                    E,R = nl.eigh(U)
2919                    R4 = np.concatenate((np.concatenate((R,[[0],[0],[0]]),axis=1),[[0,0,0,1],]),axis=0)
2920                    E = np.sqrt(E)
2921                    if atom[ct] == 'H' and not drawingData['showHydrogen']:
2922                        pass
2923                    else:
2924                        RenderEllipsoid(x,y,z,ellipseProb,E,R4,color)                   
2925                else:
2926                    if atom[ct] == 'H' and not drawingData['showHydrogen']:
2927                        pass
2928                    else:
2929                        radius = ellipseProb*math.sqrt(abs(atom[cs+4]))
2930                        RenderSphere(x,y,z,radius,color)
2931            elif 'lines' in atom[cs]:
2932                radius = 0.1
2933                RenderLines(x,y,z,Bonds,color)
2934#                RenderBonds(x,y,z,Bonds,0.05,color,6)
2935            elif atom[cs] == 'sticks':
2936                radius = 0.1
2937                RenderBonds(x,y,z,Bonds,bondR,color)
2938            elif atom[cs] == 'polyhedra':
2939                RenderPolyhedra(x,y,z,Faces,color)
2940            elif atom[cs] == 'backbone':
2941                if atom[ct-1].split()[0] in ['C','N']:
2942                    Backbone.append(list(np.inner(Amat,np.array([x,y,z]))))
2943                    BackboneColor.append(list(color))
2944                   
2945            if atom[cs+1] == 'type':
2946                RenderLabel(x,y,z,atom[ct],radius)
2947            elif atom[cs+1] == 'name':
2948                RenderLabel(x,y,z,atom[ct-1],radius)
2949            elif atom[cs+1] == 'number':
2950                RenderLabel(x,y,z,str(iat),radius)
2951            elif atom[cs+1] == 'residue' and atom[ct-1] == 'CA':
2952                RenderLabel(x,y,z,atom[ct-4],radius)
2953            elif atom[cs+1] == '1-letter' and atom[ct-1] == 'CA':
2954                RenderLabel(x,y,z,atom[ct-3],radius)
2955            elif atom[cs+1] == 'chain' and atom[ct-1] == 'CA':
2956                RenderLabel(x,y,z,atom[ct-2],radius)
2957#        glDisable(GL_BLEND)
2958        if len(rhoXYZ):
2959            RenderMap(rho,rhoXYZ,indx,Rok)
2960        if len(mapPeaks):
2961            for ind,[mag,x,y,z] in enumerate(mapPeaks):
2962                if ind in Ind and pageName == 'Map peaks':
2963                    RenderMapPeak(x,y,z,Gr)
2964                else:
2965                    RenderMapPeak(x,y,z,Wt)
2966        if Backbone:
2967            RenderBackbone(Backbone,BackboneColor,bondR)
2968#        print time.time()-time0
2969        Page.canvas.SwapBuffers()
2970       
2971    def OnSize(event):
2972        Draw()
2973       
2974    def OnFocus(event):
2975        Draw()
2976       
2977    try:
2978        plotNum = G2frame.G2plotNB.plotList.index(generalData['Name'])
2979        Page = G2frame.G2plotNB.nb.GetPage(plotNum)       
2980    except ValueError:
2981        Plot = G2frame.G2plotNB.addOgl(generalData['Name'])
2982        plotNum = G2frame.G2plotNB.plotList.index(generalData['Name'])
2983        Page = G2frame.G2plotNB.nb.GetPage(plotNum)
2984        Page.views = False
2985        view = False
2986        altDown = False
2987    Page.SetFocus()
2988    cb = wx.ComboBox(G2frame.G2plotNB.status,style=wx.CB_DROPDOWN|wx.CB_READONLY,
2989        choices=(' save as:','jpeg','tiff','bmp'))
2990    cb.Bind(wx.EVT_COMBOBOX, OnKeyBox)
2991    cb.SetValue(' save as:')
2992    Page.canvas.Bind(wx.EVT_MOUSEWHEEL, OnMouseWheel)
2993    Page.canvas.Bind(wx.EVT_LEFT_DOWN, OnMouseDown)
2994    Page.canvas.Bind(wx.EVT_RIGHT_DOWN, OnMouseDown)
2995    Page.canvas.Bind(wx.EVT_MIDDLE_DOWN, OnMouseDown)
2996    Page.canvas.Bind(wx.EVT_KEY_UP, OnKey)
2997    Page.canvas.Bind(wx.EVT_MOTION, OnMouseMove)
2998    Page.canvas.Bind(wx.EVT_SIZE, OnSize)
2999    Page.canvas.Bind(wx.EVT_SET_FOCUS, OnFocus)
3000    Page.camera['position'] = drawingData['cameraPos']
3001    Page.camera['viewPoint'] = np.inner(Amat,drawingData['viewPoint'][0])
3002    Page.camera['backColor'] = np.array(list(drawingData['backColor'])+[0,])/255.
3003    Page.canvas.SetCurrent()
3004    Draw()
3005       
Note: See TracBrowser for help on using the repository browser.