source: trunk/GSASIIphsGUI.py @ 698

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

implement Pawley update from reflection list
a bit more for stress/atrain

  • Property svn:keywords set to Date Author Revision URL Id
File size: 196.8 KB
Line 
1# -*- coding: utf-8 -*-
2#GSASII - phase data display routines
3########### SVN repository information ###################
4# $Date: 2012-08-03 20:50:30 +0000 (Fri, 03 Aug 2012) $
5# $Author: vondreele $
6# $Revision: 698 $
7# $URL: trunk/GSASIIphsGUI.py $
8# $Id: GSASIIphsGUI.py 698 2012-08-03 20:50:30Z vondreele $
9########### SVN repository information ###################
10import wx
11import wx.grid as wg
12import matplotlib as mpl
13import math
14import copy
15import time
16import sys
17import random as ran
18import cPickle
19import GSASIIpath
20GSASIIpath.SetVersionNumber("$Revision: 698 $")
21import GSASIIlattice as G2lat
22import GSASIIspc as G2spc
23import GSASIIElem as G2elem
24import GSASIIElemGUI as G2elemGUI
25import GSASIIplot as G2plt
26import GSASIIgrid as G2gd
27import GSASIIIO as G2IO
28import GSASIIstruct as G2str
29import GSASIImath as G2mth
30import GSASIIpwd as G2pwd
31import numpy as np
32import numpy.linalg as nl
33import numpy.ma as ma
34
35VERY_LIGHT_GREY = wx.Colour(235,235,235)
36WHITE = wx.Colour(255,255,255)
37BLACK = wx.Colour(0,0,0)
38mapDefault = {'MapType':'','RefList':'','Resolution':0.5,
39                'rho':[],'rhoMax':0.,'mapSize':10.0,'cutOff':50.,'Flip':False}
40# trig functions in degrees
41sind = lambda x: math.sin(x*math.pi/180.)
42tand = lambda x: math.tan(x*math.pi/180.)
43cosd = lambda x: math.cos(x*math.pi/180.)
44asind = lambda x: 180.*math.asin(x)/math.pi
45
46class SymOpDialog(wx.Dialog):
47    def __init__(self,parent,SGData,New=True):
48        wx.Dialog.__init__(self,parent,-1,'Select symmetry operator',
49            pos=wx.DefaultPosition,style=wx.DEFAULT_DIALOG_STYLE)
50        panel = wx.Panel(self)
51        self.SGData = SGData
52        self.New = New
53        self.OpSelected = [0,0,0,[0,0,0],False]
54        mainSizer = wx.BoxSizer(wx.VERTICAL)
55        mainSizer.Add((5,5),0)
56        if SGData['SGInv']:
57            choice = ['No','Yes']
58            self.inv = wx.RadioBox(panel,-1,'Choose inversion?',choices=choice)
59            self.inv.Bind(wx.EVT_RADIOBOX, self.OnOpSelect)
60            mainSizer.Add(self.inv,0,wx.ALIGN_CENTER_VERTICAL)
61        mainSizer.Add((5,5),0)
62        if SGData['SGLatt'] != 'P':
63            LattOp = G2spc.Latt2text(SGData['SGLatt']).split(';')
64            self.latt = wx.RadioBox(panel,-1,'Choose cell centering?',choices=LattOp)
65            self.latt.Bind(wx.EVT_RADIOBOX, self.OnOpSelect)
66            mainSizer.Add(self.latt,0,wx.ALIGN_CENTER_VERTICAL)
67        mainSizer.Add((5,5),0)
68        if SGData['SGLaue'] in ['-1','2/m','mmm','4/m','4/mmm']:
69            Ncol = 2
70        else:
71            Ncol = 3
72        OpList = []
73        for M,T in SGData['SGOps']:
74            OpList.append(G2spc.MT2text(M,T))
75        self.oprs = wx.RadioBox(panel,-1,'Choose space group operator?',choices=OpList,
76            majorDimension=Ncol)
77        self.oprs.Bind(wx.EVT_RADIOBOX, self.OnOpSelect)
78        mainSizer.Add(self.oprs,0,wx.ALIGN_CENTER_VERTICAL)
79        mainSizer.Add((5,5),0)
80        mainSizer.Add(wx.StaticText(panel,-1,"   Choose unit cell?"),0,wx.ALIGN_CENTER_VERTICAL)
81        mainSizer.Add((5,5),0)
82        cellSizer = wx.BoxSizer(wx.HORIZONTAL)
83        cellSizer.Add((5,0),0)
84        cellName = ['X','Y','Z']
85        self.cell = []
86        for i in range(3):
87            self.cell.append(wx.SpinCtrl(panel,-1,cellName[i],size=wx.Size(50,20)))
88            self.cell[-1].SetRange(-3,3)
89            self.cell[-1].SetValue(0)
90            self.cell[-1].Bind(wx.EVT_SPINCTRL, self.OnOpSelect)
91            cellSizer.Add(self.cell[-1],0,wx.ALIGN_CENTER_VERTICAL)
92        mainSizer.Add(cellSizer,0,)
93        if self.New:
94            choice = ['No','Yes']
95            self.new = wx.RadioBox(panel,-1,'Generate new positions?',choices=choice)
96            self.new.Bind(wx.EVT_RADIOBOX, self.OnOpSelect)
97            mainSizer.Add(self.new,0,wx.ALIGN_CENTER_VERTICAL)
98        mainSizer.Add((5,5),0)
99
100        OkBtn = wx.Button(panel,-1,"Ok")
101        OkBtn.Bind(wx.EVT_BUTTON, self.OnOk)
102        cancelBtn = wx.Button(panel,-1,"Cancel")
103        cancelBtn.Bind(wx.EVT_BUTTON, self.OnCancel)
104        btnSizer = wx.BoxSizer(wx.HORIZONTAL)
105        btnSizer.Add((20,20),1)
106        btnSizer.Add(OkBtn)
107        btnSizer.Add((20,20),1)
108        btnSizer.Add(cancelBtn)
109        btnSizer.Add((20,20),1)
110
111        mainSizer.Add(btnSizer,0,wx.EXPAND|wx.BOTTOM|wx.TOP, 10)
112        panel.SetSizer(mainSizer)
113        panel.Fit()
114        self.Fit()
115
116    def OnOpSelect(self,event):
117        if self.SGData['SGInv']:
118            self.OpSelected[0] = self.inv.GetSelection()
119        if self.SGData['SGLatt'] != 'P':
120            self.OpSelected[1] = self.latt.GetSelection()
121        self.OpSelected[2] = self.oprs.GetSelection()
122        for i in range(3):
123            self.OpSelected[3][i] = float(self.cell[i].GetValue())
124        if self.New:
125            self.OpSelected[4] = self.new.GetSelection()
126
127    def GetSelection(self):
128        return self.OpSelected
129
130    def OnOk(self,event):
131        parent = self.GetParent()
132        parent.Raise()
133        self.EndModal(wx.ID_OK)
134
135    def OnCancel(self,event):
136        parent = self.GetParent()
137        parent.Raise()
138        self.EndModal(wx.ID_CANCEL)
139
140class DisAglDialog(wx.Dialog):
141   
142    def __default__(self,data,default):
143        if data:
144            self.data = data
145        else:
146            self.data = {}
147            self.data['Name'] = default['Name']
148            self.data['Factors'] = [0.85,0.85]
149            self.data['AtomTypes'] = default['AtomTypes']
150            self.data['BondRadii'] = default['BondRadii']
151            self.data['AngleRadii'] = default['AngleRadii']
152       
153    def __init__(self,parent,data,default):
154        wx.Dialog.__init__(self,parent,-1,'Distance Angle Controls', 
155            pos=wx.DefaultPosition,style=wx.DEFAULT_DIALOG_STYLE)
156        self.default = default
157        self.panel = wx.Panel(self)         #just a dummy - gets destroyed in Draw!
158        self.__default__(data,self.default)
159        self.Draw(self.data)
160               
161    def Draw(self,data):
162        self.panel.Destroy()
163        self.panel = wx.Panel(self)
164        mainSizer = wx.BoxSizer(wx.VERTICAL)
165        mainSizer.Add(wx.StaticText(self.panel,-1,'Controls for phase '+data['Name']),
166            0,wx.ALIGN_CENTER_VERTICAL|wx.LEFT,10)
167        mainSizer.Add((10,10),1)
168       
169        radiiSizer = wx.FlexGridSizer(2,3,5,5)
170        radiiSizer.Add(wx.StaticText(self.panel,-1,' Type'),0,wx.ALIGN_CENTER_VERTICAL)
171        radiiSizer.Add(wx.StaticText(self.panel,-1,'Bond radii'),0,wx.ALIGN_CENTER_VERTICAL)
172        radiiSizer.Add(wx.StaticText(self.panel,-1,'Angle radii'),0,wx.ALIGN_CENTER_VERTICAL)
173        self.objList = {}
174        for id,item in enumerate(self.data['AtomTypes']):
175            radiiSizer.Add(wx.StaticText(self.panel,-1,' '+item),0,wx.ALIGN_CENTER_VERTICAL)
176            bRadii = wx.TextCtrl(self.panel,-1,value='%.3f'%(data['BondRadii'][id]),style=wx.TE_PROCESS_ENTER)
177            self.objList[bRadii.GetId()] = ['BondRadii',id]
178            bRadii.Bind(wx.EVT_TEXT_ENTER,self.OnRadiiVal)
179            bRadii.Bind(wx.EVT_KILL_FOCUS,self.OnRadiiVal)
180            radiiSizer.Add(bRadii,0,wx.ALIGN_CENTER_VERTICAL)
181            aRadii = wx.TextCtrl(self.panel,-1,value='%.3f'%(data['AngleRadii'][id]),style=wx.TE_PROCESS_ENTER)
182            self.objList[aRadii.GetId()] = ['AngleRadii',id]
183            aRadii.Bind(wx.EVT_TEXT_ENTER,self.OnRadiiVal)
184            aRadii.Bind(wx.EVT_KILL_FOCUS,self.OnRadiiVal)
185            radiiSizer.Add(aRadii,0,wx.ALIGN_CENTER_VERTICAL)
186        mainSizer.Add(radiiSizer,0,wx.EXPAND)
187        factorSizer = wx.FlexGridSizer(2,2,5,5)
188        Names = ['Bond','Angle']
189        for i,name in enumerate(Names):
190            factorSizer.Add(wx.StaticText(self.panel,-1,name+' search factor'),0,wx.ALIGN_CENTER_VERTICAL)
191            bondFact = wx.TextCtrl(self.panel,-1,value='%.3f'%(data['Factors'][i]),style=wx.TE_PROCESS_ENTER)
192            self.objList[bondFact.GetId()] = ['Factors',i]
193            bondFact.Bind(wx.EVT_TEXT_ENTER,self.OnRadiiVal)
194            bondFact.Bind(wx.EVT_KILL_FOCUS,self.OnRadiiVal)
195            factorSizer.Add(bondFact)
196        mainSizer.Add(factorSizer,0,wx.EXPAND)
197       
198        OkBtn = wx.Button(self.panel,-1,"Ok")
199        OkBtn.Bind(wx.EVT_BUTTON, self.OnOk)
200        ResetBtn = wx.Button(self.panel,-1,'Reset')
201        ResetBtn.Bind(wx.EVT_BUTTON, self.OnReset)
202        btnSizer = wx.BoxSizer(wx.HORIZONTAL)
203        btnSizer.Add((20,20),1)
204        btnSizer.Add(OkBtn)
205        btnSizer.Add(ResetBtn)
206        btnSizer.Add((20,20),1)
207        mainSizer.Add(btnSizer,0,wx.EXPAND|wx.BOTTOM|wx.TOP, 10)
208        self.panel.SetSizer(mainSizer)
209        self.panel.Fit()
210        self.Fit()
211   
212    def OnRadiiVal(self,event):
213        Obj = event.GetEventObject()
214        item = self.objList[Obj.GetId()]
215        try:
216            self.data[item[0]][item[1]] = float(Obj.GetValue())
217        except ValueError:
218            pass
219        Obj.SetValue("%.3f"%(self.data[item[0]][item[1]]))          #reset in case of error
220       
221    def GetData(self):
222        return self.data
223       
224    def OnOk(self,event):
225        parent = self.GetParent()
226        parent.Raise()
227        self.EndModal(wx.ID_OK)             
228       
229    def OnReset(self,event):
230        data = {}
231        self.__default__(data,self.default)
232        self.Draw(self.data)
233       
234class SingleFloatDialog(wx.Dialog):
235   
236    def __init__(self,parent,title,prompt,value,limits=[0.,1.]):
237        wx.Dialog.__init__(self,parent,-1,title, 
238            pos=wx.DefaultPosition,style=wx.DEFAULT_DIALOG_STYLE)
239        self.panel = wx.Panel(self)         #just a dummy - gets destroyed in Draw!
240        self.limits = limits
241        self.value = value
242        self.prompt = prompt
243        self.Draw()
244       
245    def Draw(self):
246       
247        def OnValItem(event):
248            try:
249                val = float(valItem.GetValue())
250                if val < self.limits[0] or val > self.limits[1]:
251                    raise ValueError
252            except ValueError:
253                val = self.value
254            self.value = val
255            valItem.SetValue('%.5g'%(self.value))
256           
257        self.panel.Destroy()
258        self.panel = wx.Panel(self)
259        mainSizer = wx.BoxSizer(wx.VERTICAL)
260        mainSizer.Add(wx.StaticText(self.panel,-1,self.prompt),0,wx.ALIGN_CENTER)
261        valItem = wx.TextCtrl(self.panel,-1,value='%.5g'%(self.value),style=wx.TE_PROCESS_ENTER)
262        mainSizer.Add(valItem,0,wx.ALIGN_CENTER)
263        valItem.Bind(wx.EVT_TEXT_ENTER,OnValItem)
264        valItem.Bind(wx.EVT_KILL_FOCUS,OnValItem)
265        OkBtn = wx.Button(self.panel,-1,"Ok")
266        OkBtn.Bind(wx.EVT_BUTTON, self.OnOk)
267        CancelBtn = wx.Button(self.panel,-1,'Cancel')
268        CancelBtn.Bind(wx.EVT_BUTTON, self.OnCancel)
269        btnSizer = wx.BoxSizer(wx.HORIZONTAL)
270        btnSizer.Add((20,20),1)
271        btnSizer.Add(OkBtn)
272        btnSizer.Add(CancelBtn)
273        btnSizer.Add((20,20),1)
274        mainSizer.Add(btnSizer,0,wx.EXPAND|wx.BOTTOM|wx.TOP, 10)
275        self.panel.SetSizer(mainSizer)
276        self.panel.Fit()
277        self.Fit()
278
279    def GetValue(self):
280        return self.value
281       
282    def OnOk(self,event):
283        parent = self.GetParent()
284        parent.Raise()
285        self.EndModal(wx.ID_OK)             
286       
287    def OnCancel(self,event):
288        parent = self.GetParent()
289        parent.Raise()
290        self.EndModal(wx.ID_CANCEL)             
291       
292def FindAtomIndexByIDs(atomData,IDs,Draw=True):
293    indx = []
294    for i,atom in enumerate(atomData):
295        if Draw and atom[-3] in IDs:
296            indx.append(i)
297        elif atom[-1] in IDs:
298            indx.append(i)
299    return indx
300       
301def UpdatePhaseData(G2frame,Item,data,oldPage):
302
303    Atoms = []
304    if G2frame.dataDisplay:
305        G2frame.dataDisplay.Destroy()
306    PhaseName = G2frame.PatternTree.GetItemText(Item)
307    G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.BlankMenu)
308    G2frame.dataFrame.SetLabel('Phase Data for '+PhaseName)
309    G2frame.dataFrame.CreateStatusBar()
310    G2frame.dataDisplay = G2gd.GSNoteBook(parent=G2frame.dataFrame,size=G2frame.dataFrame.GetClientSize())
311
312    def SetupGeneral():
313        generalData = data['General']
314        atomData = data['Atoms']
315        generalData['AtomTypes'] = []
316        generalData['Isotopes'] = {}
317# various patches
318        if 'Isotope' not in generalData:
319            generalData['Isotope'] = {}
320        if 'Data plot type' not in generalData:
321            generalData['Data plot type'] = 'Mustrain'
322        if 'POhkl' not in generalData:
323            generalData['POhkl'] = [0,0,1]
324        if 'Map' not in generalData:
325            generalData['Map'] = mapDefault
326        if 'Flip' not in generalData:
327            generalData['Flip'] = {'RefList':'','Resolution':0.5,'Norm element':'None',
328                'k-factor':0.1}
329        if 'doPawley' not in generalData:
330            generalData['doPawley'] = False
331        if 'Pawley dmin' not in generalData:
332            generalData['Pawley dmin'] = 1.0
333           
334#        if 'SH Texture' not in generalData:
335#            generalData['SH Texture'] = data['SH Texture']
336        generalData['NoAtoms'] = {}
337        generalData['BondRadii'] = []
338        generalData['AngleRadii'] = []
339        generalData['vdWRadii'] = []
340        generalData['AtomMass'] = []
341        generalData['Color'] = []
342        generalData['Mydir'] = G2frame.dirname
343        cx,ct,cs,cia = [3,1,7,9]
344        generalData['AtomPtrs'] = [cx,ct,cs,cia]
345        if generalData['Type'] =='macromolecular':
346            cx,ct,cs,cia = [6,4,10,12]
347            generalData['AtomPtrs'] = [cx,ct,cs,cia]
348        for atom in atomData:
349            atom[ct] = atom[ct].lower().capitalize()              #force to standard form
350            if generalData['AtomTypes'].count(atom[ct]):
351                generalData['NoAtoms'][atom[ct]] += atom[cs-1]*float(atom[cs+1])
352            elif atom[ct] != 'UNK':
353                Info = G2elem.GetAtomInfo(atom[ct])
354                generalData['AtomTypes'].append(atom[ct])
355                generalData['Z'] = Info['Z']
356                generalData['Isotopes'][atom[ct]] = Info['Isotopes']
357                generalData['BondRadii'].append(Info['Drad'])
358                generalData['AngleRadii'].append(Info['Arad'])
359                generalData['vdWRadii'].append(Info['Vdrad'])
360                if atom[ct] in generalData['Isotope']:
361                    generalData['AtomMass'].append(Info['Isotopes'][generalData['Isotope'][atom[ct]]][0])
362                else:
363                    generalData['Isotope'][atom[ct]] = 'Nat. Abund.'
364                    generalData['AtomMass'].append(Info['Mass'])
365                generalData['NoAtoms'][atom[ct]] = atom[cs-1]*float(atom[cs+1])
366                generalData['Color'].append(Info['Color'])
367        F000X = 0.
368        F000N = 0.
369        for i,elem in enumerate(generalData['AtomTypes']):
370            F000X += generalData['NoAtoms'][elem]*generalData['Z']
371            isotope = generalData['Isotope'][elem]
372            F000N += generalData['NoAtoms'][elem]*generalData['Isotopes'][elem][isotope][1]
373        generalData['F000X'] = F000X
374        generalData['F000N'] = F000N
375       
376
377################################################################################
378##### General phase routines
379################################################################################
380
381    def UpdateGeneral():
382       
383        ''' default dictionary structure for phase data: (taken from GSASII.py)
384        'General':{
385            'Name':PhaseName
386            'Type':'nuclear'
387            'SGData':SGData
388            'Cell':[False,10.,10.,10.,90.,90.,90,1000.]
389            'AtomPtrs':[]
390            'Histogram list':['',]
391            'Pawley dmin':1.0}
392        'Atoms':[]
393        'Drawing':{}
394        '''
395       
396        phaseTypes = ['nuclear','modulated','magnetic','macromolecular']
397        SetupGeneral()
398        generalData = data['General']
399        Map = generalData['Map']
400        Flip = generalData['Flip'] 
401        PWDR = any(['PWDR' in item for item in data['Histograms'].keys()])
402       
403        def NameSizer():
404                   
405            def OnPhaseName(event):
406                oldName = generalData['Name']
407                generalData['Name'] = NameTxt.GetValue()
408                G2frame.G2plotNB.Rename(oldName,generalData['Name'])
409                G2frame.dataFrame.SetLabel('Phase Data for '+generalData['Name'])
410                G2frame.PatternTree.SetItemText(Item,generalData['Name'])
411                #Hmm, need to change phase name key in Reflection Lists for each histogram
412                           
413            def OnPhaseType(event):
414                if not generalData['AtomTypes']:             #can change only if no atoms!
415                    generalData['Type'] = TypeTxt.GetValue()
416                    dataDisplay.DestroyChildren()           #needed to clear away bad cellSizer, etc.
417                    wx.CallAfter(UpdateGeneral)
418                else:
419                    TypeTxt.SetValue(generalData['Type'])               
420               
421            def OnSpaceGroup(event):
422                SpcGp = SGTxt.GetValue()
423                SGErr,SGData = G2spc.SpcGroup(SpcGp)
424                if SGErr:
425                    text = [G2spc.SGErrors(SGErr)+'\nSpace Group set to previous']
426                    SGTxt.SetValue(generalData['SGData']['SpGrp'])
427                    msg = 'Space Group Error'
428                    Style = wx.ICON_EXCLAMATION
429                else:
430                    text = G2spc.SGPrint(SGData)
431                    generalData['SGData'] = SGData
432                    msg = 'Space Group Information'
433                    Style = wx.ICON_INFORMATION
434                Text = ''
435                for line in text:
436                    Text += line+'\n'
437                wx.MessageBox(Text,caption=msg,style=Style)
438                dataDisplay.DestroyChildren()           #needed to clear away bad cellSizer, etc.
439                wx.CallAfter(UpdateGeneral)
440               
441            nameSizer = wx.BoxSizer(wx.HORIZONTAL)
442            nameSizer.Add(wx.StaticText(dataDisplay,-1,' Phase name: '),0,wx.ALIGN_CENTER_VERTICAL)
443            NameTxt = wx.TextCtrl(dataDisplay,-1,value=generalData['Name'],style=wx.TE_PROCESS_ENTER)
444            NameTxt.Bind(wx.EVT_TEXT_ENTER,OnPhaseName)
445            NameTxt.Bind(wx.EVT_KILL_FOCUS,OnPhaseName)
446            nameSizer.Add(NameTxt,0,wx.ALIGN_CENTER_VERTICAL)
447            nameSizer.Add(wx.StaticText(dataDisplay,-1,'  Phase type: '),0,wx.ALIGN_CENTER_VERTICAL)
448            if len(data['Atoms']):
449                choices = phaseTypes[:-1]
450            else:
451                choices = phaseTypes           
452            TypeTxt = wx.ComboBox(dataDisplay,-1,value=generalData['Type'],choices=choices,
453                style=wx.CB_READONLY|wx.CB_DROPDOWN)
454            TypeTxt.Bind(wx.EVT_COMBOBOX, OnPhaseType)
455            nameSizer.Add(TypeTxt,0,wx.ALIGN_CENTER_VERTICAL)
456            nameSizer.Add(wx.StaticText(dataDisplay,-1,'  Space group: '),0,wx.ALIGN_CENTER_VERTICAL)
457            SGTxt = wx.TextCtrl(dataDisplay,-1,value=generalData['SGData']['SpGrp'],style=wx.TE_PROCESS_ENTER)
458            SGTxt.Bind(wx.EVT_TEXT_ENTER,OnSpaceGroup)
459            nameSizer.Add(SGTxt,0,wx.ALIGN_CENTER_VERTICAL)
460            return nameSizer
461           
462        def CellSizer():
463           
464            cellGUIlist = [[['m3','m3m'],4,zip([" Unit cell: a = "," Vol = "],["%.5f","%.3f"],[True,False],[0,0])],
465            [['3R','3mR'],6,zip([" a = "," alpha = "," Vol = "],["%.5f","%.3f","%.3f"],[True,True,False],[0,2,0])],
466            [['3','3m1','31m','6/m','6/mmm','4/m','4/mmm'],6,zip([" a = "," c = "," Vol = "],["%.5f","%.5f","%.3f"],[True,True,False],[0,2,0])],
467            [['mmm'],8,zip([" a = "," b = "," c = "," Vol = "],["%.5f","%.5f","%.5f","%.3f"],
468                [True,True,True,False],[0,1,2,0])],
469            [['2/m'+'a'],10,zip([" a = "," b = "," c = "," alpha = "," Vol = "],
470                ["%.5f","%.5f","%.5f","%.3f","%.3f"],[True,True,True,True,False],[0,1,2,4,0])],
471            [['2/m'+'b'],10,zip([" a = "," b = "," c = "," beta = "," Vol = "],
472                ["%.5f","%.5f","%.5f","%.3f","%.3f"],[True,True,True,True,False],[0,1,2,4,0])],
473            [['2/m'+'c'],10,zip([" a = "," b = "," c = "," gamma = "," Vol = "],
474                ["%.5f","%.5f","%.5f","%.3f","%.3f"],[True,True,True,True,False],[0,1,2,4,0])],
475            [['-1'],8,zip([" a = "," b = "," c = "," Vol = "," alpha = "," beta = "," gamma = "],
476                ["%.5f","%.5f","%.5f","%.3f","%.3f","%.3f","%.3f"],
477                [True,True,True,False,True,True,True],[0,1,2,0,3,4,5])]]
478               
479            def OnCellRef(event):
480                generalData['Cell'][0] = cellRef.GetValue()
481               
482            def OnCellChange(event):
483                SGData = generalData['SGData']
484                laue = SGData['SGLaue']
485                if laue == '2/m':
486                    laue += SGData['SGUniq']
487                cell = generalData['Cell']
488                Obj = event.GetEventObject()
489                ObjId = cellList.index(Obj.GetId())
490                try:
491                    value = max(1.0,float(Obj.GetValue()))
492                except ValueError:
493                    if ObjId < 3:               #bad cell edge - reset
494                        value = controls[6+ObjId]
495                    else:                       #bad angle
496                        value = 90.
497                if laue in ['m3','m3m']:
498                    cell[1] = cell[2] = cell[3] = value
499                    cell[4] = cell[5] = cell[6] = 90.0
500                    Obj.SetValue("%.5f"%(cell[1]))
501                elif laue in ['3R','3mR']:
502                    if ObjId == 0:
503                        cell[1] = cell[2] = cell[3] = value
504                        Obj.SetValue("%.5f"%(cell[1]))
505                    else:
506                        cell[4] = cell[5] = cell[6] = value
507                        Obj.SetValue("%.5f"%(cell[4]))
508                elif laue in ['3','3m1','31m','6/m','6/mmm','4/m','4/mmm']:                   
509                    cell[4] = cell[5] = 90.
510                    cell[6] = 120.
511                    if laue in ['4/m','4/mmm']:
512                        cell[6] = 90.
513                    if ObjId == 0:
514                        cell[1] = cell[2] = value
515                        Obj.SetValue("%.5f"%(cell[1]))
516                    else:
517                        cell[3] = value
518                        Obj.SetValue("%.5f"%(cell[3]))
519                elif laue in ['mmm']:
520                    cell[ObjId+1] = value
521                    cell[4] = cell[5] = cell[6] = 90.
522                    Obj.SetValue("%.5f"%(cell[ObjId+1]))
523                elif laue in ['2/m'+'a']:
524                    cell[5] = cell[6] = 90.
525                    if ObjId != 3:
526                        cell[ObjId+1] = value
527                        Obj.SetValue("%.5f"%(cell[ObjId+1]))
528                    else:
529                        cell[4] = value
530                        Obj.SetValue("%.3f"%(cell[4]))
531                elif laue in ['2/m'+'b']:
532                    cell[4] = cell[6] = 90.
533                    if ObjId != 3:
534                        cell[ObjId+1] = value
535                        Obj.SetValue("%.5f"%(cell[ObjId+1]))
536                    else:
537                        cell[5] = value
538                        Obj.SetValue("%.3f"%(cell[5]))
539                elif laue in ['2/m'+'c']:
540                    cell[5] = cell[6] = 90.
541                    if ObjId != 3:
542                        cell[ObjId+1] = value
543                        Obj.SetValue("%.5f"%(cell[ObjId+1]))
544                    else:
545                        cell[6] = value
546                        Obj.SetValue("%.3f"%(cell[6]))
547                else:
548                    cell[ObjId+1] = value
549                    if ObjId < 3:
550                        Obj.SetValue("%.5f"%(cell[1+ObjId]))
551                    else:
552                        Obj.SetValue("%.3f"%(cell[1+ObjId]))                       
553                cell[7] = G2lat.calc_V(G2lat.cell2A(cell[1:7]))
554                volVal.SetValue("%.3f"%(cell[7]))
555                generalData['Cell'] = cell
556                dataDisplay.DestroyChildren()           #needed to clear away bad cellSizer, etc.
557                wx.CallAfter(UpdateGeneral)
558           
559            cell = generalData['Cell']
560            laue = generalData['SGData']['SGLaue']
561            if laue == '2/m':
562                laue += generalData['SGData']['SGUniq']
563            for cellGUI in cellGUIlist:
564                if laue in cellGUI[0]:
565                    useGUI = cellGUI
566            cellSizer = wx.FlexGridSizer(2,useGUI[1]+1,5,5)
567            if PWDR:
568                cellRef = wx.CheckBox(dataDisplay,-1,label='Refine unit cell:')
569                cellSizer.Add(cellRef,0,wx.ALIGN_CENTER_VERTICAL)
570                cellRef.Bind(wx.EVT_CHECKBOX, OnCellRef)
571                cellRef.SetValue(cell[0])
572            cellList = []
573            for txt,fmt,ifEdit,Id in useGUI[2]:
574                cellSizer.Add(wx.StaticText(dataDisplay,label=txt),0,wx.ALIGN_CENTER_VERTICAL)
575                if ifEdit:          #a,b,c,etc.
576                    cellVal = wx.TextCtrl(dataDisplay,value=(fmt%(cell[Id+1])),
577                        style=wx.TE_PROCESS_ENTER)
578                    cellVal.Bind(wx.EVT_TEXT_ENTER,OnCellChange)       
579                    cellVal.Bind(wx.EVT_KILL_FOCUS,OnCellChange)
580                    cellSizer.Add(cellVal,0,wx.ALIGN_CENTER_VERTICAL)
581                    cellList.append(cellVal.GetId())
582                else:               #volume
583                    volVal = wx.TextCtrl(dataDisplay,value=(fmt%(cell[7])),style=wx.TE_READONLY)
584                    volVal.SetBackgroundColour(VERY_LIGHT_GREY)
585                    cellSizer.Add(volVal,0,wx.ALIGN_CENTER_VERTICAL)
586            return cellSizer
587           
588        def ElemSizer():
589           
590            def OnIsotope(event):
591                Obj = event.GetEventObject()
592                item = Indx[Obj.GetId()]
593                isotope = Obj.GetValue()
594                generalData['Isotope'][item] = isotope
595                indx = generalData['AtomTypes'].index(item)
596                data['General']['AtomMass'][indx] = generalData['Isotopes'][item][isotope][0]
597                dataDisplay.DestroyChildren()           #needed to clear away bad cellSizer, etc.
598                wx.CallAfter(UpdateGeneral)
599               
600            elemSizer = wx.FlexGridSizer(8,len(generalData['AtomTypes'])+1,1,1)
601            elemSizer.Add(wx.StaticText(dataDisplay,label=' Elements'),0,wx.ALIGN_CENTER_VERTICAL)
602            for elem in generalData['AtomTypes']:
603                typTxt = wx.TextCtrl(dataDisplay,value=elem,style=wx.TE_READONLY)
604                typTxt.SetBackgroundColour(VERY_LIGHT_GREY)
605                elemSizer.Add(typTxt,0,wx.ALIGN_CENTER_VERTICAL)
606            elemSizer.Add(wx.StaticText(dataDisplay,label=' Isotope'),0,wx.ALIGN_CENTER_VERTICAL)
607            for elem in generalData['AtomTypes']:
608                choices = generalData['Isotopes'][elem].keys()
609                isoSel = wx.ComboBox(dataDisplay,-1,value=generalData['Isotope'][elem],choices=choices,
610                    style=wx.CB_READONLY|wx.CB_DROPDOWN)
611                isoSel.Bind(wx.EVT_COMBOBOX,OnIsotope)
612                Indx[isoSel.GetId()] = elem
613                elemSizer.Add(isoSel,1,wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
614            elemSizer.Add(wx.StaticText(dataDisplay,label=' No. per cell'),0,wx.ALIGN_CENTER_VERTICAL)
615            for elem in generalData['AtomTypes']:
616                numbTxt = wx.TextCtrl(dataDisplay,value='%.1f'%(generalData['NoAtoms'][elem]),
617                    style=wx.TE_READONLY)
618                numbTxt.SetBackgroundColour(VERY_LIGHT_GREY)
619                elemSizer.Add(numbTxt,0,wx.ALIGN_CENTER_VERTICAL)
620            elemSizer.Add(wx.StaticText(dataDisplay,label=' Atom weight'),0,wx.ALIGN_CENTER_VERTICAL)
621            for wt in generalData['AtomMass']:
622                wtTxt = wx.TextCtrl(dataDisplay,value='%.3f'%(wt),style=wx.TE_READONLY)
623                wtTxt.SetBackgroundColour(VERY_LIGHT_GREY)
624                elemSizer.Add(wtTxt,0,wx.ALIGN_CENTER_VERTICAL)
625            elemSizer.Add(wx.StaticText(dataDisplay,label=' Bond radii'),0,wx.ALIGN_CENTER_VERTICAL)
626            for rad in generalData['BondRadii']:
627                bondRadii = wx.TextCtrl(dataDisplay,value='%.2f'%(rad),style=wx.TE_READONLY)
628                bondRadii.SetBackgroundColour(VERY_LIGHT_GREY)
629                elemSizer.Add(bondRadii,0,wx.ALIGN_CENTER_VERTICAL)
630            elemSizer.Add(wx.StaticText(dataDisplay,label=' Angle radii'),0,wx.ALIGN_CENTER_VERTICAL)
631            for rad in generalData['AngleRadii']:
632                elemTxt = wx.TextCtrl(dataDisplay,value='%.2f'%(rad),style=wx.TE_READONLY)
633                elemTxt.SetBackgroundColour(VERY_LIGHT_GREY)
634                elemSizer.Add(elemTxt,0,wx.ALIGN_CENTER_VERTICAL)
635            elemSizer.Add(wx.StaticText(dataDisplay,label=' van der Waals radii'),0,wx.ALIGN_CENTER_VERTICAL)
636            for rad in generalData['vdWRadii']:
637                elemTxt = wx.TextCtrl(dataDisplay,value='%.2f'%(rad),style=wx.TE_READONLY)
638                elemTxt.SetBackgroundColour(VERY_LIGHT_GREY)
639                elemSizer.Add(elemTxt,0,wx.ALIGN_CENTER_VERTICAL)
640            elemSizer.Add(wx.StaticText(dataDisplay,label=' Default color'),0,wx.ALIGN_CENTER_VERTICAL)
641            for R,G,B in generalData['Color']:
642                colorTxt = wx.TextCtrl(dataDisplay,value='',style=wx.TE_READONLY)
643                colorTxt.SetBackgroundColour(wx.Colour(R,G,B))
644                elemSizer.Add(colorTxt,0,wx.ALIGN_CENTER_VERTICAL)
645            return elemSizer
646           
647        def DenSizer():
648           
649            mass = 0.
650            for i,elem in enumerate(generalData['AtomTypes']):
651                mass += generalData['NoAtoms'][elem]*generalData['AtomMass'][i]
652            denSizer = wx.BoxSizer(wx.HORIZONTAL)
653            denSizer.Add(wx.StaticText(dataDisplay,-1,' Density: '),0,wx.ALIGN_CENTER_VERTICAL)
654            Volume = generalData['Cell'][7]
655            density = mass/(0.6022137*Volume)
656            denTxt = wx.TextCtrl(dataDisplay,-1,'%.3f'%(density),style=wx.TE_READONLY)
657            denTxt.SetBackgroundColour(VERY_LIGHT_GREY)
658            denSizer.Add(denTxt,0,wx.ALIGN_CENTER_VERTICAL)       
659            if generalData['Type'] == 'macromolecular' and mass > 0.0:
660                denSizer.Add(wx.StaticText(dataDisplay,-1,' Matthews coeff.: '),
661                    0,wx.ALIGN_CENTER_VERTICAL)
662                mattTxt = wx.TextCtrl(dataDisplay,-1,'%.3f'%(Volume/mass),style=wx.TE_READONLY)
663                mattTxt.SetBackgroundColour(VERY_LIGHT_GREY)
664                denSizer.Add(mattTxt,0,wx.ALIGN_CENTER_VERTICAL)
665            return denSizer
666           
667        def PawleySizer():
668           
669            def OnPawleyRef(event):
670                generalData['doPawley'] = pawlRef.GetValue()
671           
672            def OnPawleyVal(event):
673                try:
674                    dmin = float(pawlVal.GetValue())
675                    if 0.25 <= dmin <= 20.:
676                        generalData['Pawley dmin'] = dmin
677                except ValueError:
678                    pass
679                pawlVal.SetValue("%.3f"%(generalData['Pawley dmin']))          #reset in case of error               
680           
681            pawleySizer = wx.BoxSizer(wx.HORIZONTAL)
682            pawleySizer.Add(wx.StaticText(dataDisplay,label=' Pawley controls: '),0,wx.ALIGN_CENTER_VERTICAL)
683            pawlRef = wx.CheckBox(dataDisplay,-1,label=' Do Pawley refinement?')
684            pawlRef.SetValue(generalData['doPawley'])
685            pawlRef.Bind(wx.EVT_CHECKBOX,OnPawleyRef)
686            pawleySizer.Add(pawlRef,0,wx.ALIGN_CENTER_VERTICAL)
687            pawleySizer.Add(wx.StaticText(dataDisplay,label=' Pawley dmin: '),0,wx.ALIGN_CENTER_VERTICAL)
688            pawlVal = wx.TextCtrl(dataDisplay,value='%.3f'%(generalData['Pawley dmin']),style=wx.TE_PROCESS_ENTER)
689            pawlVal.Bind(wx.EVT_TEXT_ENTER,OnPawleyVal)       
690            pawlVal.Bind(wx.EVT_KILL_FOCUS,OnPawleyVal)
691            pawleySizer.Add(pawlVal,0,wx.ALIGN_CENTER_VERTICAL)
692            return pawleySizer
693           
694        def MapSizer():
695           
696            def OnMapType(event):
697                Map['MapType'] = mapType.GetValue()
698               
699            def OnRefList(event):
700                Map['RefList'] = refList.GetValue()
701               
702            def OnResVal(event):
703                try:
704                    res = float(mapRes.GetValue())
705                    if 0.25 <= res <= 20.:
706                        Map['Resolution'] = res
707                except ValueError:
708                    pass
709                mapRes.SetValue("%.2f"%(Map['Resolution']))          #reset in case of error
710           
711            def OnCutOff(event):
712                try:
713                    res = float(cutOff.GetValue())
714                    if 1.0 <= res <= 100.:
715                        Map['cutOff'] = res
716                except ValueError:
717                    pass
718                cutOff.SetValue("%.1f"%(Map['cutOff']))          #reset in case of error
719           
720            #patch
721            if 'cutOff' not in Map:
722                Map['cutOff'] = 100.0
723            mapTypes = ['Fobs','Fcalc','delt-F','2*Fo-Fc','Patterson']
724            refList = data['Histograms'].keys()
725            if not generalData['AtomTypes']:
726                 mapTypes = ['Patterson',]
727                 Map['MapType'] = 'Patterson'
728            mapSizer = wx.BoxSizer(wx.VERTICAL)
729            lineSizer = wx.BoxSizer(wx.HORIZONTAL)
730            lineSizer.Add(wx.StaticText(dataDisplay,label=' Fourier map controls: Map type: '),0,wx.ALIGN_CENTER_VERTICAL)
731            mapType = wx.ComboBox(dataDisplay,-1,value=Map['MapType'],choices=mapTypes,
732                style=wx.CB_READONLY|wx.CB_DROPDOWN)
733            mapType.Bind(wx.EVT_COMBOBOX,OnMapType)
734            lineSizer.Add(mapType,0,wx.ALIGN_CENTER_VERTICAL)
735            lineSizer.Add(wx.StaticText(dataDisplay,label=' Reflection set from: '),0,wx.ALIGN_CENTER_VERTICAL)
736            refList = wx.ComboBox(dataDisplay,-1,value=Map['RefList'],choices=refList,
737                style=wx.CB_READONLY|wx.CB_DROPDOWN)
738            refList.Bind(wx.EVT_COMBOBOX,OnRefList)
739            lineSizer.Add(refList,0,wx.ALIGN_CENTER_VERTICAL)
740            mapSizer.Add(lineSizer,0,wx.ALIGN_CENTER_VERTICAL)
741            line2Sizer = wx.BoxSizer(wx.HORIZONTAL)
742            line2Sizer.Add(wx.StaticText(dataDisplay,label=' Resolution: '),0,wx.ALIGN_CENTER_VERTICAL)
743            mapRes =  wx.TextCtrl(dataDisplay,value='%.2f'%(Map['Resolution']),style=wx.TE_PROCESS_ENTER)
744            mapRes.Bind(wx.EVT_TEXT_ENTER,OnResVal)       
745            mapRes.Bind(wx.EVT_KILL_FOCUS,OnResVal)
746            line2Sizer.Add(mapRes,0,wx.ALIGN_CENTER_VERTICAL)
747            line2Sizer.Add(wx.StaticText(dataDisplay,label=' Peak cutoff %: '),0,wx.ALIGN_CENTER_VERTICAL)
748            cutOff =  wx.TextCtrl(dataDisplay,value='%.1f'%(Map['cutOff']),style=wx.TE_PROCESS_ENTER)
749            cutOff.Bind(wx.EVT_TEXT_ENTER,OnCutOff)       
750            cutOff.Bind(wx.EVT_KILL_FOCUS,OnCutOff)
751            line2Sizer.Add(cutOff,0,wx.ALIGN_CENTER_VERTICAL)
752            mapSizer.Add(line2Sizer,0,wx.ALIGN_CENTER_VERTICAL)
753            return mapSizer
754               
755        def FlipSizer():
756           
757            def OnRefList(event):
758                Flip['RefList'] = refList.GetValue()
759               
760            def OnNormElem(event):
761                PE = G2elemGUI.PickElement(G2frame,ifNone=True)
762                if PE.ShowModal() == wx.ID_OK:
763                    Flip['Norm element'] = PE.Elem.strip()
764                    normElem.SetLabel(Flip['Norm element'])
765                PE.Destroy()               
766               
767            def OnResVal(event):
768                try:
769                    res = float(flipRes.GetValue())
770                    if 0.25 <= res <= 20.:
771                        Flip['Resolution'] = res
772                except ValueError:
773                    pass
774                flipRes.SetValue("%.2f"%(Flip['Resolution']))          #reset in case of error
775           
776            def OnkFactor(event):
777                try:
778                    res = float(kFactor.GetValue())
779                    if 0.1 <= res <= 1.2:
780                        Flip['k-factor'] = res
781                except ValueError:
782                    pass
783                kFactor.SetValue("%.3f"%(Flip['k-factor']))          #reset in case of error
784           
785            refList = data['Histograms'].keys()
786            flipSizer = wx.BoxSizer(wx.VERTICAL)
787            lineSizer = wx.BoxSizer(wx.HORIZONTAL)
788            lineSizer.Add(wx.StaticText(dataDisplay,label=' Charge flip controls: Reflection set from: '),0,wx.ALIGN_CENTER_VERTICAL)
789            refList = wx.ComboBox(dataDisplay,-1,value=Flip['RefList'],choices=refList,
790                style=wx.CB_READONLY|wx.CB_DROPDOWN)
791            refList.Bind(wx.EVT_COMBOBOX,OnRefList)
792            lineSizer.Add(refList,0,wx.ALIGN_CENTER_VERTICAL)
793            flipSizer.Add(lineSizer,0,wx.ALIGN_CENTER_VERTICAL)
794            line2Sizer = wx.BoxSizer(wx.HORIZONTAL)
795            line2Sizer.Add(wx.StaticText(dataDisplay,label=' Normalizing element: '),0,wx.ALIGN_CENTER_VERTICAL)
796            normElem = wx.Button(dataDisplay,label=Flip['Norm element'],style=wx.TE_READONLY)
797            normElem.Bind(wx.EVT_BUTTON,OnNormElem)
798            line2Sizer.Add(normElem,0,wx.ALIGN_CENTER_VERTICAL)
799            line2Sizer.Add(wx.StaticText(dataDisplay,label=' Resolution: '),0,wx.ALIGN_CENTER_VERTICAL)
800            flipRes =  wx.TextCtrl(dataDisplay,value='%.2f'%(Flip['Resolution']),style=wx.TE_PROCESS_ENTER)
801            flipRes.Bind(wx.EVT_TEXT_ENTER,OnResVal)       
802            flipRes.Bind(wx.EVT_KILL_FOCUS,OnResVal)
803            line2Sizer.Add(flipRes,0,wx.ALIGN_CENTER_VERTICAL)
804            line2Sizer.Add(wx.StaticText(dataDisplay,label=' k-Factor (0.1-1.2): '),0,wx.ALIGN_CENTER_VERTICAL)
805            kFactor =  wx.TextCtrl(dataDisplay,value='%.3f'%(Flip['k-factor']),style=wx.TE_PROCESS_ENTER)
806            kFactor.Bind(wx.EVT_TEXT_ENTER,OnkFactor)       
807            kFactor.Bind(wx.EVT_KILL_FOCUS,OnkFactor)
808            line2Sizer.Add(kFactor,0,wx.ALIGN_CENTER_VERTICAL)
809            flipSizer.Add(line2Sizer,0,wx.ALIGN_CENTER_VERTICAL)
810            return flipSizer
811               
812        General.DestroyChildren()
813        dataDisplay = wx.Panel(General)
814        mainSizer = wx.BoxSizer(wx.VERTICAL)
815        mainSizer.Add((5,5),0)
816        mainSizer.Add(NameSizer(),0)
817        mainSizer.Add((5,5),0)       
818        mainSizer.Add(CellSizer(),0)
819        mainSizer.Add((5,5),0)
820       
821        Indx = {}
822        if len(generalData['AtomTypes']):
823            mainSizer.Add(DenSizer())
824            mainSizer.Add((5,5),0)           
825            mainSizer.Add(ElemSizer())
826           
827        mainSizer.Add((5,5),0)
828        mainSizer.Add(PawleySizer())
829
830        mainSizer.Add((5,5),0)
831        mainSizer.Add(MapSizer())
832
833        mainSizer.Add((5,5),0)
834        mainSizer.Add(FlipSizer())
835
836        dataDisplay.SetSizer(mainSizer)
837        Size = mainSizer.Fit(G2frame.dataFrame)
838        Size[1] += 26                           #compensate for status bar
839        dataDisplay.SetSize(Size)
840        G2frame.dataFrame.setSizePosLeft(Size)
841
842################################################################################
843#####  Atom routines
844################################################################################
845
846    def FillAtomsGrid():
847
848        G2frame.dataFrame.setSizePosLeft([700,300])
849        generalData = data['General']
850        atomData = data['Atoms']
851        Items = [G2gd.wxID_ATOMSEDITINSERT, G2gd.wxID_ATOMSEDITDELETE, G2gd.wxID_ATOMSREFINE, 
852            G2gd.wxID_ATOMSMODIFY, G2gd.wxID_ATOMSTRANSFORM, G2gd.wxID_ATONTESTINSERT]
853        if atomData:
854            for item in Items:   
855                G2frame.dataFrame.AtomsMenu.Enable(item,True)
856        else:
857            for item in Items:
858                G2frame.dataFrame.AtomsMenu.Enable(item,False)           
859           
860        AAchoice = ": ,ALA,ARG,ASN,ASP,CYS,GLN,GLU,GLY,HIS,ILE,LEU,LYS,MET,PHE,PRO,SER,THR,TRP,TYR,VAL,MSE,HOH,UNK"
861        Types = [wg.GRID_VALUE_STRING,wg.GRID_VALUE_STRING,wg.GRID_VALUE_CHOICE+": ,X,XU,U,F,FX,FXU,FU",]+ \
862            3*[wg.GRID_VALUE_FLOAT+':10,5',]+[wg.GRID_VALUE_FLOAT+':10,4', #x,y,z,frac
863            wg.GRID_VALUE_STRING,wg.GRID_VALUE_STRING,wg.GRID_VALUE_CHOICE+":I,A",]
864        Types += 7*[wg.GRID_VALUE_FLOAT+':10,5',]
865        colLabels = ['Name','Type','refine','x','y','z','frac','site sym','mult','I/A','Uiso','U11','U22','U33','U12','U13','U23']
866        if generalData['Type'] == 'magnetic':
867            colLabels += ['Mx','My','Mz']
868            Types[2] = wg.GRID_VALUE_CHOICE+": ,X,XU,U,M,MX,MXU,MU,F,FX,FXU,FU,FM,FMX,FMU,"
869            Types += 3*[wg.GRID_VALUE_FLOAT+':10,4',]
870        elif generalData['Type'] == 'macromolecular':
871            colLabels = ['res no','residue','chain'] + colLabels
872            Types = [wg.GRID_VALUE_STRING,
873                wg.GRID_VALUE_CHOICE+AAchoice,
874                wg.GRID_VALUE_STRING] + Types
875        elif generalData['Type'] == 'modulated':
876            Types += []
877            colLabels += []
878
879        def RefreshAtomGrid(event):
880
881            r,c =  event.GetRow(),event.GetCol()
882            if r < 0 and c < 0:
883                for row in range(Atoms.GetNumberRows()):
884                    Atoms.SelectRow(row,True)                   
885            if r < 0:                          #double click on col label! Change all atoms!
886                sel = -1
887                noSkip = True
888                if Atoms.GetColLabelValue(c) == 'refine':
889                    Type = generalData['Type']
890                    if Type in ['nuclear','macromolecular']:
891                        choice = ['F - site fraction','X - coordinates','U - thermal parameters']
892                    elif Type in ['magnetic',]:
893                        choice = ['F - site fraction','X - coordinates','U - thermal parameters','M - magnetic moment']
894                    dlg = wx.MultiChoiceDialog(G2frame,'Select','Refinement controls',choice)
895                    if dlg.ShowModal() == wx.ID_OK:
896                        sel = dlg.GetSelections()
897                        parms = ''
898                        for x in sel:
899                            parms += choice[x][0]
900                    dlg.Destroy()
901                elif Atoms.GetColLabelValue(c) == 'I/A':
902                    choice = ['Isotropic','Anisotropic']
903                    dlg = wx.SingleChoiceDialog(G2frame,'Select','Thermal Motion',choice)
904                    if dlg.ShowModal() == wx.ID_OK:
905                        sel = dlg.GetSelection()
906                        parms = choice[sel][0]
907                    dlg.Destroy()
908                elif Atoms.GetColLabelValue(c) == 'Type':
909                    choice = generalData['AtomTypes']
910                    dlg = wx.SingleChoiceDialog(G2frame,'Select','Atom types',choice)
911                    if dlg.ShowModal() == wx.ID_OK:
912                        sel = dlg.GetSelection()
913                        parms = choice[sel]
914                        noSkip = False
915                        Atoms.ClearSelection()
916                        for row in range(Atoms.GetNumberRows()):
917                            if parms == atomData[row][c]:
918                                Atoms.SelectRow(row,True)
919                    dlg.Destroy()
920                    SetupGeneral()
921                elif Atoms.GetColLabelValue(c) == 'residue':
922                    choice = []
923                    for r in range(Atoms.GetNumberRows()):
924                        if str(atomData[r][c]) not in choice:
925                            choice.append(str(atomData[r][c]))
926                    choice.sort()
927                    dlg = wx.SingleChoiceDialog(G2frame,'Select','Residue',choice)
928                    if dlg.ShowModal() == wx.ID_OK:
929                        sel = dlg.GetSelection()
930                        parms = choice[sel]
931                        noSkip = False
932                        Atoms.ClearSelection()
933                        for row in range(Atoms.GetNumberRows()):
934                            if parms == atomData[row][c]:
935                                Atoms.SelectRow(row,True)
936                    dlg.Destroy()
937                elif Atoms.GetColLabelValue(c) == 'res no':
938                    choice = []
939                    for r in range(Atoms.GetNumberRows()):
940                        if str(atomData[r][c]) not in choice:
941                            choice.append(str(atomData[r][c]))
942                    dlg = wx.SingleChoiceDialog(G2frame,'Select','Residue no.',choice)
943                    if dlg.ShowModal() == wx.ID_OK:
944                        sel = dlg.GetSelection()
945                        parms = choice[sel]
946                        noSkip = False
947                        Atoms.ClearSelection()
948                        for row in range(Atoms.GetNumberRows()):
949                            if int(parms) == atomData[row][c]:
950                                Atoms.SelectRow(row,True)
951                    dlg.Destroy()
952                elif Atoms.GetColLabelValue(c) == 'chain':
953                    choice = []
954                    for r in range(Atoms.GetNumberRows()):
955                        if atomData[r][c] not in choice:
956                            choice.append(atomData[r][c])
957                    dlg = wx.SingleChoiceDialog(G2frame,'Select','Chain',choice)
958                    if dlg.ShowModal() == wx.ID_OK:
959                        sel = dlg.GetSelection()
960                        parms = choice[sel]
961                        noSkip = False
962                        Atoms.ClearSelection()
963                        for row in range(Atoms.GetNumberRows()):
964                            if parms == atomData[row][c]:
965                                Atoms.SelectRow(row,True)
966                    dlg.Destroy()
967                elif Atoms.GetColLabelValue(c) == 'Uiso':       #this needs to ask for value
968                    pass                                        #& then change all 'I' atoms
969                if sel >= 0 and noSkip:
970                    ui = colLabels.index('U11')
971                    us = colLabels.index('Uiso')
972                    ss = colLabels.index('site sym')
973                    for r in range(Atoms.GetNumberRows()):
974                        ID = atomData[r][-1]
975                        if parms != atomData[r][c] and Atoms.GetColLabelValue(c) == 'I/A':
976                            if parms == 'A':                #'I' --> 'A'
977                                Uiso = float(Atoms.GetCellValue(r,us))
978                                sytsym = atomData[r][ss]
979                                CSI = G2spc.GetCSuinel(sytsym)
980                                atomData[r][ui:ui+6] = Uiso*np.array(CSI[3])
981                                atomData[r][us] = 0.0
982                                Atoms.SetCellStyle(r,us,VERY_LIGHT_GREY,True)
983                                for i in range(6):
984                                    ci = ui+i
985                                    Atoms.SetCellStyle(r,ci,VERY_LIGHT_GREY,True)
986                                    if CSI[2][i]:
987                                        Atoms.SetCellStyle(r,ci,WHITE,False)
988                            else:                           #'A' --> 'I'
989                                Uij = atomData[r][ui:ui+6]
990                                Uiso = (Uij[0]+Uij[1]+Uij[2])/3.0
991                                atomData[r][us] = Uiso
992                                Atoms.SetCellStyle(r,us,WHITE,False)
993                                for i in range(6):
994                                    ci = ui+i
995                                    atomData[r][ci] = 0.0
996                                    Atoms.SetCellStyle(r,ci,VERY_LIGHT_GREY,True)
997                        atomData[r][c] = parms
998                        if 'Atoms' in data['Drawing']:
999                            DrawAtomsReplaceByID(data['Drawing'],atomData[r],ID)
1000                    FillAtomsGrid()
1001                   
1002        def ChangeAtomCell(event):
1003           
1004            def chkUij(Uij,CSI): #needs to do something!!!
1005                return Uij
1006
1007            r,c =  event.GetRow(),event.GetCol()
1008            if r >= 0 and c >= 0:
1009                ID = atomData[r][-1]
1010                if Atoms.GetColLabelValue(c) in ['x','y','z']:
1011                    ci = colLabels.index('x')
1012                    XYZ = atomData[r][ci:ci+3]
1013                    if None in XYZ:
1014                        XYZ = [0,0,0]
1015                    SScol = colLabels.index('site sym')
1016                    Mulcol = colLabels.index('mult')
1017                    E,SGData = G2spc.SpcGroup(generalData['SGData']['SpGrp'])
1018                    Sytsym,Mult = G2spc.SytSym(XYZ,SGData)
1019                    atomData[r][SScol] = Sytsym
1020                    atomData[r][Mulcol] = Mult
1021                    if atomData[r][colLabels.index('I/A')] == 'A':
1022                        ui = colLabels.index('U11')
1023                        CSI = G2spc.GetCSuinel(Sytsym)
1024                        atomData[r][ui:ui+6] = chkUij(atomData[r][ui:ui+6],Sytsym)
1025                        for i in range(6):
1026                            ci = i+ui
1027                            Atoms.SetCellStyle(r,ci,VERY_LIGHT_GREY,True)
1028                            if CSI[2][i]:
1029                                Atoms.SetCellStyle(r,ci,WHITE,False)
1030                    SetupGeneral()
1031                elif Atoms.GetColLabelValue(c) == 'I/A':            #note use of text color to make it vanish!
1032                    if atomData[r][c] == 'I':
1033                        Uij = atomData[r][c+2:c+8]
1034                        atomData[r][c+1] = (Uij[0]+Uij[1]+Uij[2])/3.0
1035                        Atoms.SetCellStyle(r,c+1,WHITE,False)
1036                        Atoms.SetCellTextColour(r,c+1,BLACK)
1037                        for i in range(6):
1038                            ci = i+colLabels.index('U11')
1039                            Atoms.SetCellStyle(r,ci,VERY_LIGHT_GREY,True)
1040                            Atoms.SetCellTextColour(r,ci,VERY_LIGHT_GREY)
1041                            atomData[r][ci] = 0.0
1042                    else:
1043                        value = atomData[r][c+1]
1044                        CSI = G2spc.GetCSuinel(atomData[r][colLabels.index('site sym')])
1045                        atomData[r][c+1] =  0.0
1046                        Atoms.SetCellStyle(r,c+1,VERY_LIGHT_GREY,True)
1047                        Atoms.SetCellTextColour(r,c+1,VERY_LIGHT_GREY)
1048                        for i in range(6):
1049                            ci = i+colLabels.index('U11')
1050                            atomData[r][ci] = value*CSI[3][i]
1051                            Atoms.SetCellStyle(r,ci,VERY_LIGHT_GREY,True)
1052                            Atoms.SetCellTextColour(r,ci,BLACK)
1053                            if CSI[2][i]:
1054                                Atoms.SetCellStyle(r,ci,WHITE,False)
1055                elif Atoms.GetColLabelValue(c) in ['U11','U22','U33','U12','U13','U23']:
1056                    value = atomData[r][c]
1057                    CSI = G2spc.GetCSuinel(atomData[r][colLabels.index('site sym')])
1058                    iUij = CSI[0][c-colLabels.index('U11')]
1059                    for i in range(6):
1060                        if iUij == CSI[0][i]:
1061                            atomData[r][i+colLabels.index('U11')] = value*CSI[1][i]
1062                if 'Atoms' in data['Drawing']:
1063                    DrawAtomsReplaceByID(data['Drawing'],atomData[r],ID)
1064                    FindBondsDraw()
1065                   
1066        def AtomTypeSelect(event):
1067            r,c =  event.GetRow(),event.GetCol()
1068            if Atoms.GetColLabelValue(c) == 'Type':
1069                PE = G2elemGUI.PickElement(G2frame)
1070                if PE.ShowModal() == wx.ID_OK:
1071                    if PE.Elem != 'None':                       
1072                        atomData[r][c] = PE.Elem.strip()
1073                        name = atomData[r][c]
1074                        if len(name) in [2,4]:
1075                            atomData[r][c-1] = name[:2]+'(%d)'%(r+1)
1076                        else:
1077                            atomData[r][c-1] = name[:1]+'(%d)'%(r+1)
1078                PE.Destroy()
1079                SetupGeneral()
1080                FillAtomsGrid()
1081                value = Atoms.GetCellValue(r,c)
1082                atomData[r][c] = value
1083                ID = atomData[r][-1]
1084                if 'Atoms' in data['Drawing']:
1085                    DrawAtomsReplaceByID(data['Drawing'],atomData[r],ID)
1086                SetupGeneral()
1087            else:
1088                event.Skip()
1089
1090        def RowSelect(event):
1091            r,c =  event.GetRow(),event.GetCol()
1092            if r < 0 and c < 0:
1093                if Atoms.IsSelection():
1094                    Atoms.ClearSelection()
1095            elif c < 0:                   #only row clicks
1096                if event.ControlDown():                   
1097                    if r in Atoms.GetSelectedRows():
1098                        Atoms.DeselectRow(r)
1099                    else:
1100                        Atoms.SelectRow(r,True)
1101                elif event.ShiftDown():
1102                    for row in range(r+1):
1103                        Atoms.SelectRow(row,True)
1104                else:
1105                    Atoms.ClearSelection()
1106                    Atoms.SelectRow(r,True)               
1107               
1108        def ChangeSelection(event):
1109            r,c =  event.GetRow(),event.GetCol()
1110            if r < 0 and c < 0:
1111                Atoms.ClearSelection()
1112            if c < 0:
1113                if r in Atoms.GetSelectedRows():
1114                    Atoms.DeselectRow(r)
1115                else:
1116                    Atoms.SelectRow(r,True)
1117            if r < 0:
1118                if c in Atoms.GetSelectedCols():
1119                    Atoms.DeselectCol(c)
1120                else:
1121                    Atoms.SelectCol(c,True)
1122       
1123        SGData = data['General']['SGData']
1124        if SGData['SGPolax']:
1125            G2frame.dataFrame.SetStatusText('Warning: The location of the origin is arbitrary in '+SGData['SGPolax'])
1126        table = []
1127        rowLabels = []
1128        for i,atom in enumerate(atomData):
1129            table.append(atom)
1130            rowLabels.append(str(i))
1131        atomTable = G2gd.Table(table,rowLabels=rowLabels,colLabels=colLabels,types=Types)
1132        Atoms.SetTable(atomTable, True)
1133        Atoms.Bind(wg.EVT_GRID_CELL_CHANGE, ChangeAtomCell)
1134        Atoms.Bind(wg.EVT_GRID_CELL_LEFT_DCLICK, AtomTypeSelect)
1135        Atoms.Bind(wg.EVT_GRID_LABEL_LEFT_DCLICK, RefreshAtomGrid)
1136        Atoms.Bind(wg.EVT_GRID_LABEL_LEFT_CLICK, RowSelect)
1137        Atoms.Bind(wg.EVT_GRID_LABEL_RIGHT_CLICK, ChangeSelection)
1138        Atoms.SetMargins(0,0)
1139        Atoms.AutoSizeColumns(False)
1140        colType = colLabels.index('Type')
1141        colSS = colLabels.index('site sym')
1142        colIA = colLabels.index('I/A')
1143        colU11 = colLabels.index('U11')
1144        colUiso = colLabels.index('Uiso')
1145        for i in range(colU11-1,colU11+6):
1146            Atoms.SetColSize(i,50)           
1147        for row in range(Atoms.GetNumberRows()):
1148            Atoms.SetReadOnly(row,colType,True)
1149            Atoms.SetReadOnly(row,colSS,True)                         #site sym
1150            Atoms.SetReadOnly(row,colSS+1,True)                       #Mult
1151            if Atoms.GetCellValue(row,colIA) == 'A':
1152                CSI = G2spc.GetCSuinel(atomData[row][colLabels.index('site sym')])
1153                Atoms.SetCellStyle(row,colUiso,VERY_LIGHT_GREY,True)
1154                Atoms.SetCellTextColour(row,colUiso,VERY_LIGHT_GREY)
1155                for i in range(6):
1156                    ci = colU11+i
1157                    Atoms.SetCellTextColour(row,ci,BLACK)
1158                    Atoms.SetCellStyle(row,ci,VERY_LIGHT_GREY,True)
1159                    if CSI[2][i]:
1160                        Atoms.SetCellStyle(row,ci,WHITE,False)
1161            else:
1162                Atoms.SetCellStyle(row,colUiso,WHITE,False)
1163                Atoms.SetCellTextColour(row,colUiso,BLACK)
1164                for i in range(6):
1165                    ci = colU11+i
1166                    Atoms.SetCellStyle(row,ci,VERY_LIGHT_GREY,True)
1167                    Atoms.SetCellTextColour(row,ci,VERY_LIGHT_GREY)
1168
1169    def OnAtomAdd(event):
1170        AtomAdd(0,0,0)
1171        FillAtomsGrid()
1172        event.StopPropagation()
1173       
1174    def OnAtomTestAdd(event):
1175        try:
1176            drawData = data['Drawing']
1177            x,y,z = drawData['testPos'][0]
1178            AtomAdd(x,y,z)
1179        except:
1180            AtomAdd(0,0,0)
1181        FillAtomsGrid()
1182        event.StopPropagation()
1183               
1184    def AtomAdd(x,y,z,El='H'):
1185        atomData = data['Atoms']
1186        generalData = data['General']
1187        Ncol = Atoms.GetNumberCols()
1188        atId = ran.randint(0,sys.maxint)
1189        E,SGData = G2spc.SpcGroup(generalData['SGData']['SpGrp'])
1190        Sytsym,Mult = G2spc.SytSym([x,y,z],SGData)
1191        if generalData['Type'] == 'macromolecular':
1192            atomData.append([0,'UNK','','UNK',El,'',x,y,z,1,Sytsym,Mult,'I',0.10,0,0,0,0,0,0,atId])
1193        elif generalData['Type'] == 'nuclear':
1194            atomData.append(['UNK',El,'',x,y,z,1,Sytsym,Mult,'I',0.01,0,0,0,0,0,0,atId])
1195        elif generalData['Type'] == 'magnetic':
1196            atomData.append(['UNK',El,'',x,y,z,1,Sytsym,Mult,0,'I',0.01,0,0,0,0,0,0,0,0,0,atId])
1197        SetupGeneral()
1198        if 'Atoms' in data['Drawing']:           
1199            DrawAtomAdd(data['Drawing'],atomData[-1])
1200            G2plt.PlotStructure(G2frame,data)
1201
1202    def OnAtomInsert(event):
1203        AtomInsert(0,0,0)
1204        FillAtomsGrid()
1205        event.StopPropagation()
1206       
1207    def OnAtomTestInsert(event):
1208        if 'Drawing' in data:
1209            drawData = data['Drawing']
1210            x,y,z = drawData['testPos'][0]
1211            AtomAdd(x,y,z)
1212            FillAtomsGrid()
1213        event.StopPropagation()
1214           
1215    def AtomInsert(x,y,z):
1216        indx = Atoms.GetSelectedRows()
1217        if indx:
1218            indx = indx[0]
1219            atomData = data['Atoms']
1220            generalData = data['General']
1221            Ncol = Atoms.GetNumberCols()
1222            E,SGData = G2spc.SpcGroup(generalData['SGData']['SpGrp'])
1223            Sytsym,Mult = G2spc.SytSym([0,0,0],SGData)
1224            atId = ran.randint(0,sys.maxint)
1225            if generalData['Type'] == 'macromolecular':
1226                atomData.insert(indx,[0,'UNK','','UNK','UNK','',x,y,z,1,Sytsym,Mult,'I',0.10,0,0,0,0,0,0,atId])
1227            elif generalData['Type'] == 'nuclear':
1228                atomData.insert(indx,['UNK','UNK','',x,y,z,1,Sytsym,Mult,'I',0.01,0,0,0,0,0,0,atId])
1229            elif generalData['Type'] == 'magnetic':
1230                atomData.insert(indx,['UNK','UNK','',x,y,z,1,Sytsym,Mult,0,'I',0.01,0,0,0,0,0,0,0,0,0,atId])
1231            SetupGeneral()
1232
1233    def AtomDelete(event):
1234        indx = Atoms.GetSelectedRows()
1235        IDs = []
1236        if indx:
1237            atomData = data['Atoms']
1238            indx.reverse()
1239            for ind in indx:
1240                atom = atomData[ind]
1241                IDs.append(atom[-1])
1242                del atomData[ind]
1243            if 'Atoms' in data['Drawing']:
1244                DrawAtomsDeleteByIDs(IDs)
1245                FillAtomsGrid()
1246                G2plt.PlotStructure(G2frame,data)
1247            SetupGeneral()
1248        event.StopPropagation()
1249
1250    def AtomRefine(event):
1251        colLabels = [Atoms.GetColLabelValue(c) for c in range(Atoms.GetNumberCols())]
1252        c = colLabels.index('refine')
1253        indx = Atoms.GetSelectedRows()
1254        if indx:
1255            atomData = data['Atoms']
1256            generalData = data['General']
1257            Type = generalData['Type']
1258            if Type in ['nuclear','macromolecular']:
1259                choice = ['F - site fraction','X - coordinates','U - thermal parameters']
1260            elif Type == 'magnetic':
1261                choice = ['F - site fraction','X - coordinates','U - thermal parameters','M - magnetic moment']
1262            dlg = wx.MultiChoiceDialog(G2frame,'Select','Refinement controls',choice)
1263            if dlg.ShowModal() == wx.ID_OK:
1264                sel = dlg.GetSelections()
1265                parms = ''
1266                for x in sel:
1267                    parms += choice[x][0]
1268                for r in indx:
1269                    atomData[r][c] = parms
1270                Atoms.ForceRefresh()
1271            dlg.Destroy()
1272
1273    def AtomModify(event):                  #intent to implement global modifications (+,-,*,/, etc.)?
1274        indx = Atoms.GetSelectedRows()
1275        if indx:
1276            atomData = data['Atoms']
1277            generalData = data['General']
1278            colLabels = [Atoms.GetColLabelValue(c) for c in range(Atoms.GetNumberCols())]
1279            choices = ['Type','x','y','z','frac','I/A','Uiso']
1280            dlg = wx.SingleChoiceDialog(G2frame,'Select','Atom parameter',choices)
1281            if dlg.ShowModal() == wx.ID_OK:
1282                sel = dlg.GetSelection()
1283                parm = choices[sel]
1284                cid = colLabels.index(parm)
1285            dlg.Destroy()
1286            if parm in ['Type']:
1287                dlg = G2elemGUI.PickElement(G2frame)
1288                if dlg.ShowModal() == wx.ID_OK:
1289                    if dlg.Elem not in ['None']:
1290                        El = dlg.Elem.strip()
1291                        for r in indx:                       
1292                            atomData[r][cid] = El
1293                            if len(El) in [2,4]:
1294                                atomData[r][cid-1] = El[:2]+'(%d)'%(r+1)
1295                            else:
1296                                atomData[r][cid-1] = El[:1]+'(%d)'%(r+1)
1297                        SetupGeneral()
1298                        if 'Atoms' in data['Drawing']:
1299                            for r in indx:
1300                                ID = atomData[r][-1]
1301                                DrawAtomsReplaceByID(data['Drawing'],atomData[r],ID)
1302                    FillAtomsGrid()
1303                dlg.Destroy()
1304            elif parm in ['I/A']:
1305                choices = ['Isotropic','Anisotropic']
1306                dlg = wx.SingleChoiceDialog(G2frame,'Select','Thermal parameter model',choices)
1307                if dlg.ShowModal() == wx.ID_OK:
1308                    sel = dlg.GetSelection()
1309                    parm = choices[sel][0]
1310                    for r in indx:                       
1311                        atomData[r][cid] = parm
1312                    FillAtomsGrid()
1313                dlg.Destroy()
1314            elif parm in ['frac','Uiso']:
1315                limits = [0.,1.]
1316                val = 1.0
1317                if  parm in ['Uiso']:
1318                    limits = [0.,0.25]
1319                    val = 0.01
1320                dlg = SingleFloatDialog(G2frame,'New value','Enter new value for '+parm,val,limits)
1321                if dlg.ShowModal() == wx.ID_OK:
1322                    parm = dlg.GetValue()
1323                    for r in indx:                       
1324                        atomData[r][cid] = parm
1325                    SetupGeneral()
1326                    FillAtomsGrid()
1327                dlg.Destroy()
1328            elif parm in ['x','y','z']:
1329                limits = [-1.,1.]
1330                val = 0.
1331                dlg = SingleFloatDialog(G2frame,'Atom shift','Enter shift for '+parm,val,limits)
1332                if dlg.ShowModal() == wx.ID_OK:
1333                    parm = dlg.GetValue()
1334                    for r in indx:                       
1335                        atomData[r][cid] += parm
1336                    SetupGeneral()
1337                    FillAtomsGrid()
1338                dlg.Destroy()
1339
1340    def AtomTransform(event):
1341        indx = Atoms.GetSelectedRows()
1342        if indx:
1343            generalData = data['General']
1344            colLabels = [Atoms.GetColLabelValue(c) for c in range(Atoms.GetNumberCols())]
1345            cx = colLabels.index('x')
1346            cuia = colLabels.index('I/A')
1347            cuij = colLabels.index('U11')
1348            css = colLabels.index('site sym')
1349            atomData = data['Atoms']
1350            generalData = data['General']
1351            SGData = generalData['SGData']
1352            dlg = SymOpDialog(G2frame,SGData,True)
1353            try:
1354                if dlg.ShowModal() == wx.ID_OK:
1355                    Inv,Cent,Opr,Cell,New = dlg.GetSelection()
1356                    Cell = np.array(Cell)
1357                    cent = SGData['SGCen'][Cent]
1358                    M,T = SGData['SGOps'][Opr]
1359                    for ind in indx:
1360                        XYZ = np.array(atomData[ind][cx:cx+3])
1361                        XYZ = np.inner(M,XYZ)+T
1362                        if Inv:
1363                            XYZ = -XYZ
1364                        XYZ = XYZ+cent+Cell
1365                        if New:
1366                            atom = copy.copy(atomData[ind])
1367                        else:
1368                            atom = atomData[ind]
1369                        atom[cx:cx+3] = XYZ
1370                        atom[css:css+2] = G2spc.SytSym(XYZ,SGData)
1371                        if atom[cuia] == 'A':
1372                            Uij = atom[cuij:cuij+6]
1373                            U = G2spc.Uij2U(Uij)
1374                            U = np.inner(np.inner(M,U),M)
1375                            Uij = G2spc.U2Uij(U)
1376                            atom[cuij:cuij+6] = Uij
1377                        if New:
1378                            atomData.append(atom)
1379            finally:
1380                dlg.Destroy()
1381            Atoms.ClearSelection()
1382            if New:
1383                FillAtomsGrid()
1384            else:
1385                Atoms.ForceRefresh()
1386
1387    def OnDistAngle(event):
1388        indx = Atoms.GetSelectedRows()
1389        Oxyz = []
1390        xyz = []
1391        DisAglData = {}
1392        DisAglCtls = {}
1393        if indx:
1394            generalData = data['General']
1395            DisAglData['OrigIndx'] = indx
1396            if 'DisAglCtls' in generalData:
1397                DisAglCtls = generalData['DisAglCtls']
1398            dlg = DisAglDialog(G2frame,DisAglCtls,generalData)
1399            if dlg.ShowModal() == wx.ID_OK:
1400                DisAglCtls = dlg.GetData()
1401            dlg.Destroy()
1402            generalData['DisAglCtls'] = DisAglCtls
1403            atomData = data['Atoms']
1404            colLabels = [Atoms.GetColLabelValue(c) for c in range(Atoms.GetNumberCols())]
1405            cx = colLabels.index('x')
1406            cn = colLabels.index('Name')
1407            for i,atom in enumerate(atomData):
1408                xyz.append([i,]+atom[cn:cn+2]+atom[cx:cx+3])
1409                if i in indx:
1410                    Oxyz.append([i,]+atom[cn:cn+2]+atom[cx:cx+3])
1411            DisAglData['OrigAtoms'] = Oxyz
1412            DisAglData['TargAtoms'] = xyz
1413            generalData = data['General']
1414            DisAglData['SGData'] = generalData['SGData']
1415            DisAglData['Cell'] = generalData['Cell'][1:] #+ volume
1416            if 'pId' in data:
1417                DisAglData['pId'] = data['pId']
1418                DisAglData['covData'] = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.root, 'Covariance'))
1419            G2str.DistAngle(DisAglCtls,DisAglData)
1420                       
1421################################################################################
1422#Structure drawing GUI stuff               
1423################################################################################
1424
1425    def SetupDrawingData():
1426        generalData = data['General']
1427        atomData = data['Atoms']
1428        AA3letter = ['ALA','ARG','ASN','ASP','CYS','GLN','GLU','GLY','HIS','ILE',
1429            'LEU','LYS','MET','PHE','PRO','SER','THR','TRP','TYR','VAL','MSE','HOH','WAT','UNK']
1430        AA1letter = ['A','R','N','D','C','Q','E','G','H','I',
1431            'L','K','M','F','P','S','T','W','Y','V','M',' ',' ',' ']
1432        defaultDrawing = {'Atoms':[],'viewPoint':[[0.5,0.5,0.5],[]],'showHydrogen':True,
1433            'backColor':[0,0,0],'depthFog':False,'Zclip':50.0,'cameraPos':50.,
1434            'radiusFactor':0.85,'contourLevel':1.,'bondRadius':0.1,'ballScale':0.33,
1435            'vdwScale':0.67,'ellipseProb':50,'sizeH':0.50,'unitCellBox':False,
1436            'showABC':True,'selectedAtoms':[],'Atoms':[],'Rotation':[0.0,0.0,0.0,[]],
1437            'bondList':{},'testPos':[[-.1,-.1,-.1],[0.0,0.0,0.0],[0,0]]}
1438        try:
1439            drawingData = data['Drawing']
1440        except KeyError:
1441            data['Drawing'] = {}
1442            drawingData = data['Drawing']
1443        if not drawingData:                 #fill with defaults if empty
1444            drawingData.update(defaultDrawing)
1445        if 'contourLevel' not in drawingData:
1446            drawingData['contourLevel'] = 1.
1447        cx,ct,cs,ci = [0,0,0,0]
1448        if generalData['Type'] == 'nuclear':
1449            cx,ct,cs,ci = [2,1,6,17]         #x, type, style & index
1450        elif generalData['Type'] == 'macromolecular':
1451            cx,ct,cs,ci = [5,4,9,20]         #x, type, style & index
1452        elif generalData['Type'] == 'magnetic':
1453            cx,ct,cs,ci = [2,1,6,20]         #x, type, style & index
1454#        elif generalData['Type'] == 'modulated':
1455#           ?????   for future
1456        drawingData['atomPtrs'] = [cx,ct,cs,ci]
1457        if not drawingData.get('Atoms'):
1458            for atom in atomData:
1459                DrawAtomAdd(drawingData,atom)
1460            data['Drawing'] = drawingData
1461           
1462    def MakeDrawAtom(atom,oldatom=None):
1463        AA3letter = ['ALA','ARG','ASN','ASP','CYS','GLN','GLU','GLY','HIS','ILE',
1464            'LEU','LYS','MET','PHE','PRO','SER','THR','TRP','TYR','VAL','MSE','HOH','WAT','UNK']
1465        AA1letter = ['A','R','N','D','C','Q','E','G','H','I',
1466            'L','K','M','F','P','S','T','W','Y','V','M',' ',' ',' ']
1467        generalData = data['General']
1468        SGData = generalData['SGData']
1469        if generalData['Type'] == 'nuclear':
1470            if oldatom:
1471                opr = oldatom[5]
1472                if atom[9] == 'A':                   
1473                    X,U = G2spc.ApplyStringOps(opr,SGData,atom[3:6],atom[11:17])
1474                    atomInfo = [atom[:2]+list(X)+oldatom[5:9]+atom[9:11]+list(U)+oldatom[17:]][0]
1475                else:
1476                    X = G2spc.ApplyStringOps(opr,SGData,atom[3:6])
1477                    atomInfo = [atom[:2]+list(X)+oldatom[5:9]+atom[9:]+[oldatom[-1]]][0]
1478            else:
1479                atomInfo = [atom[:2]+atom[3:6]+['1',]+['vdW balls',]+
1480                    ['',]+[[255,255,255],]+atom[9:]+[[],[]]][0]
1481            ct,cs = [1,8]         #type & color
1482        elif generalData['Type'] == 'macromolecular':
1483            try:
1484                oneLetter = AA3letter.index(atom[1])
1485            except ValueError:
1486                oneLetter = -1
1487            atomInfo = [[atom[1].strip()+atom[0],]+
1488                [AA1letter[oneLetter]+atom[0],]+atom[2:5]+
1489                atom[6:9]+['1',]+['sticks',]+['',]+[[255,255,255],]+atom[12:]+[[],[]]][0]
1490            ct,cs = [4,11]         #type & color
1491        elif generalData['Type'] == 'magnetic':
1492            if oldatom:
1493                atomInfo = [atom[:2]+oldatom[3:]][0]
1494            else:
1495                atomInfo = [atom[:2]+atom[3:6]+['vdW balls',]+['',]+atom[9:]+[[],[]]][0]
1496            ct,cs = [1,8]         #type & color
1497#        elif generalData['Type'] == 'modulated':
1498#           ?????   for future
1499        atNum = generalData['AtomTypes'].index(atom[ct])
1500        atomInfo[cs] = list(generalData['Color'][atNum])
1501        return atomInfo
1502           
1503    def DrawAtomAdd(drawingData,atom):
1504        drawingData['Atoms'].append(MakeDrawAtom(atom))
1505       
1506    def DrawAtomsReplaceByID(drawingData,atom,ID):
1507        IDs = [ID,]
1508        atomData = drawingData['Atoms']
1509        indx = FindAtomIndexByIDs(atomData,IDs)
1510        for ind in indx:
1511            atomData[ind] = MakeDrawAtom(atom,atomData[ind])
1512           
1513    def OnRestraint(event):       
1514        indx = drawAtoms.GetSelectedRows()
1515        restData = G2frame.PatternTree.GetItemPyData(   
1516            G2gd.GetPatternTreeItemId(G2frame,G2frame.root,'Restraints'))
1517        drawingData = data['Drawing']
1518        generalData = data['General']
1519        Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7])           
1520        cx,ct,cs,ci = drawingData['atomPtrs']
1521        atomData = drawingData['Atoms']
1522        atNames = []
1523        atXYZ = []
1524        atSymOp = []
1525        atIndx = []
1526        for item in indx:
1527            atNames.append(atomData[item][ct-1])
1528            atXYZ.append(np.array(atomData[item][cx:cx+3]))
1529            atSymOp.append(atomData[item][cs-1])
1530            atIndx.append(atomData[item][ci])
1531        if event.GetId() == G2gd.wxID_DRAWRESTRBOND and len(indx) == 2:
1532            try:
1533                bondData = restData[PhaseName]['Bond']
1534            except KeyError:
1535                bondData = {'wtFactor':1.0,'Bonds':[]}
1536                restData[PhaseName] = {}
1537                restData[PhaseName]['Bond'] = bondData
1538            dist = G2mth.getRestDist(atXYZ,Amat)
1539            bondData['Bonds'].append([atNames,atSymOp,atIndx,dist,1.54,0.01])
1540        elif event.GetId() == G2gd.wxID_DRAWRESTRANGLE and len(indx) == 3:
1541            try:
1542                angleData = restData[PhaseName]['Angle']
1543            except KeyError:
1544                angleData = {'wtFactor':1.0,'Angles':[]}
1545                restData[PhaseName] = {}
1546                restData[PhaseName]['Angle'] = angleData
1547            angle = G2mth.getRestAngle(atXYZ,Amat)
1548            angleData['Angles'].append([atNames,atSymOp,atIndx,angle,109.5,1.0])           
1549        elif event.GetId() == G2gd.wxID_DRAWRESTRPLANE and len(indx) > 3:
1550            try:
1551                planeData = restData[PhaseName]['Plane']
1552            except KeyError:
1553                planeData = {'wtFactor':1.0,'Planes':[]}
1554                restData[PhaseName] = {}
1555                restData[PhaseName]['Plane'] = planeData
1556            plane = G2mth.getRestPlane(atXYZ,Amat)
1557            planeData['Planes'].append([atNames,atSymOp,atIndx,plane,0.0,0.01])           
1558        elif event.GetId() == G2gd.wxID_DRAWRESTRCHIRAL and len(indx) == 4:
1559            try:
1560                chiralData = restData[PhaseName]['Chiral']
1561            except KeyError:
1562                chiralData = {'wtFactor':1.0,'Volumes':[]}
1563                restData[PhaseName] = {}
1564                restData[PhaseName]['Chiral'] = chiralData
1565            volume = G2mth.getRestChiral(atXYZ,Amat)
1566            chiralData['Volumes'].append([atNames,atSymOp,atIndx,volume,2.5,0.1])           
1567        else:
1568            print '**** ERROR wrong number of atoms selected for this restraint'
1569            return
1570        G2frame.PatternTree.SetItemPyData(   
1571            G2gd.GetPatternTreeItemId(G2frame,G2frame.root,'Restraints'),restData)
1572
1573################################################################################
1574##### Atom draw routines
1575################################################################################
1576           
1577    def UpdateDrawAtoms():
1578        generalData = data['General']
1579        SetupDrawingData()
1580        drawingData = data['Drawing']
1581        cx,ct,cs,ci = drawingData['atomPtrs']
1582        atomData = drawingData['Atoms']
1583        Types = [wg.GRID_VALUE_STRING,wg.GRID_VALUE_STRING,]+3*[wg.GRID_VALUE_FLOAT+':10,5',]+ \
1584            [wg.GRID_VALUE_STRING,wg.GRID_VALUE_CHOICE+": ,lines,vdW balls,sticks,balls & sticks,ellipsoids,polyhedra",
1585            wg.GRID_VALUE_CHOICE+": ,type,name,number",wg.GRID_VALUE_STRING,wg.GRID_VALUE_STRING,]
1586        styleChoice = [' ','lines','vdW balls','sticks','balls & sticks','ellipsoids','polyhedra']
1587        labelChoice = [' ','type','name','number']
1588        colLabels = ['Name','Type','x','y','z','Sym Op','Style','Label','Color','I/A']
1589        if generalData['Type'] == 'macromolecular':
1590            colLabels = ['Residue','1-letter','Chain'] + colLabels
1591            Types = 3*[wg.GRID_VALUE_STRING,]+Types
1592            Types[8] = wg.GRID_VALUE_CHOICE+": ,lines,vdW balls,sticks,balls & sticks,ellipsoids,backbone,ribbons,schematic"
1593            styleChoice = [' ','lines','vdW balls','sticks','balls & sticks','ellipsoids','backbone','ribbons','schematic']
1594            labelChoice = [' ','type','name','number','residue','1-letter','chain']
1595            Types[9] = wg.GRID_VALUE_CHOICE+": ,type,name,number,residue,1-letter,chain"
1596#        elif generalData['Type'] == 'modulated':
1597#            Types += []
1598#            colLabels += []
1599
1600        def RefreshAtomGrid(event):
1601
1602            def SetChoice(name,c,n=0):
1603                choice = []
1604                for r in range(len(atomData)):
1605                    if n:
1606                        srchStr = str(atomData[r][c][:n])
1607                    else:
1608                        srchStr = str(atomData[r][c])
1609                    if srchStr not in choice:
1610                        if n:
1611                            choice.append(str(atomData[r][c][:n]))
1612                        else:
1613                            choice.append(str(atomData[r][c]))
1614                choice.sort()
1615
1616                dlg = wx.MultiChoiceDialog(G2frame,'Select',name,choice)
1617                if dlg.ShowModal() == wx.ID_OK:
1618                    sel = dlg.GetSelections()
1619                    parms = []
1620                    for x in sel:
1621                        parms.append(choice[x])
1622                    noSkip = False
1623                    drawAtoms.ClearSelection()
1624                    drawingData['selectedAtoms'] = []
1625                    for row in range(len(atomData)):
1626                        test = atomData[row][c]
1627                        if n:
1628                            test = test[:n]
1629                        if  test in parms:
1630                            drawAtoms.SelectRow(row,True)
1631                            drawingData['selectedAtoms'].append(row)
1632                    G2plt.PlotStructure(G2frame,data)                   
1633                dlg.Destroy()
1634               
1635            r,c =  event.GetRow(),event.GetCol()
1636            if r < 0 and c < 0:
1637                for row in range(drawAtoms.GetNumberRows()):
1638                    drawingData['selectedAtoms'].append(row)
1639                    drawAtoms.SelectRow(row,True)                   
1640            elif r < 0:                          #dclick on col label
1641                sel = -1
1642                Parms = False
1643                noSkip = True
1644                if drawAtoms.GetColLabelValue(c) == 'Style':
1645                    dlg = wx.SingleChoiceDialog(G2frame,'Select','Atom drawing style',styleChoice)
1646                    if dlg.ShowModal() == wx.ID_OK:
1647                        sel = dlg.GetSelection()
1648                        parms = styleChoice[sel]
1649                        for r in range(len(atomData)):
1650                            atomData[r][c] = parms
1651                            drawAtoms.SetCellValue(r,c,parms)
1652                        FindBondsDraw()
1653                        G2plt.PlotStructure(G2frame,data)
1654                    dlg.Destroy()
1655                elif drawAtoms.GetColLabelValue(c) == 'Label':
1656                    dlg = wx.SingleChoiceDialog(G2frame,'Select','Atom labelling style',labelChoice)
1657                    if dlg.ShowModal() == wx.ID_OK:
1658                        sel = dlg.GetSelection()
1659                        parms = labelChoice[sel]
1660                        for r in range(len(atomData)):
1661                            atomData[r][c] = parms
1662                            drawAtoms.SetCellValue(r,c,parms)
1663                    dlg.Destroy()                   
1664                elif drawAtoms.GetColLabelValue(c) == 'Color':
1665                    dlg = wx.ColourDialog(G2frame)
1666                    if dlg.ShowModal() == wx.ID_OK:
1667                        color = dlg.GetColourData().GetColour()
1668                        attr = wg.GridCellAttr()                #needs to be here - gets lost if outside loop!
1669                        attr.SetReadOnly(True)
1670                        attr.SetBackgroundColour(color)
1671                        for r in range(len(atomData)):
1672                            atomData[r][c] = color
1673                            drawingData['Atoms'][r][c] = color
1674                            drawAtoms.SetAttr(r,c,attr)
1675                        UpdateDrawAtoms()
1676                    dlg.Destroy()
1677                elif drawAtoms.GetColLabelValue(c) == 'Residue':
1678                    SetChoice('Residue',c,3)
1679                elif drawAtoms.GetColLabelValue(c) == '1-letter':
1680                    SetChoice('1-letter',c,1)
1681                elif drawAtoms.GetColLabelValue(c) == 'Chain':
1682                    SetChoice('Chain',c)
1683                elif drawAtoms.GetColLabelValue(c) == 'Name':
1684                    SetChoice('Name',c)
1685                elif drawAtoms.GetColLabelValue(c) == 'Sym Op':
1686                    SetChoice('Name',c)
1687                elif drawAtoms.GetColLabelValue(c) == 'Type':
1688                    SetChoice('Type',c)
1689                elif drawAtoms.GetColLabelValue(c) in ['x','y','z','I/A']:
1690                    drawAtoms.ClearSelection()
1691            else:
1692                if drawAtoms.GetColLabelValue(c) in ['Style','Label']:
1693                    atomData[r][c] = drawAtoms.GetCellValue(r,c)
1694                    FindBondsDraw()
1695                elif drawAtoms.GetColLabelValue(c) == 'Color':
1696                    color = atomData[r][c]
1697                    colors = wx.ColourData()
1698                    colors.SetChooseFull(True)
1699                    colors.SetCustomColour(0,color)
1700                    colors.SetColour(color)
1701                    dlg = wx.ColourDialog(G2frame,colors)
1702                    dlg.GetColourData().SetCustomColour(0,color)
1703                    if dlg.ShowModal() == wx.ID_OK:
1704                        color = dlg.GetColourData().GetColour()
1705                        attr = wg.GridCellAttr()                #needs to be here - gets lost if outside loop!
1706                        attr.SetReadOnly(True)
1707                        attr.SetBackgroundColour(color)
1708                        atomData[r][c] = color
1709                        drawingData['Atoms'][r][c] = color
1710                        drawAtoms.SetAttr(i,cs+2,attr)
1711                    dlg.Destroy()
1712                    event.StopPropagation()
1713                    UpdateDrawAtoms()
1714            G2plt.PlotStructure(G2frame,data)
1715                   
1716        def RowSelect(event):
1717            r,c =  event.GetRow(),event.GetCol()
1718            if r < 0 and c < 0:
1719                if drawAtoms.IsSelection():
1720                    drawAtoms.ClearSelection()
1721            elif c < 0:                   #only row clicks
1722                if event.ControlDown():                   
1723                    if r in drawAtoms.GetSelectedRows():
1724                        drawAtoms.DeselectRow(r)
1725                    else:
1726                        drawAtoms.SelectRow(r,True)
1727                elif event.ShiftDown():
1728                    for row in range(r+1):
1729                        drawAtoms.SelectRow(row,True)
1730                else:
1731                    drawAtoms.ClearSelection()
1732                    drawAtoms.SelectRow(r,True)               
1733            drawingData['selectedAtoms'] = []
1734            drawingData['selectedAtoms'] = drawAtoms.GetSelectedRows()
1735            G2plt.PlotStructure(G2frame,data)                   
1736               
1737        table = []
1738        rowLabels = []
1739        for i,atom in enumerate(drawingData['Atoms']):
1740            table.append(atom[:colLabels.index('I/A')+1])
1741            rowLabels.append(str(i))
1742
1743        atomTable = G2gd.Table(table,rowLabels=rowLabels,colLabels=colLabels,types=Types)
1744        drawAtoms.SetTable(atomTable, True)
1745        drawAtoms.SetMargins(0,0)
1746        drawAtoms.AutoSizeColumns(True)
1747        drawAtoms.SetColSize(colLabels.index('Style'),80)
1748        drawAtoms.SetColSize(colLabels.index('Color'),50)
1749        drawAtoms.Bind(wg.EVT_GRID_CELL_CHANGE, RefreshAtomGrid)
1750        drawAtoms.Bind(wg.EVT_GRID_LABEL_LEFT_DCLICK, RefreshAtomGrid)
1751        drawAtoms.Bind(wg.EVT_GRID_CELL_LEFT_DCLICK, RefreshAtomGrid)
1752        drawAtoms.Bind(wg.EVT_GRID_LABEL_LEFT_CLICK, RowSelect)
1753        for i,atom in enumerate(drawingData['Atoms']):
1754            attr = wg.GridCellAttr()                #needs to be here - gets lost if outside loop!
1755            attr.SetReadOnly(True)
1756            attr.SetBackgroundColour(atom[cs+2])
1757            drawAtoms.SetAttr(i,cs+2,attr)
1758            drawAtoms.SetCellValue(i,cs+2,'')
1759        indx = drawingData['selectedAtoms']
1760        if indx:
1761            for r in range(len(atomData)):
1762                if r in indx:
1763                    drawAtoms.SelectRow(r)
1764        for c in range(len(colLabels)):
1765           attr = wg.GridCellAttr()                #needs to be here - gets lost if outside loop!
1766           attr.SetReadOnly(True)
1767           attr.SetBackgroundColour(VERY_LIGHT_GREY)
1768           if colLabels[c] not in ['Style','Label','Color']:
1769                drawAtoms.SetColAttr(c,attr)
1770        G2frame.dataFrame.setSizePosLeft([600,300])
1771       
1772        FindBondsDraw()
1773        drawAtoms.ClearSelection()
1774        G2plt.PlotStructure(G2frame,data)
1775
1776    def DrawAtomStyle(event):
1777        indx = drawAtoms.GetSelectedRows()
1778        if indx:
1779            generalData = data['General']
1780            atomData = data['Drawing']['Atoms']
1781            cx,ct,cs,ci = data['Drawing']['atomPtrs']
1782            styleChoice = [' ','lines','vdW balls','sticks','balls & sticks','ellipsoids','polyhedra']
1783            if generalData['Type'] == 'macromolecular':
1784                styleChoice = [' ','lines','vdW balls','sticks','balls & sticks','ellipsoids',
1785                'backbone','ribbons','schematic']
1786            dlg = wx.SingleChoiceDialog(G2frame,'Select','Atom drawing style',styleChoice)
1787            if dlg.ShowModal() == wx.ID_OK:
1788                sel = dlg.GetSelection()
1789                parms = styleChoice[sel]
1790                for r in indx:
1791                    atomData[r][cs] = parms
1792                    drawAtoms.SetCellValue(r,cs,parms)
1793            dlg.Destroy()
1794            FindBondsDraw()
1795            drawAtoms.ClearSelection()
1796            G2plt.PlotStructure(G2frame,data)
1797
1798    def DrawAtomLabel(event):
1799        indx = drawAtoms.GetSelectedRows()
1800        if indx:
1801            generalData = data['General']
1802            atomData = data['Drawing']['Atoms']
1803            cx,ct,cs,ci = data['Drawing']['atomPtrs']
1804            styleChoice = [' ','type','name','number']
1805            if generalData['Type'] == 'macromolecular':
1806                styleChoice = [' ','type','name','number','residue','1-letter','chain']
1807            dlg = wx.SingleChoiceDialog(G2frame,'Select','Atom label style',styleChoice)
1808            if dlg.ShowModal() == wx.ID_OK:
1809                sel = dlg.GetSelection()
1810                parms = styleChoice[sel]
1811                for r in indx:
1812                    atomData[r][cs+1] = parms
1813                    drawAtoms.SetCellValue(r,cs+1,parms)
1814            dlg.Destroy()
1815            drawAtoms.ClearSelection()
1816            G2plt.PlotStructure(G2frame,data)
1817           
1818    def DrawAtomColor(event):
1819
1820        indx = drawAtoms.GetSelectedRows()
1821        if indx:
1822            if len(indx) > 1:
1823                G2frame.dataFrame.SetStatusText('Select Custom Color, change color, Add to Custom Colors, then OK')
1824            else:
1825                G2frame.dataFrame.SetStatusText('Change color, Add to Custom Colors, then OK')
1826            generalData = data['General']
1827            atomData = data['Drawing']['Atoms']
1828            cx,ct,cs,ci = data['Drawing']['atomPtrs']
1829            atmColors = []
1830            atmTypes = []
1831            for r in indx:
1832                if atomData[r][cs+2] not in atmColors:
1833                    atmColors.append(atomData[r][cs+2])
1834                    atmTypes.append(atomData[r][ct])
1835                    if len(atmColors) > 16:
1836                        break
1837            colors = wx.ColourData()
1838            colors.SetChooseFull(True)
1839            for i,color in enumerate(atmColors):
1840                colors.SetCustomColour(i,color)
1841            dlg = wx.ColourDialog(G2frame,colors)
1842            if dlg.ShowModal() == wx.ID_OK:
1843                for i in range(len(atmColors)):                   
1844                    atmColors[i] = dlg.GetColourData().GetCustomColour(i)
1845                colorDict = dict(zip(atmTypes,atmColors))
1846                for r in indx:
1847                    color = colorDict[atomData[r][ct]]
1848                    atomData[r][cs+2] = color
1849                    attr = wg.GridCellAttr()                #needs to be here - gets lost if outside loop!
1850                    attr.SetBackgroundColour(color)
1851                    drawAtoms.SetAttr(r,cs+2,attr)
1852                    data['Drawing']['Atoms'][r][cs+2] = color
1853            drawAtoms.ClearSelection()
1854            dlg.Destroy()
1855            G2frame.dataFrame.SetStatusText('')
1856            G2plt.PlotStructure(G2frame,data)
1857           
1858    def ResetAtomColors(event):
1859        generalData = data['General']
1860        atomData = data['Drawing']['Atoms']
1861        cx,ct,cs,ci = data['Drawing']['atomPtrs']
1862        for atom in atomData:           
1863            atNum = generalData['AtomTypes'].index(atom[ct])
1864            atom[cs+2] = list(generalData['Color'][atNum])
1865        UpdateDrawAtoms()
1866        drawAtoms.ClearSelection()
1867        G2plt.PlotStructure(G2frame,data)       
1868       
1869    def SetViewPoint(event):
1870        indx = drawAtoms.GetSelectedRows()
1871        if indx:
1872            atomData = data['Drawing']['Atoms']
1873            cx = data['Drawing']['atomPtrs'][0]
1874            data['Drawing']['viewPoint'] = [atomData[indx[0]][cx:cx+3],[indx[0],0]]
1875            drawAtoms.ClearSelection()                                  #do I really want to do this?
1876            G2plt.PlotStructure(G2frame,data)
1877           
1878    def noDuplicate(xyz,atomData):                  #be careful where this is used - it's slow
1879        cx = data['Drawing']['atomPtrs'][0]
1880        if True in [np.allclose(np.array(xyz),np.array(atom[cx:cx+3]),atol=0.0002) for atom in atomData]:
1881            return False
1882        else:
1883            return True
1884               
1885    def AddSymEquiv(event):
1886        indx = drawAtoms.GetSelectedRows()
1887        indx.sort()
1888        if indx:
1889            colLabels = [drawAtoms.GetColLabelValue(c) for c in range(drawAtoms.GetNumberCols())]
1890            cx = colLabels.index('x')
1891            cuia = colLabels.index('I/A')
1892            cuij = cuia+2
1893            atomData = data['Drawing']['Atoms']
1894            generalData = data['General']
1895            SGData = generalData['SGData']
1896            dlg = SymOpDialog(G2frame,SGData,False)
1897            try:
1898                if dlg.ShowModal() == wx.ID_OK:
1899                    Inv,Cent,Opr,Cell,New = dlg.GetSelection()
1900                    Cell = np.array(Cell)
1901                    cent = SGData['SGCen'][Cent]
1902                    M,T = SGData['SGOps'][Opr]
1903                    for ind in indx:
1904                        XYZ = np.array(atomData[ind][cx:cx+3])
1905                        XYZ = np.inner(M,XYZ)+T
1906                        if Inv:
1907                            XYZ = -XYZ
1908                        XYZ = XYZ+cent+Cell
1909                        if noDuplicate(XYZ,atomData):
1910                            atom = copy.copy(atomData[ind])
1911                            atom[cx:cx+3] = XYZ
1912                            atomOp = atom[cx+3]
1913                            newOp = str(((Opr+1)+100*Cent)*(1-2*Inv))+'+'+ \
1914                                str(int(Cell[0]))+','+str(int(Cell[1]))+','+str(int(Cell[2]))                           
1915                            atom[cx+3] = G2spc.StringOpsProd(atomOp,newOp,SGData)
1916                            if atom[cuia] == 'A':
1917                                Uij = atom[cuij:cuij+6]
1918                                U = G2spc.Uij2U(Uij)
1919                                U = np.inner(np.inner(M,U),M)
1920                                Uij = G2spc.U2Uij(U)
1921                                atom[cuij:cuij+6] = Uij
1922                            atomData.append(atom)
1923            finally:
1924                dlg.Destroy()
1925            UpdateDrawAtoms()
1926            drawAtoms.ClearSelection()
1927            G2plt.PlotStructure(G2frame,data)
1928           
1929    def TransformSymEquiv(event):
1930        indx = drawAtoms.GetSelectedRows()
1931        indx.sort()
1932        if indx:
1933            atomData = data['Drawing']['Atoms']
1934            colLabels = [drawAtoms.GetColLabelValue(c) for c in range(drawAtoms.GetNumberCols())]
1935            cx = colLabels.index('x')
1936            cuia = colLabels.index('I/A')
1937            cuij = cuia+2
1938            atomData = data['Drawing']['Atoms']
1939            generalData = data['General']
1940            SGData = generalData['SGData']
1941            dlg = SymOpDialog(G2frame,SGData,False)
1942            try:
1943                if dlg.ShowModal() == wx.ID_OK:
1944                    Inv,Cent,Opr,Cell,New = dlg.GetSelection()
1945                    Cell = np.array(Cell)
1946                    cent = SGData['SGCen'][Cent]
1947                    M,T = SGData['SGOps'][Opr]
1948                    for ind in indx:
1949                        XYZ = np.array(atomData[ind][cx:cx+3])
1950                        XYZ = np.inner(M,XYZ)+T
1951                        if Inv:
1952                            XYZ = -XYZ
1953                        XYZ = XYZ+cent+Cell
1954                        atom = atomData[ind]
1955                        atom[cx:cx+3] = XYZ
1956                        atomOp = atom[cx+3]
1957                        newOp = str(((Opr+1)+100*Cent)*(1-2*Inv))+'+'+ \
1958                            str(int(Cell[0]))+','+str(int(Cell[1]))+','+str(int(Cell[2]))
1959                        atom[cx+3] = G2spc.StringOpsProd(atomOp,newOp,SGData)
1960                        if atom[cuia] == 'A':
1961                            Uij = atom[cuij:cuij+6]
1962                            U = G2spc.Uij2U(Uij)
1963                            U = np.inner(np.inner(M,U),M)
1964                            Uij = G2spc.U2Uij(U)
1965                            atom[cuij:cuij+6] = Uij
1966                    data['Drawing']['Atoms'] = atomData
1967            finally:
1968                dlg.Destroy()
1969            UpdateDrawAtoms()
1970            drawAtoms.ClearSelection()
1971            G2plt.PlotStructure(G2frame,data)
1972           
1973    def FillCoordSphere(event):
1974        generalData = data['General']
1975        Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7])
1976        radii = generalData['BondRadii']
1977        atomTypes = generalData['AtomTypes']
1978        try:
1979            indH = atomTypes.index('H')
1980            radii[indH] = 0.5
1981        except:
1982            pass           
1983        indx = drawAtoms.GetSelectedRows()
1984        if indx:
1985            indx.sort()
1986            atomData = data['Drawing']['Atoms']
1987            numAtoms = len(atomData)
1988            cx,ct,cs,ci = data['Drawing']['atomPtrs']
1989            generalData = data['General']
1990            SGData = generalData['SGData']
1991            cellArray = G2lat.CellBlock(1)
1992            for ind in indx:
1993                atomA = atomData[ind]
1994                xyzA = np.array(atomA[cx:cx+3])
1995                indA = atomTypes.index(atomA[ct])
1996                for atomB in atomData[:numAtoms]:
1997                    indB = atomTypes.index(atomB[ct])
1998                    sumR = radii[indA]+radii[indB]
1999                    xyzB = np.array(atomB[cx:cx+3])
2000                    for xyz in cellArray+xyzB:
2001                        dist = np.sqrt(np.sum(np.inner(Amat,xyz-xyzA)**2))
2002                        if 0 < dist <= data['Drawing']['radiusFactor']*sumR:
2003                            if noDuplicate(xyz,atomData):
2004                                oprB = atomB[cx+3]
2005                                C = xyz-xyzB
2006                                newOp = '1+'+str(int(round(C[0])))+','+str(int(round(C[1])))+','+str(int(round(C[2])))
2007                                newAtom = atomB[:]
2008                                newAtom[cx:cx+3] = xyz
2009                                newAtom[cx+3] = G2spc.StringOpsProd(oprB,newOp,SGData)
2010                                atomData.append(newAtom)
2011            data['Drawing']['Atoms'] = atomData
2012            UpdateDrawAtoms()
2013            drawAtoms.ClearSelection()
2014            G2plt.PlotStructure(G2frame,data)
2015           
2016    def FillUnitCell(event):
2017        indx = drawAtoms.GetSelectedRows()
2018        indx.sort()
2019        if indx:
2020            atomData = data['Drawing']['Atoms']
2021            colLabels = [drawAtoms.GetColLabelValue(c) for c in range(drawAtoms.GetNumberCols())]
2022            cx = colLabels.index('x')
2023            cuia = colLabels.index('I/A')
2024            cuij = cuia+2
2025            generalData = data['General']
2026            SGData = generalData['SGData']
2027            for ind in indx:
2028                atom = atomData[ind]
2029                XYZ = np.array(atom[cx:cx+3])
2030                if atom[cuia] == 'A':
2031                    Uij = atom[cuij:cuij+6]
2032                    result = G2spc.GenAtom(XYZ,SGData,False,Uij,False)
2033                    for item in result:
2034                        atom = copy.copy(atomData[ind])
2035                        atom[cx:cx+3] = item[0]
2036                        atom[cx+3] = str(item[2])+'+' \
2037                            +str(item[3][0])+','+str(item[3][1])+','+str(item[3][2])
2038                        atom[cuij:cuij+6] = item[1]
2039                        Opp = G2spc.Opposite(item[0])
2040                        for xyz in Opp:
2041                            if noDuplicate(xyz,atomData):
2042                                cell = np.asarray(np.rint(xyz-atom[cx:cx+3]),dtype=np.int32)
2043                                cell = '1'+'+'+ \
2044                                    str(cell[0])+','+str(cell[1])+','+str(cell[2])
2045                                atom[cx:cx+3] = xyz
2046                                atom[cx+3] = G2spc.StringOpsProd(cell,atom[cx+3],SGData)
2047                                atomData.append(atom[:])
2048                else:
2049                    result = G2spc.GenAtom(XYZ,SGData,False,Move=False)
2050                    for item in result:
2051                        atom = copy.copy(atomData[ind])
2052                        atom[cx:cx+3] = item[0]
2053                        atom[cx+3] = str(item[1])+'+' \
2054                            +str(item[2][0])+','+str(item[2][1])+','+str(item[2][2])
2055                        Opp = G2spc.Opposite(item[0])
2056                        for xyz in Opp:
2057                            if noDuplicate(xyz,atomData):
2058                                cell = np.asarray(np.rint(xyz-atom[cx:cx+3]),dtype=np.int32)
2059                                cell = '1'+'+'+ \
2060                                    str(cell[0])+','+str(cell[1])+','+str(cell[2])
2061                                atom[cx:cx+3] = xyz
2062                                atom[cx+3] = G2spc.StringOpsProd(cell,atom[cx+3],SGData)
2063                                atomData.append(atom[:])               
2064                data['Drawing']['Atoms'] = atomData
2065            UpdateDrawAtoms()
2066            drawAtoms.ClearSelection()
2067            G2plt.PlotStructure(G2frame,data)
2068           
2069    def FindBondsToo():                         #works but slow for large structures - keep as reference
2070        cx,ct,cs,ci = data['Drawing']['atomPtrs']
2071        atomData = data['Drawing']['Atoms']
2072        generalData = data['General']
2073        Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7])
2074        radii = generalData['BondRadii']
2075        atomTypes = generalData['AtomTypes']
2076        try:
2077            indH = atomTypes.index('H')
2078            radii[indH] = 0.5
2079        except:
2080            pass           
2081        for atom in atomData:
2082            atom[-1] = []
2083        Atoms = []
2084        for i,atom in enumerate(atomData):
2085            Atoms.append([i,np.array(atom[cx:cx+3]),atom[cs],radii[atomTypes.index(atom[ct])]])
2086        for atomA in Atoms:
2087            if atomA[2] in ['lines','sticks','ellipsoids','balls & sticks','polyhedra']:
2088                for atomB in Atoms:                   
2089                    Dx = atomB[1]-atomA[1]
2090                    DX = np.inner(Amat,Dx)
2091                    dist = np.sqrt(np.sum(DX**2))
2092                    sumR = atomA[3]+atomB[3]
2093                    if 0.5 < dist <= 0.85*sumR:
2094                        i = atomA[0]
2095                        if atomA[2] == 'polyhedra':
2096                            atomData[i][-1].append(DX)
2097                        elif atomB[1] != 'polyhedra':
2098                            j = atomB[0]
2099                            atomData[i][-1].append(Dx*atomA[3]/sumR)
2100                            atomData[j][-1].append(-Dx*atomB[3]/sumR)
2101                   
2102    def FindBondsDraw():                    #uses numpy & masks - very fast even for proteins!
2103        import numpy.ma as ma
2104        cx,ct,cs,ci = data['Drawing']['atomPtrs']
2105        hydro = data['Drawing']['showHydrogen']
2106        atomData = data['Drawing']['Atoms']
2107        generalData = data['General']
2108        Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7])
2109        radii = generalData['BondRadii']
2110        atomTypes = generalData['AtomTypes']
2111        try:
2112            indH = atomTypes.index('H')
2113            radii[indH] = 0.5
2114        except:
2115            pass           
2116        for atom in atomData:
2117            atom[-2] = []               #clear out old bonds/polyhedra
2118            atom[-1] = []
2119        Indx = range(len(atomData))
2120        Atoms = []
2121        Styles = []
2122        Radii = []
2123        for atom in atomData:
2124            Atoms.append(np.array(atom[cx:cx+3]))
2125            Styles.append(atom[cs])
2126            try:
2127                if not hydro and atom[ct] == 'H':
2128                    Radii.append(0.0)
2129                else:
2130                    Radii.append(radii[atomTypes.index(atom[ct])])
2131            except ValueError:          #changed atom type!
2132                Radii.append(0.20)
2133        Atoms = np.array(Atoms)
2134        Radii = np.array(Radii)
2135        IASR = zip(Indx,Atoms,Styles,Radii)
2136        for atomA in IASR:
2137            if atomA[2] in ['lines','sticks','ellipsoids','balls & sticks','polyhedra']:
2138                Dx = Atoms-atomA[1]
2139                dist = ma.masked_less(np.sqrt(np.sum(np.inner(Amat,Dx)**2,axis=0)),0.5) #gets rid of G2frame & disorder "bonds" < 0.5A
2140                sumR = atomA[3]+Radii
2141                IndB = ma.nonzero(ma.masked_greater(dist-data['Drawing']['radiusFactor']*sumR,0.))                 #get indices of bonded atoms
2142                i = atomA[0]
2143                for j in IndB[0]:
2144                    if Styles[i] == 'polyhedra':
2145                        atomData[i][-2].append(np.inner(Amat,Dx[j]))
2146                    elif Styles[j] != 'polyhedra' and j > i:
2147                        atomData[i][-2].append(Dx[j]*Radii[i]/sumR[j])
2148                        atomData[j][-2].append(-Dx[j]*Radii[j]/sumR[j])
2149                if Styles[i] == 'polyhedra':
2150                    Bonds = atomData[i][-2]
2151                    Faces = []
2152                    if len(Bonds) > 2:
2153                        FaceGen = G2lat.uniqueCombinations(Bonds,3)     #N.B. this is a generator
2154                        for face in FaceGen:
2155                            vol = nl.det(face)
2156                            if abs(vol) > 1. or len(Bonds) == 3:
2157                                if vol < 0.:
2158                                    face = [face[0],face[2],face[1]]
2159                                face = np.array(face)
2160                                if not np.array([np.array(nl.det(face-bond))+0.0001 < 0 for bond in Bonds]).any():
2161                                    norm = np.cross(face[1]-face[0],face[2]-face[0])
2162                                    norm /= np.sqrt(np.sum(norm**2))
2163                                    Faces.append([face,norm])
2164                        atomData[i][-1] = Faces
2165                       
2166    def DrawAtomsDelete(event):   
2167        indx = drawAtoms.GetSelectedRows()
2168        indx.sort()
2169        if indx:
2170            atomData = data['Drawing']['Atoms']
2171            indx.reverse()
2172            for ind in indx:
2173                del atomData[ind]
2174            UpdateDrawAtoms()
2175            drawAtoms.ClearSelection()
2176            G2plt.PlotStructure(G2frame,data)
2177        event.StopPropagation()
2178       
2179    def OnReloadDrawAtoms(event):
2180        data['Drawing']['Atoms'] = []
2181        UpdateDrawAtoms()
2182        drawAtoms.ClearSelection()
2183        G2plt.PlotStructure(G2frame,data)
2184        event.StopPropagation()
2185       
2186    def FindAtomIndexByIDs(atomData,IDs,Draw=True):
2187        indx = []
2188        for i,atom in enumerate(atomData):
2189            if Draw and atom[-3] in IDs:
2190                indx.append(i)
2191            elif atom[-1] in IDs:
2192                indx.append(i)
2193        return indx
2194       
2195    def DrawAtomsDeleteByIDs(IDs):
2196        atomData = data['Drawing']['Atoms']
2197        indx = FindAtomIndexByIDs(atomData,IDs)
2198        indx.reverse()
2199        for ind in indx:
2200            del atomData[ind]
2201           
2202    def ChangeDrawAtomsByIDs(colName,IDs,value):
2203        atomData = data['Drawing']['Atoms']
2204        cx,ct,cs,ci = data['Drawing']['atomPtrs']
2205        if colName == 'Name':
2206            col = ct-1
2207        elif colName == 'Type':
2208            col = ct
2209        elif colName == 'I/A':
2210            col = cs
2211        indx = FindAtomIndexByIDs(atomData,IDs)
2212        for ind in indx:
2213            atomData[ind][col] = value
2214               
2215    def OnDrawPlane(event):
2216        indx = drawAtoms.GetSelectedRows()
2217        if len(indx) < 4:
2218            print '**** ERROR - need 4+ atoms for plane calculation'
2219            return
2220        PlaneData = {}
2221        drawingData = data['Drawing']
2222        atomData = drawingData['Atoms']
2223        colLabels = [drawAtoms.GetColLabelValue(c) for c in range(drawAtoms.GetNumberCols())]
2224        cx = colLabels.index('x')
2225        cn = colLabels.index('Name')
2226        xyz = []
2227        for i,atom in enumerate(atomData):
2228            if i in indx:
2229                xyz.append([i,]+atom[cn:cn+2]+atom[cx:cx+3])
2230        generalData = data['General']
2231        PlaneData['Name'] = generalData['Name']
2232        PlaneData['Atoms'] = xyz
2233        PlaneData['Cell'] = generalData['Cell'][1:] #+ volume
2234        G2str.BestPlane(PlaneData)
2235   
2236    def OnDrawDAT(event):
2237        #distance, angle, torsion
2238        indx = drawAtoms.GetSelectedRows()
2239        if len(indx) not in [2,3,4]:
2240            print '**** ERROR - wrong number of atoms for distance, angle or torsion calculation'
2241            return
2242        DATData = {}
2243        ocx,oct,ocs,cia = data['General']['AtomPtrs']
2244        drawingData = data['Drawing']
2245        atomData = data['Atoms']
2246        atomDData = drawingData['Atoms']
2247        colLabels = [drawAtoms.GetColLabelValue(c) for c in range(drawAtoms.GetNumberCols())]
2248        cx = colLabels.index('x')
2249        cn = colLabels.index('Name')
2250        cid = colLabels.index('I/A')+8
2251        xyz = []
2252        Oxyz = []
2253        DATData['Natoms'] = len(indx)
2254        for i in indx:
2255            atom = atomDData[i]
2256            xyz.append([i,]+atom[cn:cn+2]+atom[cx:cx+4]) #also gets Sym Op
2257            id = FindAtomIndexByIDs(atomData,[atom[cid],],False)[0]
2258            Oxyz.append([id,]+atomData[id][cx+1:cx+4])
2259        DATData['Datoms'] = xyz
2260        DATData['Oatoms'] = Oxyz
2261        generalData = data['General']
2262        DATData['Name'] = generalData['Name']
2263        DATData['SGData'] = generalData['SGData']
2264        DATData['Cell'] = generalData['Cell'][1:] #+ volume
2265        if 'pId' in data:
2266            DATData['pId'] = data['pId']
2267            DATData['covData'] = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.root, 'Covariance'))
2268        G2str.DisAglTor(DATData)
2269               
2270################################################################################
2271#### Draw Options page
2272################################################################################
2273
2274    def UpdateDrawOptions():
2275        import copy
2276        import wx.lib.colourselect as wcs
2277        generalData = data['General']
2278        SetupDrawingData()
2279        drawingData = data['Drawing']
2280        if generalData['Type'] == 'nuclear':
2281            pickChoice = ['Atoms','Bonds','Torsions','Planes']
2282        elif generalData['Type'] == 'macromolecular':
2283            pickChoice = ['Atoms','Residues','Chains','Bonds','Torsions','Planes','phi/psi']
2284
2285        def SlopSizer():
2286           
2287            def OnCameraPos(event):
2288                drawingData['cameraPos'] = cameraPos.GetValue()
2289                cameraPosTxt.SetLabel(' Camera Distance: '+'%.2f'%(drawingData['cameraPos']))
2290                ZclipTxt.SetLabel(' Z clipping: '+'%.2fA'%(drawingData['Zclip']*drawingData['cameraPos']/100.))
2291                G2plt.PlotStructure(G2frame,data)
2292
2293            def OnZclip(event):
2294                drawingData['Zclip'] = Zclip.GetValue()
2295                ZclipTxt.SetLabel(' Z clipping: '+'%.2fA'%(drawingData['Zclip']*drawingData['cameraPos']/100.))
2296                G2plt.PlotStructure(G2frame,data)
2297               
2298            def OnVdWScale(event):
2299                drawingData['vdwScale'] = vdwScale.GetValue()/100.
2300                vdwScaleTxt.SetLabel(' van der Waals scale: '+'%.2f'%(drawingData['vdwScale']))
2301                G2plt.PlotStructure(G2frame,data)
2302   
2303            def OnEllipseProb(event):
2304                drawingData['ellipseProb'] = ellipseProb.GetValue()
2305                ellipseProbTxt.SetLabel(' Ellipsoid probability: '+'%d%%'%(drawingData['ellipseProb']))
2306                G2plt.PlotStructure(G2frame,data)
2307   
2308            def OnBallScale(event):
2309                drawingData['ballScale'] = ballScale.GetValue()/100.
2310                ballScaleTxt.SetLabel(' Ball scale: '+'%.2f'%(drawingData['ballScale']))
2311                G2plt.PlotStructure(G2frame,data)
2312
2313            def OnBondRadius(event):
2314                drawingData['bondRadius'] = bondRadius.GetValue()/100.
2315                bondRadiusTxt.SetLabel(' Bond radius, A: '+'%.2f'%(drawingData['bondRadius']))
2316                G2plt.PlotStructure(G2frame,data)
2317               
2318            def OnContourLevel(event):
2319                drawingData['contourLevel'] = contourLevel.GetValue()/100.
2320                contourLevelTxt.SetLabel(' Contour level: '+'%.2f'%(drawingData['contourLevel']*generalData['Map']['rhoMax']))
2321                G2plt.PlotStructure(G2frame,data)
2322
2323            def OnMapSize(event):
2324                drawingData['mapSize'] = mapSize.GetValue()/10.
2325                mapSizeTxt.SetLabel(' Map radius, A: '+'%.1f'%(drawingData['mapSize']))
2326                G2plt.PlotStructure(G2frame,data)
2327
2328           
2329            slopSizer = wx.BoxSizer(wx.HORIZONTAL)
2330            slideSizer = wx.FlexGridSizer(7,2)
2331            slideSizer.AddGrowableCol(1,1)
2332   
2333            cameraPosTxt = wx.StaticText(dataDisplay,-1,
2334                ' Camera Distance: '+'%.2f'%(drawingData['cameraPos']),name='cameraPos')
2335            slideSizer.Add(cameraPosTxt,0,wx.ALIGN_CENTER_VERTICAL)
2336            cameraPos = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=drawingData['cameraPos'],name='cameraSlider')
2337            cameraPos.SetRange(10,500)
2338            cameraPos.Bind(wx.EVT_SLIDER, OnCameraPos)
2339            slideSizer.Add(cameraPos,1,wx.EXPAND|wx.RIGHT)
2340           
2341            ZclipTxt = wx.StaticText(dataDisplay,-1,' Z clipping: '+'%.2fA'%(drawingData['Zclip']*drawingData['cameraPos']/100.))
2342            slideSizer.Add(ZclipTxt,0,wx.ALIGN_CENTER_VERTICAL)
2343            Zclip = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=drawingData['Zclip'])
2344            Zclip.SetRange(1,99)
2345            Zclip.Bind(wx.EVT_SLIDER, OnZclip)
2346            slideSizer.Add(Zclip,1,wx.EXPAND|wx.RIGHT)
2347           
2348            vdwScaleTxt = wx.StaticText(dataDisplay,-1,' van der Waals scale: '+'%.2f'%(drawingData['vdwScale']))
2349            slideSizer.Add(vdwScaleTxt,0,wx.ALIGN_CENTER_VERTICAL)
2350            vdwScale = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=int(100*drawingData['vdwScale']))
2351            vdwScale.Bind(wx.EVT_SLIDER, OnVdWScale)
2352            slideSizer.Add(vdwScale,1,wx.EXPAND|wx.RIGHT)
2353   
2354            ellipseProbTxt = wx.StaticText(dataDisplay,-1,' Ellipsoid probability: '+'%d%%'%(drawingData['ellipseProb']))
2355            slideSizer.Add(ellipseProbTxt,0,wx.ALIGN_CENTER_VERTICAL)
2356            ellipseProb = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=drawingData['ellipseProb'])
2357            ellipseProb.SetRange(1,99)
2358            ellipseProb.Bind(wx.EVT_SLIDER, OnEllipseProb)
2359            slideSizer.Add(ellipseProb,1,wx.EXPAND|wx.RIGHT)
2360   
2361            ballScaleTxt = wx.StaticText(dataDisplay,-1,' Ball scale: '+'%.2f'%(drawingData['ballScale']))
2362            slideSizer.Add(ballScaleTxt,0,wx.ALIGN_CENTER_VERTICAL)
2363            ballScale = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=int(100*drawingData['ballScale']))
2364            ballScale.Bind(wx.EVT_SLIDER, OnBallScale)
2365            slideSizer.Add(ballScale,1,wx.EXPAND|wx.RIGHT)
2366   
2367            bondRadiusTxt = wx.StaticText(dataDisplay,-1,' Bond radius, A: '+'%.2f'%(drawingData['bondRadius']))
2368            slideSizer.Add(bondRadiusTxt,0,wx.ALIGN_CENTER_VERTICAL)
2369            bondRadius = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=int(100*drawingData['bondRadius']))
2370            bondRadius.SetRange(1,25)
2371            bondRadius.Bind(wx.EVT_SLIDER, OnBondRadius)
2372            slideSizer.Add(bondRadius,1,wx.EXPAND|wx.RIGHT)
2373           
2374            if generalData['Map']['rhoMax']:
2375                contourLevelTxt = wx.StaticText(dataDisplay,-1,' Contour level: '+'%.2f'%(drawingData['contourLevel']*generalData['Map']['rhoMax']))
2376                slideSizer.Add(contourLevelTxt,0,wx.ALIGN_CENTER_VERTICAL)
2377                contourLevel = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=int(100*drawingData['contourLevel']))
2378                contourLevel.SetRange(1,100)
2379                contourLevel.Bind(wx.EVT_SLIDER, OnContourLevel)
2380                slideSizer.Add(contourLevel,1,wx.EXPAND|wx.RIGHT)
2381                mapSizeTxt = wx.StaticText(dataDisplay,-1,' Map radius, A: '+'%.1f'%(drawingData['mapSize']))
2382                slideSizer.Add(mapSizeTxt,0,wx.ALIGN_CENTER_VERTICAL)
2383                mapSize = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=int(10*drawingData['mapSize']))
2384                mapSize.SetRange(1,100)
2385                mapSize.Bind(wx.EVT_SLIDER, OnMapSize)
2386                slideSizer.Add(mapSize,1,wx.EXPAND|wx.RIGHT)
2387           
2388            slopSizer.Add(slideSizer,1,wx.EXPAND|wx.RIGHT)
2389            slopSizer.Add((10,5),0)
2390            slopSizer.SetMinSize(wx.Size(350,10))
2391            return slopSizer
2392           
2393        def ShowSizer():
2394           
2395            def OnBackColor(event):
2396                drawingData['backColor'] = event.GetValue()
2397                G2plt.PlotStructure(G2frame,data)
2398   
2399            def OnShowABC(event):
2400                drawingData['showABC'] = showABC.GetValue()
2401                G2plt.PlotStructure(G2frame,data)
2402   
2403            def OnShowUnitCell(event):
2404                drawingData['unitCellBox'] = unitCellBox.GetValue()
2405                G2plt.PlotStructure(G2frame,data)
2406   
2407            def OnShowHyd(event):
2408                drawingData['showHydrogen'] = showHydrogen.GetValue()
2409                FindBondsDraw()
2410                G2plt.PlotStructure(G2frame,data)
2411               
2412            showSizer = wx.FlexGridSizer(5,3,5,0)           
2413            lineSizer = wx.BoxSizer(wx.HORIZONTAL)
2414            lineSizer.Add(wx.StaticText(dataDisplay,-1,' Background color:'),0,wx.ALIGN_CENTER_VERTICAL)
2415            backColor = wcs.ColourSelect(dataDisplay, -1,colour=drawingData['backColor'],size=wx.Size(25,25))
2416            backColor.Bind(wcs.EVT_COLOURSELECT, OnBackColor)
2417            lineSizer.Add(backColor,0,wx.ALIGN_CENTER_VERTICAL)
2418            showSizer.Add(lineSizer,0,)
2419           
2420            showSizer.Add(wx.StaticText(dataDisplay,-1,' View Point:  '),0,wx.ALIGN_CENTER_VERTICAL)
2421            VP = drawingData['viewPoint'][0]
2422            viewPoint = wx.TextCtrl(dataDisplay,value='%.3f, %.3f, %.3f'%(VP[0],VP[1],VP[2]),
2423                style=wx.TE_READONLY,size=wx.Size(120,20),name='viewPoint')
2424            viewPoint.SetBackgroundColour(VERY_LIGHT_GREY)
2425            showSizer.Add(viewPoint,0,wx.ALIGN_CENTER_VERTICAL)
2426           
2427            showABC = wx.CheckBox(dataDisplay,-1,label=' Show test point?')
2428            showABC.Bind(wx.EVT_CHECKBOX, OnShowABC)
2429            showABC.SetValue(drawingData['showABC'])
2430            showSizer.Add(showABC,0,wx.ALIGN_CENTER_VERTICAL)
2431   
2432            unitCellBox = wx.CheckBox(dataDisplay,-1,label=' Show unit cell?')
2433            unitCellBox.Bind(wx.EVT_CHECKBOX, OnShowUnitCell)
2434            unitCellBox.SetValue(drawingData['unitCellBox'])
2435            showSizer.Add(unitCellBox,0,wx.ALIGN_CENTER_VERTICAL)
2436   
2437            showHydrogen = wx.CheckBox(dataDisplay,-1,label=' Show hydrogens?')
2438            showHydrogen.Bind(wx.EVT_CHECKBOX, OnShowHyd)
2439            showHydrogen.SetValue(drawingData['showHydrogen'])
2440            showSizer.Add(showHydrogen,0,wx.ALIGN_CENTER_VERTICAL)
2441            return showSizer
2442           
2443        def RadSizer():
2444           
2445            def OnSizeHatoms(event):
2446                try:
2447                    value = max(0.1,min(1.2,float(sizeH.GetValue())))
2448                except ValueError:
2449                    value = 0.5
2450                drawingData['sizeH'] = value
2451                sizeH.SetValue("%.2f"%(value))
2452                G2plt.PlotStructure(G2frame,data)
2453               
2454            def OnRadFactor(event):
2455                try:
2456                    value = max(0.1,min(1.2,float(radFactor.GetValue())))
2457                except ValueError:
2458                    value = 0.85
2459                drawingData['radiusFactor'] = value
2460                radFactor.SetValue("%.2f"%(value))
2461                FindBondsDraw()
2462                G2plt.PlotStructure(G2frame,data)
2463           
2464            radSizer = wx.BoxSizer(wx.HORIZONTAL)
2465            radSizer.Add(wx.StaticText(dataDisplay,-1,' Hydrogen radius, A:  '),0,wx.ALIGN_CENTER_VERTICAL)
2466            sizeH = wx.TextCtrl(dataDisplay,-1,value='%.2f'%(drawingData['sizeH']),size=wx.Size(60,20),style=wx.TE_PROCESS_ENTER)
2467            sizeH.Bind(wx.EVT_TEXT_ENTER,OnSizeHatoms)
2468            sizeH.Bind(wx.EVT_KILL_FOCUS,OnSizeHatoms)
2469            radSizer.Add(sizeH,0,wx.ALIGN_CENTER_VERTICAL)
2470   
2471            radSizer.Add(wx.StaticText(dataDisplay,-1,' Bond search factor:  '),0,wx.ALIGN_CENTER_VERTICAL)
2472            radFactor = wx.TextCtrl(dataDisplay,value='%.2f'%(drawingData['radiusFactor']),size=wx.Size(60,20),style=wx.TE_PROCESS_ENTER)
2473            radFactor.Bind(wx.EVT_TEXT_ENTER,OnRadFactor)
2474            radFactor.Bind(wx.EVT_KILL_FOCUS,OnRadFactor)
2475            radSizer.Add(radFactor,0,wx.ALIGN_CENTER_VERTICAL)
2476            return radSizer
2477
2478        drawOptions.DestroyChildren()
2479        dataDisplay = wx.Panel(drawOptions)
2480        mainSizer = wx.BoxSizer(wx.VERTICAL)
2481        mainSizer.Add((5,5),0)
2482        mainSizer.Add(wx.StaticText(dataDisplay,-1,' Drawing controls:'),0,wx.ALIGN_CENTER_VERTICAL)
2483        mainSizer.Add((5,5),0)       
2484        mainSizer.Add(SlopSizer(),0)
2485        mainSizer.Add((5,5),0)
2486        mainSizer.Add(ShowSizer(),0,)
2487        mainSizer.Add((5,5),0)
2488        mainSizer.Add(RadSizer(),0,)
2489
2490        dataDisplay.SetSizer(mainSizer)
2491        Size = mainSizer.Fit(G2frame.dataFrame)
2492        Size[1] += 26                           #compensate for status bar
2493        dataDisplay.SetSize(Size)
2494        G2frame.dataFrame.setSizePosLeft(Size)
2495
2496################################################################################
2497####  Texture routines
2498################################################################################
2499       
2500    def UpdateTexture():
2501        generalData = data['General']       
2502        SGData = generalData['SGData']
2503        try:
2504            textureData = generalData['SH Texture']
2505        except KeyError:            #fix old files!
2506            textureData = generalData['SH Texture'] = {'Order':0,'Model':'cylindrical',
2507                'Sample omega':[False,0.0],'Sample chi':[False,0.0],'Sample phi':[False,0.0],
2508                'SH Coeff':[False,{}],'SHShow':False,'PFhkl':[0,0,1],
2509                'PFxyz':[0,0,1.],'PlotType':'Pole figure'}
2510        if 'SHShow' not in textureData:     #another fix
2511            textureData.update({'SHShow':False,'PFhkl':[0,0,1],'PFxyz':[0,0,1.],'PlotType':'Pole figure'})
2512        try:                        #another fix!
2513            x = textureData['PlotType']
2514        except KeyError:
2515            textureData.update({'PFxyz':[0,0,1.],'PlotType':'Pole figure'})
2516        shModels = ['cylindrical','none','shear - 2/m','rolling - mmm']
2517        SamSym = dict(zip(shModels,['0','-1','2/m','mmm']))
2518        if generalData['doPawley'] and G2gd.GetPatternTreeItemId(G2frame,G2frame.root,'Sequental results'):
2519            G2frame.dataFrame.RefineTexture.Enable(True)
2520        shAngles = ['omega','chi','phi']
2521       
2522        def SetSHCoef():
2523            cofNames = G2lat.GenSHCoeff(SGData['SGLaue'],SamSym[textureData['Model']],textureData['Order'])
2524            newSHCoef = dict(zip(cofNames,np.zeros(len(cofNames))))
2525            SHCoeff = textureData['SH Coeff'][1]
2526            for cofName in SHCoeff:
2527                if cofName in  cofNames:
2528                    newSHCoef[cofName] = SHCoeff[cofName]
2529            return newSHCoef
2530       
2531        def OnShOrder(event):
2532            Obj = event.GetEventObject()
2533            textureData['Order'] = int(Obj.GetValue())
2534            textureData['SH Coeff'][1] = SetSHCoef()
2535            wx.CallAfter(UpdateTexture)
2536            G2plt.PlotTexture(G2frame,data)
2537                       
2538        def OnShModel(event):
2539            Obj = event.GetEventObject()
2540            textureData['Model'] = Obj.GetValue()
2541            textureData['SH Coeff'][1] = SetSHCoef()
2542            wx.CallAfter(UpdateTexture)
2543            G2plt.PlotTexture(G2frame,data)
2544           
2545        def OnSHRefine(event):
2546            Obj = event.GetEventObject()
2547            textureData['SH Coeff'][0] = Obj.GetValue()
2548           
2549        def OnSHShow(event):
2550            Obj = event.GetEventObject()
2551            textureData['SHShow'] = Obj.GetValue()
2552            wx.CallAfter(UpdateTexture)
2553           
2554        def OnProjSel(event):
2555            Obj = event.GetEventObject()
2556            G2frame.Projection = Obj.GetValue()
2557            G2plt.PlotTexture(G2frame,data)
2558           
2559        def OnColorSel(event):
2560            Obj = event.GetEventObject()
2561            G2frame.ContourColor = Obj.GetValue()
2562            G2plt.PlotTexture(G2frame,data)
2563           
2564        def OnAngRef(event):
2565            Obj = event.GetEventObject()
2566            textureData[angIndx[Obj.GetId()]][0] = Obj.GetValue()
2567           
2568        def OnAngValue(event):
2569            Obj = event.GetEventObject()
2570            try:
2571                value =  float(Obj.GetValue())
2572            except ValueError:
2573                value = textureData[valIndx[Obj.GetId()]][1]
2574            Obj.SetValue('%8.2f'%(value))
2575            textureData[valIndx[Obj.GetId()]][1] = value
2576           
2577        def OnODFValue(event): 
2578            Obj = event.GetEventObject()
2579            try:
2580                value =  float(Obj.GetValue())
2581            except ValueError:
2582                value = textureData['SH Coeff'][1][ODFIndx[Obj.GetId()]]
2583            Obj.SetValue('%8.3f'%(value))
2584            textureData['SH Coeff'][1][ODFIndx[Obj.GetId()]] = value
2585            G2plt.PlotTexture(G2frame,data)
2586           
2587        def OnPfType(event):
2588            Obj = event.GetEventObject()
2589            textureData['PlotType'] = Obj.GetValue()
2590            wx.CallAfter(UpdateTexture)
2591            G2plt.PlotTexture(G2frame,data)
2592           
2593        def OnPFValue(event):
2594            Obj = event.GetEventObject()
2595            Saxis = Obj.GetValue().split()
2596            if textureData['PlotType'] in ['Pole figure','Axial pole distribution']:               
2597                try:
2598                    hkl = [int(Saxis[i]) for i in range(3)]
2599                except (ValueError,IndexError):
2600                    hkl = textureData['PFhkl']
2601                if not np.any(np.array(hkl)):       #can't be all zeros!
2602                    hkl = textureData['PFhkl']
2603                Obj.SetValue('%d %d %d'%(hkl[0],hkl[1],hkl[2]))
2604                textureData['PFhkl'] = hkl
2605            else:
2606                try:
2607                    xyz = [float(Saxis[i]) for i in range(3)]
2608                except (ValueError,IndexError):
2609                    xyz = textureData['PFxyz']
2610                if not np.any(np.array(xyz)):       #can't be all zeros!
2611                    xyz = textureData['PFxyz']
2612                Obj.SetValue('%3.1f %3.1f %3.1f'%(xyz[0],xyz[1],xyz[2]))
2613                textureData['PFxyz'] = xyz
2614            G2plt.PlotTexture(G2frame,data)
2615
2616        if Texture.GetSizer():
2617            Texture.GetSizer().Clear(True)
2618        mainSizer = wx.BoxSizer(wx.VERTICAL)
2619        titleSizer = wx.BoxSizer(wx.HORIZONTAL)
2620        titleSizer.Add(wx.StaticText(Texture,-1,'Spherical harmonics texture data for '+PhaseName+':'),0,wx.ALIGN_CENTER_VERTICAL)
2621        titleSizer.Add(wx.StaticText(Texture,-1,
2622            ' Texture Index J = %7.3f'%(G2lat.textureIndex(textureData['SH Coeff'][1]))),
2623            0,wx.ALIGN_CENTER_VERTICAL)
2624        mainSizer.Add(titleSizer,0)
2625        mainSizer.Add((0,5),0)
2626        shSizer = wx.FlexGridSizer(1,6,5,5)
2627        shSizer.Add(wx.StaticText(Texture,-1,'Texture model: '),0,wx.ALIGN_CENTER_VERTICAL)
2628        shModel = wx.ComboBox(Texture,-1,value=textureData['Model'],choices=shModels,
2629            style=wx.CB_READONLY|wx.CB_DROPDOWN)
2630        shModel.Bind(wx.EVT_COMBOBOX,OnShModel)
2631        shSizer.Add(shModel,0,wx.ALIGN_CENTER_VERTICAL)
2632        shSizer.Add(wx.StaticText(Texture,-1,'  Harmonic order: '),0,wx.ALIGN_CENTER_VERTICAL)
2633        shOrder = wx.ComboBox(Texture,-1,value=str(textureData['Order']),choices=[str(2*i) for i in range(18)],
2634            style=wx.CB_READONLY|wx.CB_DROPDOWN)
2635        shOrder.Bind(wx.EVT_COMBOBOX,OnShOrder)
2636        shSizer.Add(shOrder,0,wx.ALIGN_CENTER_VERTICAL)
2637        shRef = wx.CheckBox(Texture,-1,label=' Refine texture?')
2638        shRef.SetValue(textureData['SH Coeff'][0])
2639        shRef.Bind(wx.EVT_CHECKBOX, OnSHRefine)
2640        shSizer.Add(shRef,0,wx.ALIGN_CENTER_VERTICAL)
2641        shShow = wx.CheckBox(Texture,-1,label=' Show coeff.?')
2642        shShow.SetValue(textureData['SHShow'])
2643        shShow.Bind(wx.EVT_CHECKBOX, OnSHShow)
2644        shSizer.Add(shShow,0,wx.ALIGN_CENTER_VERTICAL)
2645        mainSizer.Add(shSizer,0,0)
2646        mainSizer.Add((0,5),0)
2647        PTSizer = wx.FlexGridSizer(2,4,5,5)
2648        PTSizer.Add(wx.StaticText(Texture,-1,' Texture plot type: '),0,wx.ALIGN_CENTER_VERTICAL)
2649        choices = ['Axial pole distribution','Pole figure','Inverse pole figure']           
2650        pfType = wx.ComboBox(Texture,-1,value=str(textureData['PlotType']),choices=choices,
2651            style=wx.CB_READONLY|wx.CB_DROPDOWN)
2652        pfType.Bind(wx.EVT_COMBOBOX,OnPfType)
2653        PTSizer.Add(pfType,0,wx.ALIGN_CENTER_VERTICAL)
2654        if 'Axial' not in textureData['PlotType']:
2655            PTSizer.Add(wx.StaticText(Texture,-1,' Projection type: '),0,wx.ALIGN_CENTER_VERTICAL)
2656            projSel = wx.ComboBox(Texture,-1,value=G2frame.Projection,choices=['equal area','stereographic','3D display'],
2657                style=wx.CB_READONLY|wx.CB_DROPDOWN)
2658            projSel.Bind(wx.EVT_COMBOBOX,OnProjSel)
2659            PTSizer.Add(projSel,0,wx.ALIGN_CENTER_VERTICAL)
2660        if textureData['PlotType'] in ['Pole figure','Axial pole distribution']:
2661            PTSizer.Add(wx.StaticText(Texture,-1,' Pole figure HKL: '),0,wx.ALIGN_CENTER_VERTICAL)
2662            PH = textureData['PFhkl']
2663            pfVal = wx.TextCtrl(Texture,-1,'%d %d %d'%(PH[0],PH[1],PH[2]),style=wx.TE_PROCESS_ENTER)
2664        else:
2665            PTSizer.Add(wx.StaticText(Texture,-1,' Inverse pole figure XYZ: '),0,wx.ALIGN_CENTER_VERTICAL)
2666            PX = textureData['PFxyz']
2667            pfVal = wx.TextCtrl(Texture,-1,'%3.1f %3.1f %3.1f'%(PX[0],PX[1],PX[2]),style=wx.TE_PROCESS_ENTER)
2668        pfVal.Bind(wx.EVT_TEXT_ENTER,OnPFValue)
2669        pfVal.Bind(wx.EVT_KILL_FOCUS,OnPFValue)
2670        PTSizer.Add(pfVal,0,wx.ALIGN_CENTER_VERTICAL)
2671        if 'Axial' not in textureData['PlotType']:
2672            PTSizer.Add(wx.StaticText(Texture,-1,' Color scheme'),0,wx.ALIGN_CENTER_VERTICAL)
2673            choice = [m for m in mpl.cm.datad.keys() if not m.endswith("_r")]
2674            choice.sort()
2675            colorSel = wx.ComboBox(Texture,-1,value=G2frame.ContourColor,choices=choice,
2676                style=wx.CB_READONLY|wx.CB_DROPDOWN)
2677            colorSel.Bind(wx.EVT_COMBOBOX,OnColorSel)
2678            PTSizer.Add(colorSel,0,wx.ALIGN_CENTER_VERTICAL)       
2679        mainSizer.Add(PTSizer,0,wx.ALIGN_CENTER_VERTICAL)
2680        mainSizer.Add((0,5),0)
2681        if textureData['SHShow']:
2682            mainSizer.Add(wx.StaticText(Texture,-1,'Spherical harmonic coefficients: '),0,wx.ALIGN_CENTER_VERTICAL)
2683            mainSizer.Add((0,5),0)
2684            ODFSizer = wx.FlexGridSizer(2,8,2,2)
2685            ODFIndx = {}
2686            ODFkeys = textureData['SH Coeff'][1].keys()
2687            ODFkeys.sort()
2688            for item in ODFkeys:
2689                ODFSizer.Add(wx.StaticText(Texture,-1,item),0,wx.ALIGN_CENTER_VERTICAL)
2690                ODFval = wx.TextCtrl(Texture,wx.ID_ANY,'%8.3f'%(textureData['SH Coeff'][1][item]),style=wx.TE_PROCESS_ENTER)
2691                ODFIndx[ODFval.GetId()] = item
2692                ODFval.Bind(wx.EVT_TEXT_ENTER,OnODFValue)
2693                ODFval.Bind(wx.EVT_KILL_FOCUS,OnODFValue)
2694                ODFSizer.Add(ODFval,0,wx.ALIGN_CENTER_VERTICAL)
2695            mainSizer.Add(ODFSizer,0,wx.ALIGN_CENTER_VERTICAL)
2696            mainSizer.Add((0,5),0)
2697        mainSizer.Add((0,5),0)
2698        mainSizer.Add(wx.StaticText(Texture,-1,'Sample orientation angles: '),0,wx.ALIGN_CENTER_VERTICAL)
2699        mainSizer.Add((0,5),0)
2700        angSizer = wx.BoxSizer(wx.HORIZONTAL)
2701        angIndx = {}
2702        valIndx = {}
2703        for item in ['Sample omega','Sample chi','Sample phi']:
2704            angRef = wx.CheckBox(Texture,-1,label=item+': ')
2705            angRef.SetValue(textureData[item][0])
2706            angIndx[angRef.GetId()] = item
2707            angRef.Bind(wx.EVT_CHECKBOX, OnAngRef)
2708            angSizer.Add(angRef,0,wx.ALIGN_CENTER_VERTICAL)
2709            angVal = wx.TextCtrl(Texture,wx.ID_ANY,'%8.2f'%(textureData[item][1]),style=wx.TE_PROCESS_ENTER)
2710            valIndx[angVal.GetId()] = item
2711            angVal.Bind(wx.EVT_TEXT_ENTER,OnAngValue)
2712            angVal.Bind(wx.EVT_KILL_FOCUS,OnAngValue)
2713            angSizer.Add(angVal,0,wx.ALIGN_CENTER_VERTICAL)
2714            angSizer.Add((5,0),0)
2715        mainSizer.Add(angSizer,0,wx.ALIGN_CENTER_VERTICAL)
2716        Texture.SetSizer(mainSizer,True)
2717        mainSizer.Fit(G2frame.dataFrame)
2718        Size = mainSizer.GetMinSize()
2719        Size[0] += 40
2720        Size[1] = max(Size[1],250) + 20
2721        Texture.SetSize(Size)
2722        Texture.SetScrollbars(10,10,Size[0]/10-4,Size[1]/10-1)
2723        Size[1] = min(Size[1],450)
2724        G2frame.dataFrame.setSizePosLeft(Size)
2725
2726################################################################################
2727##### DData routines
2728################################################################################
2729       
2730    def UpdateDData():
2731        UseList = data['Histograms']
2732        if UseList:
2733            G2frame.dataFrame.DataMenu.Enable(G2gd.wxID_DATADELETE,True)
2734            G2frame.Refine.Enable(True)
2735        else:
2736            G2frame.dataFrame.DataMenu.Enable(G2gd.wxID_DATADELETE,False)
2737            G2frame.Refine.Enable(False)           
2738        generalData = data['General']       
2739        SGData = generalData['SGData']
2740        keyList = UseList.keys()
2741        keyList.sort()
2742        PWDR = any(['PWDR' in item for item in keyList])
2743        Indx = {}
2744       
2745        def PlotSizer():
2746
2747            def OnPlotSel(event):
2748                Obj = event.GetEventObject()
2749                generalData['Data plot type'] = Obj.GetStringSelection()
2750                wx.CallAfter(UpdateDData)
2751                G2plt.PlotSizeStrainPO(G2frame,data)
2752               
2753            def OnPOhkl(event):
2754                Obj = event.GetEventObject()
2755                Saxis = Obj.GetValue().split()
2756                try:
2757                    hkl = [int(Saxis[i]) for i in range(3)]
2758                except (ValueError,IndexError):
2759                    hkl = generalData['POhkl']
2760                if not np.any(np.array(hkl)):
2761                    hkl = generalData['POhkl']
2762                generalData['POhkl'] = hkl
2763                h,k,l = hkl
2764                Obj.SetValue('%3d %3d %3d'%(h,k,l)) 
2765                G2plt.PlotSizeStrainPO(G2frame,data)
2766           
2767            plotSizer = wx.BoxSizer(wx.VERTICAL)
2768            choice = ['None','Mustrain','Size','Preferred orientation']
2769            plotSel = wx.RadioBox(DData,-1,'Select plot type:',choices=choice,
2770                majorDimension=2,style=wx.RA_SPECIFY_COLS)
2771            plotSel.SetStringSelection(generalData['Data plot type'])
2772            plotSel.Bind(wx.EVT_RADIOBOX,OnPlotSel)   
2773            plotSizer.Add(plotSel)
2774            if generalData['Data plot type'] == 'Preferred orientation':
2775                POhklSizer = wx.BoxSizer(wx.HORIZONTAL)
2776                POhklSizer.Add(wx.StaticText(DData,-1,' Plot preferred orientation for H K L: '),0,wx.ALIGN_CENTER_VERTICAL)
2777                h,k,l = generalData['POhkl']
2778                poAxis = wx.TextCtrl(DData,-1,'%3d %3d %3d'%(h,k,l),style=wx.TE_PROCESS_ENTER)
2779                poAxis.Bind(wx.EVT_TEXT_ENTER,OnPOhkl)
2780                poAxis.Bind(wx.EVT_KILL_FOCUS,OnPOhkl)
2781                POhklSizer.Add(poAxis,0,wx.ALIGN_CENTER_VERTICAL)
2782                plotSizer.Add(POhklSizer)           
2783            return plotSizer
2784           
2785        def ScaleSizer():
2786           
2787            def OnScaleRef(event):
2788                Obj = event.GetEventObject()
2789                UseList[Indx[Obj.GetId()]]['Scale'][1] = Obj.GetValue()
2790               
2791            def OnScaleVal(event):
2792                Obj = event.GetEventObject()
2793                try:
2794                    scale = float(Obj.GetValue())
2795                    if scale > 0:
2796                        UseList[Indx[Obj.GetId()]]['Scale'][0] = scale
2797                except ValueError:
2798                    pass
2799                Obj.SetValue("%.4f"%(UseList[Indx[Obj.GetId()]]['Scale'][0]))          #reset in case of error
2800                           
2801            scaleSizer = wx.BoxSizer(wx.HORIZONTAL)
2802            if 'PWDR' in item:
2803                scaleRef = wx.CheckBox(DData,-1,label=' Phase fraction: ')
2804            elif 'HKLF' in item:
2805                scaleRef = wx.CheckBox(DData,-1,label=' Scale factor: ')               
2806            scaleRef.SetValue(UseList[item]['Scale'][1])
2807            Indx[scaleRef.GetId()] = item
2808            scaleRef.Bind(wx.EVT_CHECKBOX, OnScaleRef)
2809            scaleSizer.Add(scaleRef,0,wx.ALIGN_CENTER_VERTICAL)
2810            scaleVal = wx.TextCtrl(DData,wx.ID_ANY,
2811                '%.4f'%(UseList[item]['Scale'][0]),style=wx.TE_PROCESS_ENTER)
2812            Indx[scaleVal.GetId()] = item
2813            scaleVal.Bind(wx.EVT_TEXT_ENTER,OnScaleVal)
2814            scaleVal.Bind(wx.EVT_KILL_FOCUS,OnScaleVal)
2815            scaleSizer.Add(scaleVal,0,wx.ALIGN_CENTER_VERTICAL)
2816            return scaleSizer
2817           
2818        def OnUseData(event):
2819            Obj = event.GetEventObject()
2820            hist = Indx[Obj.GetId()]
2821            UseList[hist]['Use'] = Obj.GetValue()
2822           
2823        def OnShowData(event):
2824            Obj = event.GetEventObject()
2825            hist = Indx[Obj.GetId()]
2826            UseList[hist]['Show'] = Obj.GetValue()
2827            wx.CallAfter(UpdateDData)
2828            G2plt.PlotSizeStrainPO(G2frame,data)
2829           
2830        def OnCopyData(event):
2831            #how about HKLF data? This is only for PWDR data
2832            Obj = event.GetEventObject()
2833            hist = Indx[Obj.GetId()]
2834            sourceDict = UseList[hist]
2835            copyNames = ['Scale','Pref.Ori.','Size','Mustrain','HStrain','Extinction']
2836            copyDict = {}
2837            for name in copyNames: 
2838                copyDict[name] = copy.deepcopy(sourceDict[name])        #force copy
2839            keyList = ['All',]+UseList.keys()
2840            if UseList:
2841                copyList = []
2842                dlg = wx.MultiChoiceDialog(G2frame, 
2843                    'Copy parameters to which histograms?', 'Copy parameters', 
2844                    keyList, wx.CHOICEDLG_STYLE)
2845                try:
2846                    if dlg.ShowModal() == wx.ID_OK:
2847                        result = dlg.GetSelections()
2848                        for i in result: 
2849                            copyList.append(keyList[i])
2850                        if 'All' in copyList: 
2851                            copyList = keyList[1:]
2852                        for item in copyList:
2853                            UseList[item].update(copy.deepcopy(copyDict))
2854                        wx.CallAfter(UpdateDData)
2855                finally:
2856                    dlg.Destroy()
2857                   
2858        def OnCopyFlags(event):
2859            Obj = event.GetEventObject()
2860            hist = Indx[Obj.GetId()]
2861            sourceDict = UseList[hist]
2862            copyDict = {}
2863            copyNames = ['Scale','Pref.Ori.','Size','Mustrain','HStrain','Extinction']
2864            for name in copyNames:
2865                if name in ['Scale','Extinction','HStrain']:
2866                    copyDict[name] = sourceDict[name][1]
2867                elif name in ['Size','Mustrain']:
2868                    copyDict[name] = [sourceDict[name][0],sourceDict[name][2],sourceDict[name][4]]
2869                elif name == 'Pref.Ori.':
2870                    copyDict[name] = [sourceDict[name][0],sourceDict[name][2]]
2871                    if sourceDict[name][0] == 'SH':
2872                        SHterms = sourceDict[name][5]
2873                        SHflags = {}
2874                        for item in SHterms:
2875                            SHflags[item] = SHterms[item][1]
2876                        copyDict[name].append(SHflags)                       
2877            keyList = ['All',]+UseList.keys()
2878            if UseList:
2879                copyList = []
2880                dlg = wx.MultiChoiceDialog(G2frame, 
2881                    'Copy parameters to which histograms?', 'Copy parameters', 
2882                    keyList, wx.CHOICEDLG_STYLE)
2883                try:
2884                    if dlg.ShowModal() == wx.ID_OK:
2885                        result = dlg.GetSelections()
2886                        for i in result: 
2887                            copyList.append(keyList[i])
2888                        if 'All' in copyList: 
2889                            copyList = keyList[1:]
2890                        for item in copyList:
2891                            UseList[item]                           
2892                            for name in copyNames:
2893                                if name in ['Scale','Extinction','HStrain']:
2894                                    UseList[item][name][1] = copy.copy(copyDict[name])
2895                                elif name in ['Size','Mustrain']:
2896                                    UseList[item][name][0] = copy.copy(copyDict[name][0])
2897                                    UseList[item][name][2] = copy.copy(copyDict[name][1])
2898                                    UseList[item][name][4] = copy.copy(copyDict[name][2])
2899                                elif name == 'Pref.Ori.':
2900                                    UseList[item][name][0] = copy.copy(copyDict[name][0])
2901                                    UseList[item][name][2] = copy.copy(copyDict[name][1])
2902                                    if sourceDict[name][0] == 'SH':
2903                                        SHflags = copy.copy(copyDict[name][2])
2904                                        SHterms = copy.copy(sourceDict[name][5])
2905                                        for item in SHflags:
2906                                            SHterms[item][1] = copy.copy(SHflags[item])                                             
2907                        wx.CallAfter(UpdateDData)
2908                finally:
2909                    dlg.Destroy()
2910           
2911           
2912        def OnLGmixRef(event):
2913            Obj = event.GetEventObject()
2914            hist,name = Indx[Obj.GetId()]
2915            UseList[hist][name][2][2] = Obj.GetValue()
2916           
2917        def OnLGmixVal(event):
2918            Obj = event.GetEventObject()
2919            hist,name = Indx[Obj.GetId()]
2920            try:
2921                value = float(Obj.GetValue())
2922                if 0.1 <= value <= 1:
2923                    UseList[hist][name][1][2] = value
2924                else:
2925                    raise ValueError
2926            except ValueError:
2927                pass
2928            Obj.SetValue("%.4f"%(UseList[hist][name][1][2]))          #reset in case of error
2929
2930        def OnSizeType(event):
2931            Obj = event.GetEventObject()
2932            hist = Indx[Obj.GetId()]
2933            UseList[hist]['Size'][0] = Obj.GetValue()
2934            G2plt.PlotSizeStrainPO(G2frame,data)
2935            wx.CallAfter(UpdateDData)
2936           
2937        def OnSizeRef(event):
2938            Obj = event.GetEventObject()
2939            hist,pid = Indx[Obj.GetId()]
2940            if UseList[hist]['Size'][0] == 'ellipsoidal':
2941                UseList[hist]['Size'][5][pid] = Obj.GetValue()               
2942            else:
2943                UseList[hist]['Size'][2][pid] = Obj.GetValue()
2944           
2945        def OnSizeVal(event):
2946            Obj = event.GetEventObject()
2947            hist,pid = Indx[Obj.GetId()]
2948            if UseList[hist]['Size'][0] == 'ellipsoidal':
2949                try:
2950                    size = float(Obj.GetValue())
2951                    if pid < 3 and size <= 0.001:            #10A lower limit!
2952                        raise ValueError
2953                    UseList[hist]['Size'][4][pid] = size                   
2954                except ValueError:
2955                    pass
2956                Obj.SetValue("%.3f"%(UseList[hist]['Size'][4][pid]))          #reset in case of error
2957            else:
2958                try:
2959                    size = float(Obj.GetValue())
2960                    if size <= 0.001:            #10A lower limit!
2961                        raise ValueError
2962                    UseList[hist]['Size'][1][pid] = size
2963                except ValueError:
2964                    pass
2965                Obj.SetValue("%.3f"%(UseList[hist]['Size'][1][pid]))          #reset in case of error
2966            G2plt.PlotSizeStrainPO(G2frame,data)
2967           
2968        def OnSizeAxis(event):           
2969            Obj = event.GetEventObject()
2970            hist = Indx[Obj.GetId()]
2971            Saxis = Obj.GetValue().split()
2972            try:
2973                hkl = [int(Saxis[i]) for i in range(3)]
2974            except (ValueError,IndexError):
2975                hkl = UseList[hist]['Size'][3]
2976            if not np.any(np.array(hkl)):
2977                hkl = UseList[hist]['Size'][3]
2978            UseList[hist]['Size'][3] = hkl
2979            h,k,l = hkl
2980            Obj.SetValue('%3d %3d %3d'%(h,k,l)) 
2981                       
2982        def OnStrainType(event):
2983            Obj = event.GetEventObject()
2984            hist = Indx[Obj.GetId()]
2985            UseList[hist]['Mustrain'][0] = Obj.GetValue()
2986            wx.CallAfter(UpdateDData)
2987            G2plt.PlotSizeStrainPO(G2frame,data)
2988           
2989        def OnStrainRef(event):
2990            Obj = event.GetEventObject()
2991            hist,pid = Indx[Obj.GetId()]
2992            if UseList[hist]['Mustrain'][0] == 'generalized':
2993                UseList[hist]['Mustrain'][5][pid] = Obj.GetValue()
2994            else:
2995                UseList[hist]['Mustrain'][2][pid] = Obj.GetValue()
2996           
2997        def OnStrainVal(event):
2998            Snames = G2spc.MustrainNames(SGData)
2999            Obj = event.GetEventObject()
3000            hist,pid = Indx[Obj.GetId()]
3001            try:
3002                strain = float(Obj.GetValue())
3003                if UseList[hist]['Mustrain'][0] == 'generalized':
3004                    if '4' in Snames[pid] and strain < 0:
3005                        raise ValueError
3006                    UseList[hist]['Mustrain'][4][pid] = strain
3007                else:
3008                    if strain <= 0:
3009                        raise ValueError
3010                    UseList[hist]['Mustrain'][1][pid] = strain
3011            except ValueError:
3012                pass
3013            if UseList[hist]['Mustrain'][0] == 'generalized':
3014                Obj.SetValue("%.3f"%(UseList[hist]['Mustrain'][4][pid]))          #reset in case of error
3015            else:
3016                Obj.SetValue("%.1f"%(UseList[hist]['Mustrain'][1][pid]))          #reset in case of error
3017            G2plt.PlotSizeStrainPO(G2frame,data)
3018           
3019        def OnStrainAxis(event):
3020            Obj = event.GetEventObject()
3021            hist = Indx[Obj.GetId()]
3022            Saxis = Obj.GetValue().split()
3023            try:
3024                hkl = [int(Saxis[i]) for i in range(3)]
3025            except (ValueError,IndexError):
3026                hkl = UseList[hist]['Mustrain'][3]
3027            if not np.any(np.array(hkl)):
3028                hkl = UseList[hist]['Mustrain'][3]
3029            UseList[hist]['Mustrain'][3] = hkl
3030            h,k,l = hkl
3031            Obj.SetValue('%3d %3d %3d'%(h,k,l)) 
3032            G2plt.PlotSizeStrainPO(G2frame,data)
3033           
3034        def OnHstrainRef(event):
3035            Obj = event.GetEventObject()
3036            hist,pid = Indx[Obj.GetId()]
3037            UseList[hist]['HStrain'][1][pid] = Obj.GetValue()
3038           
3039        def OnHstrainVal(event):
3040            Snames = G2spc.HStrainNames(SGData)
3041            Obj = event.GetEventObject()
3042            hist,pid = Indx[Obj.GetId()]
3043            try:
3044                strain = float(Obj.GetValue())
3045                UseList[hist]['HStrain'][0][pid] = strain
3046            except ValueError:
3047                pass
3048            Obj.SetValue("%.5f"%(UseList[hist]['HStrain'][0][pid]))          #reset in case of error
3049
3050        def OnPOVal(event):
3051            Obj = event.GetEventObject()
3052            hist = Indx[Obj.GetId()]
3053            try:
3054                mdVal = float(Obj.GetValue())
3055                if mdVal > 0:
3056                    UseList[hist]['Pref.Ori.'][1] = mdVal
3057            except ValueError:
3058                pass
3059            Obj.SetValue("%.3f"%(UseList[hist]['Pref.Ori.'][1]))          #reset in case of error
3060           
3061        def OnPOAxis(event):
3062            Obj = event.GetEventObject()
3063            hist = Indx[Obj.GetId()]
3064            Saxis = Obj.GetValue().split()
3065            try:
3066                hkl = [int(Saxis[i]) for i in range(3)]
3067            except (ValueError,IndexError):
3068                hkl = UseList[hist]['Pref.Ori.'][3]
3069            if not np.any(np.array(hkl)):
3070                hkl = UseList[hist]['Pref.Ori.'][3]
3071            UseList[hist]['Pref.Ori.'][3] = hkl
3072            h,k,l = hkl
3073            Obj.SetValue('%3d %3d %3d'%(h,k,l)) 
3074           
3075        def OnPOOrder(event):
3076            Obj = event.GetEventObject()
3077            hist = Indx[Obj.GetId()]
3078            Order = int(Obj.GetValue())
3079            UseList[hist]['Pref.Ori.'][4] = Order
3080            UseList[hist]['Pref.Ori.'][5] = SetPOCoef(Order,hist)
3081            wx.CallAfter(UpdateDData)
3082
3083        def OnPOType(event):
3084            Obj = event.GetEventObject()
3085            hist = Indx[Obj.GetId()]
3086            if 'March' in Obj.GetValue():
3087                UseList[hist]['Pref.Ori.'][0] = 'MD'
3088            else:
3089                UseList[hist]['Pref.Ori.'][0] = 'SH'
3090            wx.CallAfter(UpdateDData)           
3091   
3092        def OnPORef(event):
3093            Obj = event.GetEventObject()
3094            hist = Indx[Obj.GetId()]
3095            UseList[hist]['Pref.Ori.'][2] = Obj.GetValue()
3096               
3097        def SetPOCoef(Order,hist):
3098            cofNames = G2lat.GenSHCoeff(SGData['SGLaue'],'0',Order,False)     #cylindrical & no M
3099            newPOCoef = dict(zip(cofNames,np.zeros(len(cofNames))))
3100            POCoeff = UseList[hist]['Pref.Ori.'][5]
3101            for cofName in POCoeff:
3102                if cofName in  cofNames:
3103                    newPOCoef[cofName] = POCoeff[cofName]
3104            return newPOCoef
3105       
3106        def OnExtRef(event):
3107            Obj = event.GetEventObject()
3108            UseList[Indx[Obj.GetId()]]['Extinction'][1] = Obj.GetValue()
3109           
3110        def OnExtVal(event):
3111            Obj = event.GetEventObject()
3112            try:
3113                ext = float(Obj.GetValue())
3114                if ext >= 0:
3115                    UseList[Indx[Obj.GetId()]]['Extinction'][0] = ext
3116            except ValueError:
3117                pass
3118            Obj.SetValue("%.2f"%(UseList[Indx[Obj.GetId()]]['Extinction'][0]))
3119           
3120        def OnTbarVal(event):
3121            Obj = event.GetEventObject()
3122            try:
3123                tbar = float(Obj.GetValue())
3124                if tbar >= 0:
3125                    UseList[Indx[Obj.GetId()]]['Extinction'][2]['Tbar'] = tbar
3126            except ValueError:
3127                pass
3128            Obj.SetValue("%.2f"%(UseList[Indx[Obj.GetId()]]['Extinction'][2]['Tbar']))
3129           
3130        def OnEval(event):
3131            Obj = event.GetEventObject()
3132            item = Indx[Obj.GetId()]
3133            try:
3134                val = float(Obj.GetValue())
3135                if val >= 0:
3136                    UseList[item[0]]['Extinction'][2][item[1]][0] = val
3137            except ValueError:
3138                pass
3139            Obj.SetValue("%9.3g"%(UseList[item[0]]['Extinction'][2][item[1]][0]))
3140           
3141        def OnEref(event):
3142            Obj = event.GetEventObject()
3143            item = Indx[Obj.GetId()]
3144            UseList[item[0]]['Extinction'][2][item[1]][1] = Obj.GetValue()
3145
3146        def OnSCExtType(event):
3147            Obj = event.GetEventObject()
3148            item = Indx[Obj.GetId()]
3149            UseList[item[0]]['Extinction'][item[1]] = Obj.GetValue()
3150            wx.CallAfter(UpdateDData)
3151               
3152        def checkAxis(axis):
3153            if not np.any(np.array(axis)):
3154                return False
3155            return axis
3156           
3157        def TopSizer(name,choices,parm,OnType):
3158            topSizer = wx.BoxSizer(wx.HORIZONTAL)
3159            topSizer.Add(wx.StaticText(DData,-1,name),0,wx.ALIGN_CENTER_VERTICAL)
3160            sizeType = wx.ComboBox(DData,wx.ID_ANY,value=UseList[item][parm][0],choices=choices,
3161                style=wx.CB_READONLY|wx.CB_DROPDOWN)
3162            sizeType.Bind(wx.EVT_COMBOBOX, OnType)
3163            Indx[sizeType.GetId()] = item
3164            topSizer.Add(sizeType)
3165            topSizer.Add((5,0),0)
3166            return topSizer
3167           
3168        def LGmixSizer(name,OnVal,OnRef):
3169            lgmixSizer = wx.BoxSizer(wx.HORIZONTAL)
3170            lgmixRef = wx.CheckBox(DData,-1,label='LGmix')
3171            lgmixRef.thisown = False
3172            lgmixRef.SetValue(UseList[item][name][2][2])
3173            Indx[lgmixRef.GetId()] = [item,name]
3174            lgmixRef.Bind(wx.EVT_CHECKBOX, OnRef)
3175            lgmixSizer.Add(lgmixRef,0,wx.ALIGN_CENTER_VERTICAL)
3176            lgmixVal = wx.TextCtrl(DData,wx.ID_ANY,
3177                '%.4f'%(UseList[item][name][1][2]),style=wx.TE_PROCESS_ENTER)
3178            Indx[lgmixVal.GetId()] = [item,name]
3179            lgmixVal.Bind(wx.EVT_TEXT_ENTER,OnVal)
3180            lgmixVal.Bind(wx.EVT_KILL_FOCUS,OnVal)
3181            lgmixSizer.Add(lgmixVal,0,wx.ALIGN_CENTER_VERTICAL)
3182            return lgmixSizer
3183                       
3184        def IsoSizer(name,parm,fmt,OnVal,OnRef):
3185            isoSizer = wx.BoxSizer(wx.HORIZONTAL)
3186            sizeRef = wx.CheckBox(DData,-1,label=name)
3187            sizeRef.thisown = False
3188            sizeRef.SetValue(UseList[item][parm][2][0])
3189            Indx[sizeRef.GetId()] = [item,0]
3190            sizeRef.Bind(wx.EVT_CHECKBOX, OnRef)
3191            isoSizer.Add(sizeRef,0,wx.ALIGN_CENTER_VERTICAL)
3192            sizeVal = wx.TextCtrl(DData,wx.ID_ANY,
3193                fmt%(UseList[item][parm][1][0]),style=wx.TE_PROCESS_ENTER)
3194            Indx[sizeVal.GetId()] = [item,0]
3195            sizeVal.Bind(wx.EVT_TEXT_ENTER,OnVal)
3196            sizeVal.Bind(wx.EVT_KILL_FOCUS,OnVal)
3197            isoSizer.Add(sizeVal,0,wx.ALIGN_CENTER_VERTICAL)
3198            return isoSizer
3199           
3200        def UniSizer(parm,OnAxis):
3201            uniSizer = wx.BoxSizer(wx.HORIZONTAL)
3202            uniSizer.Add(wx.StaticText(DData,-1,' Unique axis, H K L: '),0,wx.ALIGN_CENTER_VERTICAL)
3203            h,k,l = UseList[item][parm][3]
3204            Axis = wx.TextCtrl(DData,-1,'%3d %3d %3d'%(h,k,l),style=wx.TE_PROCESS_ENTER)
3205            Indx[Axis.GetId()] = item
3206            Axis.Bind(wx.EVT_TEXT_ENTER,OnAxis)
3207            Axis.Bind(wx.EVT_KILL_FOCUS,OnAxis)
3208            uniSizer.Add(Axis,0,wx.ALIGN_CENTER_VERTICAL)
3209            return uniSizer
3210           
3211        def UniDataSizer(parmName,parm,fmt,OnVal,OnRef):
3212            dataSizer = wx.BoxSizer(wx.HORIZONTAL)
3213            parms = zip([' Equatorial '+parmName,' Axial '+parmName],
3214                UseList[item][parm][1],UseList[item][parm][2],range(2))
3215            for Pa,val,ref,id in parms:
3216                sizeRef = wx.CheckBox(DData,-1,label=Pa)
3217                sizeRef.thisown = False
3218                sizeRef.SetValue(ref)
3219                Indx[sizeRef.GetId()] = [item,id]
3220                sizeRef.Bind(wx.EVT_CHECKBOX, OnRef)
3221                dataSizer.Add(sizeRef,0,wx.ALIGN_CENTER_VERTICAL)
3222                sizeVal = wx.TextCtrl(DData,wx.ID_ANY,fmt%(val),style=wx.TE_PROCESS_ENTER)
3223                Indx[sizeVal.GetId()] = [item,id]
3224                sizeVal.Bind(wx.EVT_TEXT_ENTER,OnVal)
3225                sizeVal.Bind(wx.EVT_KILL_FOCUS,OnVal)
3226                dataSizer.Add(sizeVal,0,wx.ALIGN_CENTER_VERTICAL)
3227                dataSizer.Add((5,0),0)
3228            return dataSizer
3229           
3230        def EllSizeDataSizer():
3231            parms = zip(['S11','S22','S33','S12','S13','S23'],UseList[item]['Size'][4],
3232                UseList[item]['Size'][5],range(6))
3233            dataSizer = wx.FlexGridSizer(1,6,5,5)
3234            for Pa,val,ref,id in parms:
3235                sizeRef = wx.CheckBox(DData,-1,label=Pa)
3236                sizeRef.thisown = False
3237                sizeRef.SetValue(ref)
3238                Indx[sizeRef.GetId()] = [item,id]
3239                sizeRef.Bind(wx.EVT_CHECKBOX, OnSizeRef)
3240                dataSizer.Add(sizeRef,0,wx.ALIGN_CENTER_VERTICAL)
3241                sizeVal = wx.TextCtrl(DData,wx.ID_ANY,'%.3f'%(val),style=wx.TE_PROCESS_ENTER)
3242                Indx[sizeVal.GetId()] = [item,id]
3243                sizeVal.Bind(wx.EVT_TEXT_ENTER,OnSizeVal)
3244                sizeVal.Bind(wx.EVT_KILL_FOCUS,OnSizeVal)
3245                dataSizer.Add(sizeVal,0,wx.ALIGN_CENTER_VERTICAL)
3246            return dataSizer
3247           
3248        def GenStrainDataSizer():
3249            Snames = G2spc.MustrainNames(SGData)
3250            numb = len(Snames)
3251            if len(UseList[item]['Mustrain'][4]) < numb:
3252                UseList[item]['Mustrain'][4] = numb*[0.0,]
3253                UseList[item]['Mustrain'][5] = numb*[False,]
3254            parms = zip(Snames,UseList[item]['Mustrain'][4],UseList[item]['Mustrain'][5],range(numb))
3255            dataSizer = wx.FlexGridSizer(1,6,5,5)
3256            for Pa,val,ref,id in parms:
3257                strainRef = wx.CheckBox(DData,-1,label=Pa)
3258                strainRef.thisown = False
3259                strainRef.SetValue(ref)
3260                Indx[strainRef.GetId()] = [item,id]
3261                strainRef.Bind(wx.EVT_CHECKBOX, OnStrainRef)
3262                dataSizer.Add(strainRef,0,wx.ALIGN_CENTER_VERTICAL)
3263                strainVal = wx.TextCtrl(DData,wx.ID_ANY,'%.5f'%(val),style=wx.TE_PROCESS_ENTER)
3264                Indx[strainVal.GetId()] = [item,id]
3265                strainVal.Bind(wx.EVT_TEXT_ENTER,OnStrainVal)
3266                strainVal.Bind(wx.EVT_KILL_FOCUS,OnStrainVal)
3267                dataSizer.Add(strainVal,0,wx.ALIGN_CENTER_VERTICAL)
3268            return dataSizer
3269           
3270        def HstrainSizer():
3271            hstrainSizer = wx.FlexGridSizer(1,6,5,5)
3272            Hsnames = G2spc.HStrainNames(SGData)
3273            parms = zip(Hsnames,UseList[item]['HStrain'][0],UseList[item]['HStrain'][1],range(len(Hsnames)))
3274            for Pa,val,ref,id in parms:
3275                hstrainRef = wx.CheckBox(DData,-1,label=Pa)
3276                hstrainRef.thisown = False
3277                hstrainRef.SetValue(ref)
3278                Indx[hstrainRef.GetId()] = [item,id]
3279                hstrainRef.Bind(wx.EVT_CHECKBOX, OnHstrainRef)
3280                hstrainSizer.Add(hstrainRef,0,wx.ALIGN_CENTER_VERTICAL)
3281                hstrainVal = wx.TextCtrl(DData,wx.ID_ANY,'%.5f'%(val),style=wx.TE_PROCESS_ENTER)
3282                Indx[hstrainVal.GetId()] = [item,id]
3283                hstrainVal.Bind(wx.EVT_TEXT_ENTER,OnHstrainVal)
3284                hstrainVal.Bind(wx.EVT_KILL_FOCUS,OnHstrainVal)
3285                hstrainSizer.Add(hstrainVal,0,wx.ALIGN_CENTER_VERTICAL)
3286            return hstrainSizer
3287           
3288        def PoTopSizer(POData):
3289            poSizer = wx.FlexGridSizer(1,6,5,5)
3290            choice = ['March-Dollase','Spherical harmonics']
3291            POtype = choice[['MD','SH'].index(POData[0])]
3292            poSizer.Add(wx.StaticText(DData,-1,' Preferred orientation model '),0,wx.ALIGN_CENTER_VERTICAL)
3293            POType = wx.ComboBox(DData,wx.ID_ANY,value=POtype,choices=choice,
3294                style=wx.CB_READONLY|wx.CB_DROPDOWN)
3295            Indx[POType.GetId()] = item
3296            POType.Bind(wx.EVT_COMBOBOX, OnPOType)
3297            poSizer.Add(POType)
3298            if POData[0] == 'SH':
3299                poSizer.Add(wx.StaticText(DData,-1,' Harmonic order: '),0,wx.ALIGN_CENTER_VERTICAL)
3300                poOrder = wx.ComboBox(DData,wx.ID_ANY,value=str(POData[4]),choices=[str(2*i) for i in range(18)],
3301                    style=wx.CB_READONLY|wx.CB_DROPDOWN)
3302                Indx[poOrder.GetId()] = item
3303                poOrder.Bind(wx.EVT_COMBOBOX,OnPOOrder)
3304                poSizer.Add(poOrder,0,wx.ALIGN_CENTER_VERTICAL)
3305                poRef = wx.CheckBox(DData,-1,label=' Refine? ')
3306                poRef.SetValue(POData[2])
3307                Indx[poRef.GetId()] = item
3308                poRef.Bind(wx.EVT_CHECKBOX,OnPORef)
3309                poSizer.Add(poRef,0,wx.ALIGN_CENTER_VERTICAL)
3310            return poSizer
3311           
3312        def MDDataSizer(POData):
3313            poSizer = wx.BoxSizer(wx.HORIZONTAL)
3314            poRef = wx.CheckBox(DData,-1,label=' March-Dollase ratio: ')
3315            poRef.SetValue(POData[2])
3316            Indx[poRef.GetId()] = item
3317            poRef.Bind(wx.EVT_CHECKBOX,OnPORef)
3318            poSizer.Add(poRef,0,wx.ALIGN_CENTER_VERTICAL)
3319            poVal = wx.TextCtrl(DData,wx.ID_ANY,
3320                '%.3f'%(POData[1]),style=wx.TE_PROCESS_ENTER)
3321            Indx[poVal.GetId()] = item
3322            poVal.Bind(wx.EVT_TEXT_ENTER,OnPOVal)
3323            poVal.Bind(wx.EVT_KILL_FOCUS,OnPOVal)
3324            poSizer.Add(poVal,0,wx.ALIGN_CENTER_VERTICAL)
3325            poSizer.Add(wx.StaticText(DData,-1,' Unique axis, H K L: '),0,wx.ALIGN_CENTER_VERTICAL)
3326            h,k,l =POData[3]
3327            poAxis = wx.TextCtrl(DData,-1,'%3d %3d %3d'%(h,k,l),style=wx.TE_PROCESS_ENTER)
3328            Indx[poAxis.GetId()] = item
3329            poAxis.Bind(wx.EVT_TEXT_ENTER,OnPOAxis)
3330            poAxis.Bind(wx.EVT_KILL_FOCUS,OnPOAxis)
3331            poSizer.Add(poAxis,0,wx.ALIGN_CENTER_VERTICAL)
3332            return poSizer
3333           
3334        def SHDataSizer(POData):
3335            textJ = G2lat.textureIndex(POData[5])
3336            mainSizer.Add(wx.StaticText(DData,-1,' Spherical harmonic coefficients: '+'Texture index: %.3f'%(textJ)),0,wx.ALIGN_CENTER_VERTICAL)
3337            mainSizer.Add((0,5),0)
3338            ODFSizer = wx.FlexGridSizer(2,8,2,2)
3339            ODFIndx = {}
3340            ODFkeys = POData[5].keys()
3341            ODFkeys.sort()
3342            for odf in ODFkeys:
3343                ODFSizer.Add(wx.StaticText(DData,-1,odf),0,wx.ALIGN_CENTER_VERTICAL)
3344                ODFval = wx.TextCtrl(DData,wx.ID_ANY,'%8.3f'%(POData[5][odf]),style=wx.TE_PROCESS_ENTER)
3345                ODFIndx[ODFval.GetId()] = odf
3346#                ODFval.Bind(wx.EVT_TEXT_ENTER,OnODFValue)
3347#                ODFval.Bind(wx.EVT_KILL_FOCUS,OnODFValue)
3348                ODFSizer.Add(ODFval,0,wx.ALIGN_CENTER_VERTICAL)
3349            return ODFSizer
3350           
3351        def ExtSizer():           
3352            extSizer = wx.BoxSizer(wx.HORIZONTAL)
3353            extRef = wx.CheckBox(DData,-1,label=' Extinction: ')
3354            extRef.SetValue(UseList[item]['Extinction'][1])
3355            Indx[extRef.GetId()] = item
3356            extRef.Bind(wx.EVT_CHECKBOX, OnExtRef)
3357            extSizer.Add(extRef,0,wx.ALIGN_CENTER_VERTICAL)
3358            extVal = wx.TextCtrl(DData,wx.ID_ANY,
3359                '%.2f'%(UseList[item]['Extinction'][0]),style=wx.TE_PROCESS_ENTER)
3360            Indx[extVal.GetId()] = item
3361            extVal.Bind(wx.EVT_TEXT_ENTER,OnExtVal)
3362            extVal.Bind(wx.EVT_KILL_FOCUS,OnExtVal)
3363            extSizer.Add(extVal,0,wx.ALIGN_CENTER_VERTICAL)
3364            return extSizer
3365       
3366        def SCExtSizer():
3367            extSizer = wx.BoxSizer(wx.VERTICAL)
3368            typeSizer = wx.BoxSizer(wx.HORIZONTAL)           
3369            typeSizer.Add(wx.StaticText(DData,-1,' Extinction type: '),0,wx.ALIGN_CENTER_VERTICAL)
3370            Choices = ['Primary','Secondary Type I','Secondary Type II','Secondary Type I & II']
3371            typeTxt = wx.ComboBox(DData,-1,choices=Choices,value=UseList[item]['Extinction'][1],
3372                style=wx.CB_READONLY|wx.CB_DROPDOWN)
3373            Indx[typeTxt.GetId()] = [item,1]
3374            typeTxt.Bind(wx.EVT_COMBOBOX,OnSCExtType)
3375            typeSizer.Add(typeTxt)
3376            typeSizer.Add(wx.StaticText(DData,-1,' Approx: '),0,wx.ALIGN_CENTER_VERTICAL)
3377            Choices=['Lorentzian','Gaussian']
3378            approxTxT = wx.ComboBox(DData,-1,choices=Choices,value=UseList[item]['Extinction'][0],
3379                style=wx.CB_READONLY|wx.CB_DROPDOWN)
3380            Indx[approxTxT.GetId()] = [item,0]
3381            approxTxT.Bind(wx.EVT_COMBOBOX,OnSCExtType)
3382            typeSizer.Add(approxTxT)
3383            extSizer.Add(typeSizer,0,wx.ALIGN_CENTER_VERTICAL)
3384            extSizer.Add((0,5),)
3385            valSizer =wx.BoxSizer(wx.HORIZONTAL)
3386            valSizer.Add(wx.StaticText(DData,-1,' Tbar(mm):'),0,wx.ALIGN_CENTER_VERTICAL)
3387            tbarVal = wx.TextCtrl(DData,wx.ID_ANY,
3388                '%.3f'%(UseList[item]['Extinction'][2]['Tbar']),style=wx.TE_PROCESS_ENTER)
3389            Indx[tbarVal.GetId()] = item
3390            tbarVal.Bind(wx.EVT_TEXT_ENTER,OnTbarVal)
3391            tbarVal.Bind(wx.EVT_KILL_FOCUS,OnTbarVal)
3392            valSizer.Add(tbarVal,0,wx.ALIGN_CENTER_VERTICAL)
3393            if 'Primary' in UseList[item]['Extinction'][1]:
3394                Ekey = ['Ep',]
3395            elif 'Secondary Type II' == UseList[item]['Extinction'][1]:
3396                Ekey = ['Es',]
3397            elif 'Secondary Type I' == UseList[item]['Extinction'][1]:
3398                Ekey = ['Eg',]
3399            else:
3400                Ekey = ['Eg','Es']
3401            for ekey in Ekey:
3402                Eref = wx.CheckBox(DData,-1,label=ekey+' : ')
3403                Eref.SetValue(UseList[item]['Extinction'][2][ekey][1])
3404                Indx[Eref.GetId()] = [item,ekey]
3405                Eref.Bind(wx.EVT_CHECKBOX, OnEref)
3406                valSizer.Add(Eref,0,wx.ALIGN_CENTER_VERTICAL)
3407                Eval = wx.TextCtrl(DData,wx.ID_ANY,
3408                    '%9.3g'%(UseList[item]['Extinction'][2][ekey][0]),style=wx.TE_PROCESS_ENTER)
3409                Indx[Eval.GetId()] = [item,ekey]
3410                Eval.Bind(wx.EVT_TEXT_ENTER,OnEval)
3411                Eval.Bind(wx.EVT_KILL_FOCUS,OnEval)
3412                valSizer.Add(Eval,0,wx.ALIGN_CENTER_VERTICAL)
3413
3414            extSizer.Add(valSizer,0,wx.ALIGN_CENTER_VERTICAL)
3415            return extSizer
3416           
3417        if DData.GetSizer():
3418            DData.GetSizer().Clear(True)
3419        mainSizer = wx.BoxSizer(wx.VERTICAL)
3420        mainSizer.Add(wx.StaticText(DData,-1,'Histogram data for '+PhaseName+':'),0,wx.ALIGN_CENTER_VERTICAL)
3421        if PWDR:
3422            mainSizer.Add(PlotSizer())           
3423           
3424        for item in keyList:
3425            histData = UseList[item]
3426            if 'Use' not in UseList[item]:      #patch
3427                UseList[item]['Use'] = True
3428            showSizer = wx.BoxSizer(wx.HORIZONTAL)
3429            showData = wx.CheckBox(DData,-1,label=' Show '+item)
3430            showData.SetValue(UseList[item]['Show'])
3431            Indx[showData.GetId()] = item
3432            showData.Bind(wx.EVT_CHECKBOX, OnShowData)
3433            showSizer.Add(showData,0,wx.ALIGN_CENTER_VERTICAL)
3434            useData = wx.CheckBox(DData,-1,label='Use?')
3435            Indx[useData.GetId()] = item
3436            showSizer.Add(useData,0,wx.ALIGN_CENTER_VERTICAL)
3437            useData.Bind(wx.EVT_CHECKBOX, OnUseData)
3438            useData.SetValue(UseList[item]['Use'])
3439            copyData = wx.Button(DData,-1,label=' Copy?')
3440            Indx[copyData.GetId()] = item
3441            copyData.Bind(wx.EVT_BUTTON,OnCopyData)
3442            showSizer.Add(copyData,wx.ALIGN_CENTER_VERTICAL)
3443            copyFlags = wx.Button(DData,-1,label=' Copy flags?')
3444            Indx[copyFlags.GetId()] = item
3445            copyFlags.Bind(wx.EVT_BUTTON,OnCopyFlags)
3446            showSizer.Add(copyFlags,wx.ALIGN_CENTER_VERTICAL)
3447            mainSizer.Add((5,5),0)
3448            mainSizer.Add(showSizer,0,wx.ALIGN_CENTER_VERTICAL)
3449            mainSizer.Add((0,5),0)
3450           
3451            if UseList[item]['Show']:
3452                mainSizer.Add(ScaleSizer())
3453                mainSizer.Add((0,5),0)
3454               
3455            if item[:4] == 'PWDR' and UseList[item]['Show']:
3456                if UseList[item]['Size'][0] == 'isotropic':
3457                    isoSizer = wx.BoxSizer(wx.HORIZONTAL)
3458                    isoSizer.Add(TopSizer(' Size model: ',['isotropic','uniaxial','ellipsoidal'],
3459                        'Size',OnSizeType),0,wx.ALIGN_CENTER_VERTICAL)
3460                    isoSizer.Add(LGmixSizer('Size',OnLGmixVal,OnLGmixRef))
3461                    mainSizer.Add(isoSizer)
3462                    mainSizer.Add(IsoSizer(u' Cryst. size(\xb5m): ','Size','%.3f',
3463                        OnSizeVal,OnSizeRef),0,wx.ALIGN_CENTER_VERTICAL)
3464                elif UseList[item]['Size'][0] == 'uniaxial':
3465                    uniSizer = wx.BoxSizer(wx.HORIZONTAL)
3466                    uniSizer.Add(TopSizer(' Size model: ',['isotropic','uniaxial','ellipsoidal'],
3467                        'Size',OnSizeType),0,wx.ALIGN_CENTER_VERTICAL)
3468                    uniSizer.Add(LGmixSizer('Size',OnLGmixVal,OnLGmixRef))
3469                    uniSizer.Add(UniSizer('Size',OnSizeAxis),0,wx.ALIGN_CENTER_VERTICAL)
3470                    mainSizer.Add(uniSizer)
3471                    mainSizer.Add(UniDataSizer(u'size(\xb5m): ','Size','%.3f',OnSizeVal,OnSizeRef))
3472                elif UseList[item]['Size'][0] == 'ellipsoidal':
3473                    ellSizer = wx.BoxSizer(wx.HORIZONTAL)
3474                    ellSizer.Add(TopSizer(' Size model: ',['isotropic','uniaxial','ellipsoidal'],
3475                        'Size',OnSizeType),0,wx.ALIGN_CENTER_VERTICAL)
3476                    ellSizer.Add(LGmixSizer('Size',OnLGmixVal,OnLGmixRef))
3477                    mainSizer.Add(ellSizer)
3478                    mainSizer.Add(EllSizeDataSizer())
3479                mainSizer.Add((0,5),0)                   
3480               
3481                if UseList[item]['Mustrain'][0] == 'isotropic':
3482                    isoSizer = wx.BoxSizer(wx.HORIZONTAL)
3483                    isoSizer.Add(TopSizer(' Mustrain model: ',['isotropic','uniaxial','generalized',],
3484                        'Mustrain',OnStrainType),0,wx.ALIGN_CENTER_VERTICAL)
3485                    isoSizer.Add(LGmixSizer('Mustrain',OnLGmixVal,OnLGmixRef))
3486                    mainSizer.Add(isoSizer)
3487                    mainSizer.Add(IsoSizer(' microstrain: ','Mustrain','%.1f',
3488                        OnStrainVal,OnStrainRef),0,wx.ALIGN_CENTER_VERTICAL)                   
3489                    mainSizer.Add((0,5),0)
3490                elif UseList[item]['Mustrain'][0] == 'uniaxial':
3491                    uniSizer = wx.BoxSizer(wx.HORIZONTAL)
3492                    uniSizer.Add(TopSizer(' Mustrain model: ',['isotropic','uniaxial','generalized',],
3493                        'Mustrain',OnStrainType),0,wx.ALIGN_CENTER_VERTICAL)
3494                    uniSizer.Add(LGmixSizer('Mustrain',OnLGmixVal,OnLGmixRef))
3495                    uniSizer.Add(UniSizer('Mustrain',OnStrainAxis),0,wx.ALIGN_CENTER_VERTICAL)
3496                    mainSizer.Add(uniSizer)
3497                    mainSizer.Add(UniDataSizer('mustrain: ','Mustrain','%.1f',OnStrainVal,OnStrainRef))
3498                elif UseList[item]['Mustrain'][0] == 'generalized':
3499                    genSizer = wx.BoxSizer(wx.HORIZONTAL)
3500                    genSizer.Add(TopSizer(' Mustrain model: ',['isotropic','uniaxial','generalized',],
3501                        'Mustrain',OnStrainType),0,wx.ALIGN_CENTER_VERTICAL)
3502                    genSizer.Add(LGmixSizer('Mustrain',OnLGmixVal,OnLGmixRef))
3503                    mainSizer.Add(genSizer)
3504                    mainSizer.Add(GenStrainDataSizer())                       
3505                mainSizer.Add((0,5),0)
3506               
3507                mainSizer.Add(wx.StaticText(DData,-1,' Hydrostatic/elastic strain:'))
3508                mainSizer.Add(HstrainSizer())
3509                   
3510                #texture  'Pref. Ori.':['MD',1.0,False,[0,0,1],0,[]] last two for 'SH' are SHorder & coeff
3511                poSizer = wx.BoxSizer(wx.VERTICAL)
3512                POData = UseList[item]['Pref.Ori.']
3513                poSizer.Add(PoTopSizer(POData))
3514                if POData[0] == 'MD':
3515                    poSizer.Add(MDDataSizer(POData))
3516                else:           #'SH'
3517                    if POData[4]:       #SH order > 0
3518                        poSizer.Add(SHDataSizer(POData))
3519                       
3520                mainSizer.Add(poSizer)
3521                mainSizer.Add((0,5),0)               
3522                #Extinction  'Extinction':[0.0,False]
3523                mainSizer.Add(ExtSizer())
3524                mainSizer.Add((0,5),0)
3525            elif item[:4] == 'HKLF' and UseList[item]['Show']:
3526                mainSizer.Add((0,5),0)               
3527                mainSizer.Add(SCExtSizer())
3528                mainSizer.Add((0,5),0)
3529                pass
3530        mainSizer.Add((5,5),0)
3531
3532        DData.SetSizer(mainSizer,True)
3533        mainSizer.FitInside(G2frame.dataFrame)
3534        Size = mainSizer.GetMinSize()
3535        Size[0] += 40
3536        Size[1] = max(Size[1],290) + 20
3537        DData.SetSize(Size)
3538        DData.SetScrollbars(10,10,Size[0]/10-4,Size[1]/10-1)
3539        Size[1] = min(Size[1],450)
3540        G2frame.dataFrame.setSizePosLeft(Size)
3541       
3542    def OnHklfAdd(event):
3543        UseList = data['Histograms']
3544        keyList = UseList.keys()
3545        TextList = []
3546        if G2frame.PatternTree.GetCount():
3547            item, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root)
3548            while item:
3549                name = G2frame.PatternTree.GetItemText(item)
3550                if name not in keyList and 'HKLF' in name:
3551                    TextList.append(name)
3552                item, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie)                       
3553            dlg = wx.MultiChoiceDialog(G2frame, 'Which new data to use?', 'Use data', TextList, wx.CHOICEDLG_STYLE)
3554            try:
3555                if dlg.ShowModal() == wx.ID_OK:
3556                    result = dlg.GetSelections()
3557                    for i in result:
3558                        histoName = TextList[i]
3559                        UseList[histoName] = {'Histogram':histoName,'Show':False,'Scale':[1.0,True],
3560                            'Extinction':['Lorentzian','Secondary Type I',
3561                            {'Tbar':0.0,'Eg':[0.0,False],'Es':[0.0,False],'Ep':[0.0,False]},]}                       
3562                    data['Histograms'] = UseList
3563                    wx.BeginBusyCursor()
3564                    UpdateHKLFdata(histoName)
3565                    wx.EndBusyCursor()
3566                    wx.CallAfter(UpdateDData)
3567            finally:
3568                dlg.Destroy()
3569               
3570    def UpdateHKLFdata(histoName):
3571        generalData = data['General']
3572        Id = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,histoName)
3573        reflData = G2frame.PatternTree.GetItemPyData(Id)[1]
3574        SGData = generalData['SGData']
3575        Cell = generalData['Cell'][1:7]
3576        G,g = G2lat.cell2Gmat(Cell)
3577        for ref in reflData:
3578            H = ref[:3]
3579            ref[4] = np.sqrt(1./G2lat.calc_rDsq2(H,G))
3580            iabsnt,ref[3],ref[11],ref[12] = G2spc.GenHKLf(H,SGData)
3581        G2frame.PatternTree.SetItemPyData(Id,[histoName,reflData])
3582       
3583    def OnPwdrAdd(event):
3584        generalData = data['General']
3585        SGData = generalData['SGData']
3586        UseList = data['Histograms']
3587        newList = []
3588        NShkl = len(G2spc.MustrainNames(SGData))
3589        NDij = len(G2spc.HStrainNames(SGData))
3590        keyList = UseList.keys()
3591        TextList = ['All PWDR']
3592        if G2frame.PatternTree.GetCount():
3593            item, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root)
3594            while item:
3595                name = G2frame.PatternTree.GetItemText(item)
3596                if name not in keyList and 'PWDR' in name:
3597                    TextList.append(name)
3598                item, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie)
3599            dlg = wx.MultiChoiceDialog(G2frame, 'Which new data to use?', 'Use data', TextList, wx.CHOICEDLG_STYLE)
3600            try:
3601                if dlg.ShowModal() == wx.ID_OK:
3602                    result = dlg.GetSelections()
3603                    for i in result: newList.append(TextList[i])
3604                    if 'All PWDR' in newList:
3605                        newList = TextList[1:]
3606                    for histoName in newList:
3607                        pId = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,histoName)
3608                        UseList[histoName] = {'Histogram':histoName,'Show':False,
3609                            'Scale':[1.0,False],'Pref.Ori.':['MD',1.0,False,[0,0,1],0,{}],
3610                            'Size':['isotropic',[4.,4.,1.0],[False,False,False],[0,0,1],
3611                                [4.,4.,4.,0.,0.,0.],6*[False,]],
3612                            'Mustrain':['isotropic',[1000.0,1000.0,1.0],[False,False,False],[0,0,1],
3613                                NShkl*[0.01,],NShkl*[False,]],
3614                            'HStrain':[NDij*[0.0,],NDij*[False,]],                         
3615                            'Extinction':[0.0,False]}
3616                        refList = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,pId,'Reflection Lists'))
3617                        refList[generalData['Name']] = []                       
3618                    data['Histograms'] = UseList
3619                    wx.CallAfter(UpdateDData)
3620            finally:
3621                dlg.Destroy()
3622       
3623    def OnDataDelete(event):
3624        UseList = data['Histograms']
3625        keyList = ['All',]+UseList.keys()
3626        keyList.sort()
3627        DelList = []
3628        if UseList:
3629            DelList = []
3630            dlg = wx.MultiChoiceDialog(G2frame, 
3631                'Which histogram to delete from this phase?', 'Delete histogram', 
3632                keyList, wx.CHOICEDLG_STYLE)
3633            try:
3634                if dlg.ShowModal() == wx.ID_OK:
3635                    result = dlg.GetSelections()
3636                    for i in result: 
3637                        DelList.append(keyList[i])
3638                    if 'All' in DelList:
3639                        DelList = keyList[1:]
3640                    for i in DelList:
3641                        del UseList[i]
3642                    wx.CallAfter(UpdateDData)
3643            finally:
3644                dlg.Destroy()
3645
3646################################################################################
3647##### Pawley routines
3648################################################################################
3649
3650    def FillPawleyReflectionsGrid():
3651                       
3652        def KeyEditPawleyGrid(event):
3653            colList = G2frame.PawleyRefl.GetSelectedCols()
3654            PawleyPeaks = data['Pawley ref']
3655            if event.GetKeyCode() == wx.WXK_RETURN:
3656                event.Skip(True)
3657            elif event.GetKeyCode() == wx.WXK_CONTROL:
3658                event.Skip(True)
3659            elif event.GetKeyCode() == wx.WXK_SHIFT:
3660                event.Skip(True)
3661            elif colList:
3662                G2frame.PawleyRefl.ClearSelection()
3663                key = event.GetKeyCode()
3664                for col in colList:
3665                    if PawleyTable.GetTypeName(0,col) == wg.GRID_VALUE_BOOL:
3666                        if key == 89: #'Y'
3667                            for row in range(PawleyTable.GetNumberRows()): PawleyPeaks[row][col]=True
3668                        elif key == 78:  #'N'
3669                            for row in range(PawleyTable.GetNumberRows()): PawleyPeaks[row][col]=False
3670                        FillPawleyReflectionsGrid()
3671           
3672        if 'Pawley ref' in data:
3673            PawleyPeaks = data['Pawley ref']                       
3674            rowLabels = []
3675            for i in range(len(PawleyPeaks)): rowLabels.append(str(i))
3676            colLabels = ['h','k','l','mul','d','refine','Fsq(hkl)','sig(Fsq)']
3677            Types = 4*[wg.GRID_VALUE_LONG,]+[wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_BOOL,]+ \
3678                2*[wg.GRID_VALUE_FLOAT+':10,2',]
3679            PawleyTable = G2gd.Table(PawleyPeaks,rowLabels=rowLabels,colLabels=colLabels,types=Types)
3680            G2frame.PawleyRefl.SetTable(PawleyTable, True)
3681            G2frame.PawleyRefl.Bind(wx.EVT_KEY_DOWN, KeyEditPawleyGrid)                 
3682            for r in range(G2frame.PawleyRefl.GetNumberRows()):
3683                for c in range(G2frame.PawleyRefl.GetNumberCols()):
3684                    if c in [5,6]:
3685                        G2frame.PawleyRefl.SetReadOnly(r,c,isReadOnly=False)
3686                    else:
3687                        G2frame.PawleyRefl.SetCellStyle(r,c,VERY_LIGHT_GREY,True)
3688            G2frame.PawleyRefl.SetMargins(0,0)
3689            G2frame.PawleyRefl.AutoSizeColumns(False)
3690            G2frame.dataFrame.setSizePosLeft([500,300])
3691                   
3692    def OnPawleyLoad(event):
3693        generalData = data['General']
3694        dmin = generalData['Pawley dmin']
3695        cell = generalData['Cell'][1:7]
3696        A = G2lat.cell2A(cell)
3697        SGData = generalData['SGData']
3698        HKLd = np.array(G2lat.GenHLaue(dmin,SGData,A))
3699        PawleyPeaks = []
3700        wx.BeginBusyCursor()
3701        try:
3702            for h,k,l,d in HKLd:
3703                ext,mul = G2spc.GenHKLf([h,k,l],SGData)[:2]
3704                if not ext:
3705                    mul *= 2        #for powder multiplicity
3706                    PawleyPeaks.append([h,k,l,mul,d,False,100.0,1.0])
3707        finally:
3708            wx.EndBusyCursor()
3709        data['Pawley ref'] = PawleyPeaks
3710        FillPawleyReflectionsGrid()
3711       
3712    def OnPawleyEstimate(event):
3713        try:
3714            Refs = data['Pawley ref']
3715            Histograms = data['Histograms']
3716        except KeyError:
3717            print '**** Error - no histograms defined for this phase ****'
3718            return
3719        HistoNames = Histograms.keys()
3720        PatternId = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,HistoNames[0])
3721        xdata = G2frame.PatternTree.GetItemPyData(PatternId)[1]
3722        Inst = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId,'Instrument Parameters'))
3723        Inst = dict(zip(Inst[3],Inst[1]))
3724        Sample = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId,'Sample Parameters'))
3725        if 'Lam' in Inst:
3726            wave = Inst['Lam']
3727        else:
3728            wave = Inst['Lam1']
3729        posCorr = Inst['Zero']
3730        const = 9.e-2/(np.pi*Sample['Gonio. radius'])                  #shifts in microns
3731       
3732        for ref in Refs:
3733            pos = 2.0*asind(wave/(2.0*ref[4]))
3734            if 'Bragg' in Sample['Type']:
3735                pos -= const*(4.*Sample['Shift'][0]*cosd(pos/2.0)+ \
3736                    Sample['Transparency'][0]*sind(pos)*100.0)            #trans(=1/mueff) in cm
3737            else:               #Debye-Scherrer - simple but maybe not right
3738                pos -= const*(Sample['DisplaceX'][0]*cosd(pos)+Sample['DisplaceY'][0]*sind(pos))
3739            indx = np.searchsorted(xdata[0],pos)
3740            try:
3741                FWHM = max(0.001,G2pwd.getFWHM(pos,Inst))/2.
3742                dx = xdata[0][indx+1]-xdata[0][indx]
3743                ref[6] = FWHM*xdata[1][indx]/dx
3744                Lorenz = 1./(2.*sind(xdata[0][indx]/2.)**2*cosd(xdata[0][indx]/2.))           #Lorentz correction
3745                pola,dIdPola = G2pwd.Polarization(Inst['Polariz.'],xdata[0][indx],Inst['Azimuth'])
3746                ref[6] /= (Lorenz*pola*ref[3])
3747            except IndexError:
3748                pass
3749        FillPawleyReflectionsGrid()
3750
3751    def OnPawleyUpdate(event):
3752        try:
3753            Refs = data['Pawley ref']
3754            Histograms = data['Histograms']
3755        except KeyError:
3756            print '**** Error - no histograms defined for this phase ****'
3757            return
3758        HistoNames = Histograms.keys()
3759        PatternId = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,HistoNames[0])
3760        refData = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId,'Reflection Lists'))[PhaseName]
3761        for iref,ref in enumerate(Refs):
3762            try:
3763                ref[6] = refData[iref][9]
3764                ref[7] = 1.0
3765            except IndexError:
3766                pass
3767        FillPawleyReflectionsGrid()
3768                           
3769    def OnPawleyDelete(event):
3770        dlg = wx.MessageDialog(G2frame,'Do you really want to delete Pawley reflections?','Delete', 
3771            wx.YES_NO | wx.ICON_QUESTION)
3772        try:
3773            result = dlg.ShowModal()
3774        finally:
3775            dlg.Destroy()
3776        if result == wx.ID_YES: 
3777            data['Pawley ref'] = []
3778            FillPawleyReflectionsGrid()
3779
3780################################################################################
3781##### Fourier routines
3782################################################################################
3783
3784    def FillMapPeaksGrid():
3785                       
3786        def RowSelect(event):
3787            r,c =  event.GetRow(),event.GetCol()
3788            if r < 0 and c < 0:
3789                if MapPeaks.IsSelection():
3790                    MapPeaks.ClearSelection()
3791                else:
3792                    for row in range(MapPeaks.GetNumberRows()):
3793                        MapPeaks.SelectRow(row,True)
3794                   
3795            elif c < 0:                   #only row clicks
3796                if event.ControlDown():                   
3797                    if r in MapPeaks.GetSelectedRows():
3798                        MapPeaks.DeselectRow(r)
3799                    else:
3800                        MapPeaks.SelectRow(r,True)
3801                elif event.ShiftDown():
3802                    for row in range(r+1):
3803                        MapPeaks.SelectRow(row,True)
3804                else:
3805                    MapPeaks.ClearSelection()
3806                    MapPeaks.SelectRow(r,True)               
3807            G2plt.PlotStructure(G2frame,data)                   
3808           
3809        G2frame.dataFrame.setSizePosLeft([450,300])
3810        if 'Map Peaks' in data:
3811            mapPeaks = data['Map Peaks']                       
3812            rowLabels = []
3813            for i in range(len(mapPeaks)): rowLabels.append(str(i))
3814            colLabels = ['mag','x','y','z']
3815            Types = 4*[wg.GRID_VALUE_FLOAT+':10,4',]
3816            MapPeaksTable = G2gd.Table(mapPeaks,rowLabels=rowLabels,colLabels=colLabels,types=Types)
3817            MapPeaks.SetTable(MapPeaksTable, True)
3818            MapPeaks.Bind(wg.EVT_GRID_LABEL_LEFT_CLICK, RowSelect)
3819            for r in range(MapPeaks.GetNumberRows()):
3820                for c in range(MapPeaks.GetNumberCols()):
3821                    MapPeaks.SetCellStyle(r,c,VERY_LIGHT_GREY,True)
3822            MapPeaks.SetMargins(0,0)
3823            MapPeaks.AutoSizeColumns(False)
3824                   
3825    def OnPeaksMove(event):
3826        if 'Map Peaks' in data:
3827            mapPeaks = data['Map Peaks']                       
3828            Ind = MapPeaks.GetSelectedRows()
3829            for ind in Ind:
3830                x,y,z = mapPeaks[ind][1:]
3831                AtomAdd(x,y,z,'C')
3832   
3833    def OnPeaksClear(event):
3834        data['Map Peaks'] = []
3835        FillMapPeaksGrid()
3836        G2plt.PlotStructure(G2frame,data)
3837       
3838    def OnPeaksDelete(event):
3839        if 'Map Peaks' in data:
3840            mapPeaks = data['Map Peaks']
3841            Ind = MapPeaks.GetSelectedRows()
3842            Ind.sort()
3843            Ind.reverse()
3844            for ind in Ind:
3845                mapPeaks = np.delete(mapPeaks,ind,0)
3846            data['Map Peaks'] = mapPeaks
3847        FillMapPeaksGrid()
3848        G2plt.PlotStructure(G2frame,data)
3849               
3850    def OnPeaksUnique(event):
3851        if 'Map Peaks' in data:
3852            mapPeaks = data['Map Peaks']
3853            Ind = MapPeaks.GetSelectedRows()
3854            if Ind:
3855                G2mth.PeaksUnique(data,Ind)
3856                FillMapPeaksGrid()
3857                G2plt.PlotStructure(G2frame,data)
3858   
3859    def OnFourierMaps(event):
3860        generalData = data['General']
3861        mapData = generalData['Map']
3862        reflName = mapData['RefList']
3863        phaseName = generalData['Name']
3864        if 'PWDR' in reflName:
3865            PatternId = G2gd.GetPatternTreeItemId(G2frame,G2frame.root, reflName)
3866            reflSets = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId,'Reflection Lists'))
3867            reflData = reflSets[phaseName]
3868        elif 'HKLF' in reflName:
3869            PatternId = G2gd.GetPatternTreeItemId(G2frame,G2frame.root, reflName)
3870            reflData = G2frame.PatternTree.GetItemPyData(PatternId)[1]
3871        mapData.update(G2mth.FourierMap(data,reflData))
3872        mapData['Flip'] = False
3873        mapSig = np.std(mapData['rho'])
3874        if not data['Drawing']:                 #if new drawing - no drawing data!
3875            SetupDrawingData()
3876        data['Drawing']['contourLevel'] = 1.
3877        data['Drawing']['mapSize'] = 10.
3878        print mapData['MapType']+' computed: rhomax = %.3f rhomin = %.3f sigma = %.3f'%(np.max(mapData['rho']),np.min(mapData['rho']),mapSig)
3879        UpdateDrawAtoms()
3880        G2plt.PlotStructure(G2frame,data)
3881       
3882    def OnFourClear(event):
3883        generalData = data['General']
3884        generalData['Map'] = mapDefault
3885        G2plt.PlotStructure(G2frame,data)
3886       
3887    def printRho(SGLaue,rho,rhoMax):                         
3888# map printing for testing purposes
3889        dim = len(rho.shape)
3890        if dim == 2:
3891            ix,jy = rho.shape
3892            for j in range(jy):
3893                line = ''
3894                if SGLaue in ['3','3m1','31m','6/m','6/mmm']:
3895                    line += (jy-j)*'  '
3896                for i in range(ix):
3897                    r = int(100*rho[i,j]/rhoMax)
3898                    line += '%4d'%(r)
3899                print line+'\n'
3900        else:
3901            ix,jy,kz = rho.shape
3902            for k in range(kz):
3903                print 'k = ',k
3904                for j in range(jy):
3905                    line = ''
3906                    if SGLaue in ['3','3m1','31m','6/m','6/mmm']:
3907                        line += (jy-j)*'  '
3908                    for i in range(ix):
3909                        r = int(100*rho[i,j,k]/rhoMax)
3910                        line += '%4d'%(r)
3911                    print line+'\n'
3912## keep this               
3913   
3914    def OnSearchMaps(event):
3915       
3916        peaks = []
3917        mags = []
3918        print ' Begin fourier map search - can take some time'
3919        time0 = time.time()
3920        generalData = data['General']
3921        mapData = generalData['Map']
3922        if len(mapData['rho']):
3923            pgbar = wx.ProgressDialog('Map search','No. Peaks found =',301.0, 
3924                style = wx.PD_ELAPSED_TIME|wx.PD_AUTO_HIDE|wx.PD_CAN_ABORT)
3925            screenSize = wx.ClientDisplayRect()
3926            Size = pgbar.GetSize()
3927            Size = (int(Size[0]*1.2),Size[1]) # increase size a bit along x
3928            pgbar.SetPosition(wx.Point(screenSize[2]-Size[0]-305,screenSize[1]+5))
3929            pgbar.SetSize(Size)
3930            try:
3931                peaks,mags = G2mth.SearchMap(data,keepDup=True,Pgbar=pgbar)
3932            finally:
3933                pgbar.Destroy()
3934            sortIdx = np.argsort(mags.flatten())
3935            if len(peaks):
3936                data['Map Peaks'] = np.concatenate((mags,peaks),axis=1)           
3937                print ' Map search finished, time = %.2fs'%(time.time()-time0)
3938            Page = G2frame.dataDisplay.FindPage('Map peaks')
3939            G2frame.dataDisplay.ChangeSelection(Page)
3940            G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.MapPeaksMenu)
3941            G2frame.dataFrame.Bind(wx.EVT_MENU, OnPeaksMove, id=G2gd.wxID_PEAKSMOVE)
3942            G2frame.dataFrame.Bind(wx.EVT_MENU, OnPeaksUnique, id=G2gd.wxID_PEAKSUNIQUE)
3943            G2frame.dataFrame.Bind(wx.EVT_MENU, OnPeaksDelete, id=G2gd.wxID_PEAKSDELETE)
3944            G2frame.dataFrame.Bind(wx.EVT_MENU, OnPeaksClear, id=G2gd.wxID_PEAKSCLEAR)
3945            UpdateDrawAtoms()
3946            FillMapPeaksGrid()
3947        else:
3948            print 'No map available'
3949       
3950    def OnChargeFlip(event):
3951        generalData = data['General']
3952        mapData = generalData['Map']
3953        flipData = generalData['Flip']
3954        reflName = flipData['RefList']
3955        phaseName = generalData['Name']
3956        if 'PWDR' in reflName:
3957            PatternId = G2gd.GetPatternTreeItemId(G2frame,G2frame.root, reflName)
3958            reflSets = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId,'Reflection Lists'))
3959            reflData = reflSets[phaseName]
3960        elif 'HKLF' in reflName:
3961            PatternId = G2gd.GetPatternTreeItemId(G2frame,G2frame.root, reflName)
3962            reflData = G2frame.PatternTree.GetItemPyData(PatternId)[1]
3963        else:
3964            print '**** ERROR - No data defined for charge flipping'
3965            return
3966        pgbar = wx.ProgressDialog('Charge flipping','Residual Rcf =',101.0, 
3967            style = wx.PD_ELAPSED_TIME|wx.PD_AUTO_HIDE|wx.PD_CAN_ABORT)
3968        screenSize = wx.ClientDisplayRect()
3969        Size = pgbar.GetSize()
3970        Size = (int(Size[0]*1.2),Size[1]) # increase size a bit along x
3971        pgbar.SetPosition(wx.Point(screenSize[2]-Size[0]-305,screenSize[1]+5))
3972        pgbar.SetSize(Size)
3973        try:
3974            mapData.update(G2mth.ChargeFlip(data,reflData,pgbar))
3975        finally:
3976            pgbar.Destroy()
3977        mapData['Flip'] = True       
3978        mapSig = np.std(mapData['rho'])
3979        if not data['Drawing']:                 #if new drawing - no drawing data!
3980            SetupDrawingData()
3981        data['Drawing']['contourLevel'] = 1.
3982        data['Drawing']['mapSize'] = 10.
3983        print ' Charge flip map computed: rhomax = %.3f rhomin = %.3f sigma = %.3f'%(np.max(mapData['rho']),np.min(mapData['rho']),mapSig)
3984        if mapData['Rcf'] < 99.:
3985            OnSearchMaps(event)             #does a plot structure at end
3986        else:
3987            print 'Bad charge flip map - no peak search done'
3988               
3989    def OnTextureRefine(event):
3990        print 'refine texture?'
3991        event.Skip()       
3992           
3993    def OnTextureClear(event):
3994        print 'clear texture?'
3995        event.Skip()
3996
3997    def OnPageChanged(event):
3998        page = event.GetSelection()
3999        text = G2frame.dataDisplay.GetPageText(page)
4000        if text == 'Atoms':
4001            G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.AtomsMenu)
4002            G2frame.dataFrame.Bind(wx.EVT_MENU, OnAtomAdd, id=G2gd.wxID_ATOMSEDITADD)
4003            G2frame.dataFrame.Bind(wx.EVT_MENU, OnAtomTestAdd, id=G2gd.wxID_ATOMSTESTADD)
4004            G2frame.dataFrame.Bind(wx.EVT_MENU, OnAtomInsert, id=G2gd.wxID_ATOMSEDITINSERT)
4005            G2frame.dataFrame.Bind(wx.EVT_MENU, OnAtomTestInsert, id=G2gd.wxID_ATONTESTINSERT)
4006            G2frame.dataFrame.Bind(wx.EVT_MENU, AtomDelete, id=G2gd.wxID_ATOMSEDITDELETE)
4007            G2frame.dataFrame.Bind(wx.EVT_MENU, AtomRefine, id=G2gd.wxID_ATOMSREFINE)
4008            G2frame.dataFrame.Bind(wx.EVT_MENU, AtomModify, id=G2gd.wxID_ATOMSMODIFY)
4009            G2frame.dataFrame.Bind(wx.EVT_MENU, AtomTransform, id=G2gd.wxID_ATOMSTRANSFORM)
4010            G2frame.dataFrame.Bind(wx.EVT_MENU, OnReloadDrawAtoms, id=G2gd.wxID_RELOADDRAWATOMS)
4011            G2frame.dataFrame.Bind(wx.EVT_MENU, OnDistAngle, id=G2gd.wxID_ATOMSDISAGL)
4012            FillAtomsGrid()
4013        elif text == 'General':
4014            G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.DataGeneral)
4015            G2frame.dataFrame.Bind(wx.EVT_MENU, OnFourierMaps, id=G2gd.wxID_FOURCALC)
4016            G2frame.dataFrame.Bind(wx.EVT_MENU, OnSearchMaps, id=G2gd.wxID_FOURSEARCH)
4017            G2frame.dataFrame.Bind(wx.EVT_MENU, OnChargeFlip, id=G2gd.wxID_CHARGEFLIP)
4018            G2frame.dataFrame.Bind(wx.EVT_MENU, OnFourClear, id=G2gd.wxID_FOURCLEAR)
4019            UpdateGeneral()
4020        elif text == 'Data':
4021            G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.DataMenu)
4022            G2frame.dataFrame.Bind(wx.EVT_MENU, OnPwdrAdd, id=G2gd.wxID_PWDRADD)
4023            G2frame.dataFrame.Bind(wx.EVT_MENU, OnHklfAdd, id=G2gd.wxID_HKLFADD)
4024            G2frame.dataFrame.Bind(wx.EVT_MENU, OnDataDelete, id=G2gd.wxID_DATADELETE)
4025            UpdateDData()
4026            G2plt.PlotSizeStrainPO(G2frame,data,Start=True)
4027        elif text == 'Draw Options':
4028            G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.DataDrawOptions)
4029            UpdateDrawOptions()
4030            G2plt.PlotStructure(G2frame,data)
4031        elif text == 'Draw Atoms':
4032            G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.DrawAtomsMenu)
4033            G2frame.dataFrame.Bind(wx.EVT_MENU, DrawAtomStyle, id=G2gd.wxID_DRAWATOMSTYLE)
4034            G2frame.dataFrame.Bind(wx.EVT_MENU, DrawAtomLabel, id=G2gd.wxID_DRAWATOMLABEL)
4035            G2frame.dataFrame.Bind(wx.EVT_MENU, DrawAtomColor, id=G2gd.wxID_DRAWATOMCOLOR)
4036            G2frame.dataFrame.Bind(wx.EVT_MENU, ResetAtomColors, id=G2gd.wxID_DRAWATOMRESETCOLOR)
4037            G2frame.dataFrame.Bind(wx.EVT_MENU, SetViewPoint, id=G2gd.wxID_DRAWVIEWPOINT)
4038            G2frame.dataFrame.Bind(wx.EVT_MENU, AddSymEquiv, id=G2gd.wxID_DRAWADDEQUIV)
4039            G2frame.dataFrame.Bind(wx.EVT_MENU, TransformSymEquiv, id=G2gd.wxID_DRAWTRANSFORM)
4040            G2frame.dataFrame.Bind(wx.EVT_MENU, FillCoordSphere, id=G2gd.wxID_DRAWFILLCOORD)           
4041            G2frame.dataFrame.Bind(wx.EVT_MENU, FillUnitCell, id=G2gd.wxID_DRAWFILLCELL)
4042            G2frame.dataFrame.Bind(wx.EVT_MENU, DrawAtomsDelete, id=G2gd.wxID_DRAWDELETE)
4043            G2frame.dataFrame.Bind(wx.EVT_MENU, OnDrawDAT, id=G2gd.wxID_DRAWDISAGLTOR)
4044            G2frame.dataFrame.Bind(wx.EVT_MENU, OnDrawPlane, id=G2gd.wxID_DRAWPLANE)
4045            G2frame.dataFrame.Bind(wx.EVT_MENU, OnRestraint, id=G2gd.wxID_DRAWRESTRBOND)
4046            G2frame.dataFrame.Bind(wx.EVT_MENU, OnRestraint, id=G2gd.wxID_DRAWRESTRANGLE)
4047            G2frame.dataFrame.Bind(wx.EVT_MENU, OnRestraint, id=G2gd.wxID_DRAWRESTRPLANE)
4048            G2frame.dataFrame.Bind(wx.EVT_MENU, OnRestraint, id=G2gd.wxID_DRAWRESTRCHIRAL)
4049            UpdateDrawAtoms()
4050            G2plt.PlotStructure(G2frame,data)
4051        elif text == 'Pawley reflections':
4052            G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.PawleyMenu)
4053            G2frame.dataFrame.Bind(wx.EVT_MENU, OnPawleyLoad, id=G2gd.wxID_PAWLEYLOAD)
4054            G2frame.dataFrame.Bind(wx.EVT_MENU, OnPawleyEstimate, id=G2gd.wxID_PAWLEYESTIMATE)
4055            G2frame.dataFrame.Bind(wx.EVT_MENU, OnPawleyUpdate, id=G2gd.wxID_PAWLEYUPDATE)
4056            G2frame.dataFrame.Bind(wx.EVT_MENU, OnPawleyDelete, id=G2gd.wxID_PAWLEYDELETE)           
4057            FillPawleyReflectionsGrid()
4058        elif text == 'Texture':
4059            G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.TextureMenu)
4060            G2frame.dataFrame.Bind(wx.EVT_MENU, OnTextureRefine, id=G2gd.wxID_REFINETEXTURE)
4061            G2frame.dataFrame.Bind(wx.EVT_MENU, OnTextureClear, id=G2gd.wxID_CLEARTEXTURE)
4062            UpdateTexture()                       
4063            G2plt.PlotTexture(G2frame,data,Start=True)
4064        elif text == 'Map peaks':
4065            G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.MapPeaksMenu)
4066            G2frame.dataFrame.Bind(wx.EVT_MENU, OnPeaksMove, id=G2gd.wxID_PEAKSMOVE)
4067            G2frame.dataFrame.Bind(wx.EVT_MENU, OnPeaksUnique, id=G2gd.wxID_PEAKSUNIQUE)
4068            G2frame.dataFrame.Bind(wx.EVT_MENU, OnPeaksDelete, id=G2gd.wxID_PEAKSDELETE)
4069            G2frame.dataFrame.Bind(wx.EVT_MENU, OnPeaksClear, id=G2gd.wxID_PEAKSCLEAR)
4070            FillMapPeaksGrid()
4071            G2plt.PlotStructure(G2frame,data)
4072           
4073        else:
4074            G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.BlankMenu)
4075        event.Skip()
4076       
4077    General = wx.Window(G2frame.dataDisplay)
4078    G2frame.dataDisplay.AddPage(General,'General')
4079    G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.DataGeneral)
4080    G2frame.dataFrame.Bind(wx.EVT_MENU, OnFourierMaps, id=G2gd.wxID_FOURCALC)
4081    G2frame.dataFrame.Bind(wx.EVT_MENU, OnSearchMaps, id=G2gd.wxID_FOURSEARCH)
4082    G2frame.dataFrame.Bind(wx.EVT_MENU, OnChargeFlip, id=G2gd.wxID_CHARGEFLIP)
4083    G2frame.dataFrame.Bind(wx.EVT_MENU, OnFourClear, id=G2gd.wxID_FOURCLEAR)
4084    SetupGeneral()
4085    GeneralData = data['General']
4086    UpdateGeneral()
4087
4088    DData = wx.ScrolledWindow(G2frame.dataDisplay)
4089    G2frame.dataDisplay.AddPage(DData,'Data')
4090    Atoms = G2gd.GSGrid(G2frame.dataDisplay)
4091    G2frame.dataDisplay.AddPage(Atoms,'Atoms')
4092    drawOptions = wx.Window(G2frame.dataDisplay)
4093    G2frame.dataDisplay.AddPage(drawOptions,'Draw Options')
4094    drawAtoms = G2gd.GSGrid(G2frame.dataDisplay)
4095    G2frame.dataDisplay.AddPage(drawAtoms,'Draw Atoms')
4096    Texture = wx.ScrolledWindow(G2frame.dataDisplay)
4097    G2frame.dataDisplay.AddPage(Texture,'Texture')
4098    MapPeaks = G2gd.GSGrid(G2frame.dataDisplay)
4099    G2frame.dataDisplay.AddPage(MapPeaks,'Map peaks')
4100    G2frame.PawleyRefl = G2gd.GSGrid(G2frame.dataDisplay)
4101    G2frame.dataDisplay.AddPage(G2frame.PawleyRefl,'Pawley reflections')
4102           
4103    G2frame.dataDisplay.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, OnPageChanged)
4104    G2frame.dataDisplay.SetSelection(oldPage)
4105   
4106           
Note: See TracBrowser for help on using the repository browser.