source: trunk/GSASIIplot.py @ 750

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

put inverse checker back in SearchMap?
add atom rename facility
update of Map peaks when map/peaks are shifted by U/D/L/R key commands

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