source: trunk/GSASIIplot.py @ 620

Last change on this file since 620 was 620, checked in by vondreele, 10 years ago

remove excessive tabs in source code
fix HKL controls GUI
change HKL reflection record to match the PWDR one
start getting HKLF into fourier & charge flip

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