source: trunk/GSASIIphsGUI.py @ 661

Last change on this file since 661 was 661, checked in by toby, 10 years ago

complete revision number tracking

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