source: trunk/GSASIIplot.py @ 588

Last change on this file since 588 was 584, checked in by vondreele, 13 years ago

add coding line everywhere
more options in sample parm copy

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