source: trunk/GSASIIphsGUI.py @ 380

Last change on this file since 380 was 380, checked in by vondreele, 11 years ago

completed Rietveld refinement version

  • Property svn:keywords set to Date Author Revision URL Id
File size: 137.9 KB
Line 
1#GSASII - phase data display routines
2########### SVN repository information ###################
3# $Date: 2011-10-03 20:43:49 +0000 (Mon, 03 Oct 2011) $
4# $Author: vondreele $
5# $Revision: 380 $
6# $URL: trunk/GSASIIphsGUI.py $
7# $Id: GSASIIphsGUI.py 380 2011-10-03 20:43:49Z vondreele $
8########### SVN repository information ###################
9import wx
10import wx.grid as wg
11import matplotlib as mpl
12import math
13import copy
14import time
15import sys
16import random as ran
17import cPickle
18import GSASIIpath
19import GSASIIlattice as G2lat
20import GSASIIspc as G2spc
21import GSASIIElem as G2elem
22import GSASIIplot as G2plt
23import GSASIIgrid as G2gd
24import GSASIIIO as G2IO
25import numpy as np
26import numpy.linalg as nl
27
28VERY_LIGHT_GREY = wx.Colour(235,235,235)
29WHITE = wx.Colour(255,255,255)
30BLACK = wx.Colour(0,0,0)
31
32# trig functions in degrees
33sind = lambda x: math.sin(x*math.pi/180.)
34tand = lambda x: math.tan(x*math.pi/180.)
35cosd = lambda x: math.cos(x*math.pi/180.)
36asind = lambda x: 180.*math.asin(x)/math.pi
37
38class SymOpDialog(wx.Dialog):
39    def __init__(self,parent,SGData,New=True):
40        wx.Dialog.__init__(self,parent,-1,'Select symmetry operator',
41            pos=wx.DefaultPosition,style=wx.DEFAULT_DIALOG_STYLE)
42        panel = wx.Panel(self)
43        self.SGData = SGData
44        self.New = New
45        self.OpSelected = [0,0,0,[0,0,0],False]
46        mainSizer = wx.BoxSizer(wx.VERTICAL)
47        mainSizer.Add((5,5),0)
48        if SGData['SGInv']:
49            choice = ['No','Yes']
50            self.inv = wx.RadioBox(panel,-1,'Choose inversion?',choices=choice)
51            self.inv.Bind(wx.EVT_RADIOBOX, self.OnOpSelect)
52            mainSizer.Add(self.inv,0,wx.ALIGN_CENTER_VERTICAL)
53        mainSizer.Add((5,5),0)
54        if SGData['SGLatt'] != 'P':
55            LattOp = G2spc.Latt2text(SGData['SGLatt']).split(';')
56            self.latt = wx.RadioBox(panel,-1,'Choose cell centering?',choices=LattOp)
57            self.latt.Bind(wx.EVT_RADIOBOX, self.OnOpSelect)
58            mainSizer.Add(self.latt,0,wx.ALIGN_CENTER_VERTICAL)
59        mainSizer.Add((5,5),0)
60        if SGData['SGLaue'] in ['-1','2/m','mmm','4/m','4/mmm']:
61            Ncol = 2
62        else:
63            Ncol = 3
64        OpList = []
65        for M,T in SGData['SGOps']:
66            OpList.append(G2spc.MT2text(M,T))
67        self.oprs = wx.RadioBox(panel,-1,'Choose space group operator?',choices=OpList,
68            majorDimension=Ncol)
69        self.oprs.Bind(wx.EVT_RADIOBOX, self.OnOpSelect)
70        mainSizer.Add(self.oprs,0,wx.ALIGN_CENTER_VERTICAL)
71        mainSizer.Add((5,5),0)
72        mainSizer.Add(wx.StaticText(panel,-1,"   Choose unit cell?"),0,wx.ALIGN_CENTER_VERTICAL)
73        mainSizer.Add((5,5),0)
74        cellSizer = wx.BoxSizer(wx.HORIZONTAL)
75        cellSizer.Add((5,0),0)
76        cellName = ['X','Y','Z']
77        self.cell = []
78        for i in range(3):
79            self.cell.append(wx.SpinCtrl(panel,-1,cellName[i],size=wx.Size(50,20)))
80            self.cell[-1].SetRange(-3,3)
81            self.cell[-1].SetValue(0)
82            self.cell[-1].Bind(wx.EVT_SPINCTRL, self.OnOpSelect)
83            cellSizer.Add(self.cell[-1],0,wx.ALIGN_CENTER_VERTICAL)
84        mainSizer.Add(cellSizer,0,)
85        if self.New:
86            choice = ['No','Yes']
87            self.new = wx.RadioBox(panel,-1,'Generate new positions?',choices=choice)
88            self.new.Bind(wx.EVT_RADIOBOX, self.OnOpSelect)
89            mainSizer.Add(self.new,0,wx.ALIGN_CENTER_VERTICAL)
90        mainSizer.Add((5,5),0)
91
92        OkBtn = wx.Button(panel,-1,"Ok")
93        OkBtn.Bind(wx.EVT_BUTTON, self.OnOk)
94        cancelBtn = wx.Button(panel,-1,"Cancel")
95        cancelBtn.Bind(wx.EVT_BUTTON, self.OnCancel)
96        btnSizer = wx.BoxSizer(wx.HORIZONTAL)
97        btnSizer.Add((20,20),1)
98        btnSizer.Add(OkBtn)
99        btnSizer.Add((20,20),1)
100        btnSizer.Add(cancelBtn)
101        btnSizer.Add((20,20),1)
102
103        mainSizer.Add(btnSizer,0,wx.EXPAND|wx.BOTTOM|wx.TOP, 10)
104        panel.SetSizer(mainSizer)
105        panel.Fit()
106        self.Fit()
107
108    def OnOpSelect(self,event):
109        if self.SGData['SGInv']:
110            self.OpSelected[0] = self.inv.GetSelection()
111        if self.SGData['SGLatt'] != 'P':
112            self.OpSelected[1] = self.latt.GetSelection()
113        self.OpSelected[2] = self.oprs.GetSelection()
114        for i in range(3):
115            self.OpSelected[3][i] = float(self.cell[i].GetValue())
116        if self.New:
117            self.OpSelected[4] = self.new.GetSelection()
118
119    def GetSelection(self):
120        return self.OpSelected
121
122    def OnOk(self,event):
123        parent = self.GetParent()
124        parent.Raise()
125        self.EndModal(wx.ID_OK)
126        self.Destroy()
127
128    def OnCancel(self,event):
129        parent = self.GetParent()
130        parent.Raise()
131        self.EndModal(wx.ID_CANCEL)
132        self.Destroy()
133
134def UpdatePhaseData(self,Item,data,oldPage):
135
136    Atoms = []
137    if self.dataDisplay:
138        self.dataDisplay.Destroy()
139    PhaseName = self.PatternTree.GetItemText(Item)
140    self.dataFrame.SetMenuBar(self.dataFrame.BlankMenu)
141    self.dataFrame.SetLabel('Phase Data for '+PhaseName)
142    self.dataFrame.CreateStatusBar()
143    self.dataDisplay = G2gd.GSNoteBook(parent=self.dataFrame,size=self.dataFrame.GetClientSize())
144
145    def SetupGeneral():
146        generalData = data['General']
147        atomData = data['Atoms']
148        generalData['AtomTypes'] = []
149        generalData['NoAtoms'] = {}
150        generalData['BondRadii'] = []
151        generalData['AngleRadii'] = []
152        generalData['vdWRadii'] = []
153        generalData['AtomMass'] = []
154        generalData['Color'] = []
155        generalData['Mydir'] = self.dirname
156        cx,ct,cs,cia = [3,1,7,9]
157        generalData['AtomPtrs'] = [cx,ct,cs,cia]
158        if generalData['Type'] =='macromolecular':
159            cx,ct,cs,cia = [6,4,10,12]
160            generalData['AtomPtrs'] = [cx,ct,cs,cia]
161        for atom in atomData:
162            atom[ct] = atom[ct].lower().capitalize()              #force to standard form
163            if generalData['AtomTypes'].count(atom[ct]):
164                generalData['NoAtoms'][atom[ct]] += atom[cs-1]*float(atom[cs+1])
165            elif atom[ct] != 'UNK':
166                Info = G2elem.GetAtomInfo(atom[ct])
167                generalData['AtomTypes'].append(atom[ct])
168                generalData['BondRadii'].append(Info['Drad'])
169                generalData['AngleRadii'].append(Info['Arad'])
170                generalData['vdWRadii'].append(Info['Vdrad'])
171                generalData['AtomMass'].append(Info['Mass'])
172                generalData['NoAtoms'][atom[ct]] = atom[cs-1]*float(atom[cs+1])
173                generalData['Color'].append(Info['Color'])
174
175    def UpdateGeneral():
176       
177        ''' default dictionary structure for phase data: (taken from GSASII.py)
178        'General':{
179            'Name':PhaseName
180            'Type':'nuclear'
181            'SGData':SGData
182            'Cell':[False,10.,10.,10.,90.,90.,90,1000.]
183            'AtomPtrs':[]
184            'Histogram list':['',]
185            'Pawley dmin':1.0}
186        'Atoms':[]
187        'Drawing':{}
188        '''
189        phaseTypes = ['nuclear','modulated','magnetic','macromolecular','Pawley']
190        SetupGeneral()
191        generalData = data['General']
192       
193        def OnPhaseName(event):
194            oldName = generalData['Name']
195            generalData['Name'] = NameTxt.GetValue()
196            self.G2plotNB.Rename(oldName,generalData['Name'])
197            self.dataFrame.SetLabel('Phase Data for '+generalData['Name'])
198            self.PatternTree.SetItemText(Item,generalData['Name'])
199            #Hmm, need to change phase name key in Reflection Lists for each histogram
200                       
201        def OnPhaseType(event):
202            if not generalData['AtomTypes']:             #can change only if no atoms!
203                generalData['Type'] = TypeTxt.GetValue()
204                dataDisplay.Destroy()           #needed to clear away bad cellSizer, etc.
205                UpdateGeneral()
206                if generalData['Type'] == 'Pawley':
207                    if self.dataDisplay.FindPage('Atoms'):
208                        self.dataDisplay.DeletePage(self.dataDisplay.FindPage('Atoms'))
209                        self.dataDisplay.DeletePage(self.dataDisplay.FindPage('Draw Options'))
210                        self.dataDisplay.DeletePage(self.dataDisplay.FindPage('Draw Atoms'))
211                    if not self.dataDisplay.FindPage('Pawley reflections'):
212                        self.PawleyRefl = G2gd.GSGrid(self.dataDisplay)     
213                        self.dataDisplay.AddPage(self.PawleyRefl,'Pawley reflections')
214            else:
215                TypeTxt.SetValue(generalData['Type'])               
216               
217        def OnSpaceGroup(event):
218            SpcGp = SGTxt.GetValue()
219            SGErr,SGData = G2spc.SpcGroup(SpcGp)
220            if SGErr:
221                text = [G2spc.SGErrors(SGErr)+'\nSpace Group set to previous']
222                SGTxt.SetValue(generalData['SGData']['SpGrp'])
223                msg = 'Space Group Error'
224                Style = wx.ICON_EXCLAMATION
225            else:
226                text = G2spc.SGPrint(SGData)
227                generalData['SGData'] = SGData
228                msg = 'Space Group Information'
229                Style = wx.ICON_INFORMATION
230            Text = ''
231            for line in text:
232                Text += line+'\n'
233            wx.MessageBox(Text,caption=msg,style=Style)
234            dataDisplay.DestroyChildren()           #needed to clear away bad cellSizer, etc.
235            UpdateGeneral()
236           
237        def OnCellRef(event):
238            generalData['Cell'][0] = cellRef.GetValue()
239           
240        def OnCellChange(event):
241            SGData = generalData['SGData']
242            laue = SGData['SGLaue']
243            if laue == '2/m':
244                laue += SGData['SGUniq']
245            cell = generalData['Cell']
246            Obj = event.GetEventObject()
247            ObjId = cellList.index(Obj.GetId())
248            try:
249                value = max(1.0,float(Obj.GetValue()))
250            except ValueError:
251                if ObjId < 3:               #bad cell edge - reset
252                    value = controls[6+ObjId]
253                else:                       #bad angle
254                    value = 90.
255            if laue in ['m3','m3m']:
256                cell[1] = cell[2] = cell[3] = value
257                cell[4] = cell[5] = cell[6] = 90.0
258                Obj.SetValue("%.5f"%(cell[1]))
259            elif laue in ['3R','3mR']:
260                if ObjId == 0:
261                    cell[1] = cell[2] = cell[3] = value
262                    Obj.SetValue("%.5f"%(cell[1]))
263                else:
264                    cell[4] = cell[5] = cell[6] = value
265                    Obj.SetValue("%.5f"%(cell[4]))
266            elif laue in ['3','3m1','31m','6/m','6/mmm','4/m','4/mmm']:                   
267                cell[4] = cell[5] = 90.
268                cell[6] = 120.
269                if ObjId == 0:
270                    cell[1] = cell[2] = value
271                    Obj.SetValue("%.5f"%(cell[1]))
272                else:
273                    cell[3] = value
274                    Obj.SetValue("%.5f"%(cell[3]))
275            elif laue in ['mmm']:
276                cell[ObjId+1] = value
277                cell[4] = cell[5] = cell[6] = 90.
278                Obj.SetValue("%.5f"%(cell[ObjId+1]))
279            elif laue in ['2/m'+'a']:
280                cell[5] = cell[6] = 90.
281                if ObjId != 3:
282                    cell[ObjId+1] = value
283                    Obj.SetValue("%.5f"%(cell[ObjId+1]))
284                else:
285                    cell[4] = value
286                    Obj.SetValue("%.3f"%(cell[4]))
287            elif laue in ['2/m'+'b']:
288                cell[4] = cell[6] = 90.
289                if ObjId != 3:
290                    cell[ObjId+1] = value
291                    Obj.SetValue("%.5f"%(cell[ObjId+1]))
292                else:
293                    cell[5] = value
294                    Obj.SetValue("%.3f"%(cell[5]))
295            elif laue in ['2/m'+'c']:
296                cell[5] = cell[6] = 90.
297                if ObjId != 3:
298                    cell[ObjId+1] = value
299                    Obj.SetValue("%.5f"%(cell[ObjId+1]))
300                else:
301                    cell[6] = value
302                    Obj.SetValue("%.3f"%(cell[6]))
303            else:
304                cell[ObjId+1] = value
305                if ObjId < 3:
306                    Obj.SetValue("%.5f"%(cell[1+ObjId]))
307                else:
308                    Obj.SetValue("%.3f"%(cell[1+ObjId]))
309            cell[7] = G2lat.calc_V(G2lat.cell2A(cell[1:7]))
310            volVal.SetValue("%.3f"%(cell[7]))
311            generalData['Cell'] = cell
312            dataDisplay.Destroy()           #needed to clear away bad cellSizer, etc.
313            UpdateGeneral()
314                       
315        def OnPawleyVal(event):
316            try:
317                dmin = float(pawlVal.GetValue())
318                if 0.25 <= dmin <= 20.:
319                    generalData['Pawley dmin'] = dmin
320            except ValueError:
321                pass
322            pawlVal.SetValue("%.3f"%(generalData['Pawley dmin']))          #reset in case of error           
323                                   
324        cellGUIlist = [[['m3','m3m'],4,zip([" Unit cell: a = "," Vol = "],["%.5f","%.3f"],[True,False],[0,0])],
325        [['3R','3mR'],6,zip([" a = "," alpha = "," Vol = "],["%.5f","%.3f","%.3f"],[True,True,False],[0,2,0])],
326        [['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])],
327        [['mmm'],8,zip([" a = "," b = "," c = "," Vol = "],["%.5f","%.5f","%.5f","%.3f"],
328            [True,True,True,False],[0,1,2,0])],
329        [['2/m'+'a'],10,zip([" a = "," b = "," c = "," alpha = "," Vol = "],
330            ["%.5f","%.5f","%.5f","%.3f","%.3f"],[True,True,True,True,False],[0,1,2,4,0])],
331        [['2/m'+'b'],10,zip([" a = "," b = "," c = "," beta = "," Vol = "],
332            ["%.5f","%.5f","%.5f","%.3f","%.3f"],[True,True,True,True,False],[0,1,2,4,0])],
333        [['2/m'+'c'],10,zip([" a = "," b = "," c = "," gamma = "," Vol = "],
334            ["%.5f","%.5f","%.5f","%.3f","%.3f"],[True,True,True,True,False],[0,1,2,4,0])],
335        [['-1'],8,zip([" a = "," b = "," c = "," Vol = "," alpha = "," beta = "," gamma = "],
336            ["%.5f","%.5f","%.5f","%.3f","%.3f","%.3f","%.3f"],
337            [True,True,True,False,True,True,True],[0,1,2,0,3,4,5])]]
338       
339        General.DestroyChildren()
340        dataDisplay = wx.Panel(General)
341        mainSizer = wx.BoxSizer(wx.VERTICAL)
342        mainSizer.Add((5,5),0)
343        mainSizer.Add(wx.StaticText(dataDisplay,-1,'General phase data:'),0,wx.ALIGN_CENTER_VERTICAL)
344        mainSizer.Add((5,5),0)
345        nameSizer = wx.BoxSizer(wx.HORIZONTAL)
346        nameSizer.Add(wx.StaticText(dataDisplay,-1,' Phase name: '),0,wx.ALIGN_CENTER_VERTICAL)
347        NameTxt = wx.TextCtrl(dataDisplay,-1,value=generalData['Name'],style=wx.TE_PROCESS_ENTER)
348        NameTxt.Bind(wx.EVT_TEXT_ENTER,OnPhaseName)
349        NameTxt.Bind(wx.EVT_KILL_FOCUS,OnPhaseName)
350        nameSizer.Add(NameTxt,0,wx.ALIGN_CENTER_VERTICAL)
351        nameSizer.Add(wx.StaticText(dataDisplay,-1,'  Phase type: '),0,wx.ALIGN_CENTER_VERTICAL)
352        if len(data['Atoms']):
353            choices = phaseTypes[:-1]
354        else:
355            choices = phaseTypes           
356        TypeTxt = wx.ComboBox(dataDisplay,-1,value=generalData['Type'],choices=choices,
357            style=wx.CB_READONLY|wx.CB_DROPDOWN)
358        TypeTxt.Bind(wx.EVT_COMBOBOX, OnPhaseType)
359        nameSizer.Add(TypeTxt,0,wx.ALIGN_CENTER_VERTICAL)
360        nameSizer.Add(wx.StaticText(dataDisplay,-1,'  Space group: '),0,wx.ALIGN_CENTER_VERTICAL)
361        SGTxt = wx.TextCtrl(dataDisplay,-1,value=generalData['SGData']['SpGrp'],style=wx.TE_PROCESS_ENTER)
362        SGTxt.Bind(wx.EVT_TEXT_ENTER,OnSpaceGroup)
363        nameSizer.Add(SGTxt,0,wx.ALIGN_CENTER_VERTICAL)
364        mainSizer.Add(nameSizer,0)
365        mainSizer.Add((5,5),0)
366        cell = generalData['Cell']
367        laue = generalData['SGData']['SGLaue']
368        if laue == '2/m':
369            laue += generalData['SGData']['SGUniq']
370        for cellGUI in cellGUIlist:
371            if laue in cellGUI[0]:
372                useGUI = cellGUI
373        cellList = []
374        cellSizer = wx.FlexGridSizer(2,useGUI[1]+1,5,5)
375        cellRef = wx.CheckBox(dataDisplay,-1,label='Refine unit cell:')
376        cellSizer.Add(cellRef,0,wx.ALIGN_CENTER_VERTICAL)
377        cellRef.Bind(wx.EVT_CHECKBOX, OnCellRef)
378        cellRef.SetValue(cell[0])
379        for txt,fmt,ifEdit,Id in useGUI[2]:
380            cellSizer.Add(wx.StaticText(dataDisplay,label=txt),0,wx.ALIGN_CENTER_VERTICAL)
381            if ifEdit:          #a,b,c,etc.
382                cellVal = wx.TextCtrl(dataDisplay,value=(fmt%(cell[Id+1])),
383                    style=wx.TE_PROCESS_ENTER)
384                cellVal.Bind(wx.EVT_TEXT_ENTER,OnCellChange)       
385                cellVal.Bind(wx.EVT_KILL_FOCUS,OnCellChange)
386                cellSizer.Add(cellVal,0,wx.ALIGN_CENTER_VERTICAL)
387                cellList.append(cellVal.GetId())
388            else:               #volume
389                volVal = wx.TextCtrl(dataDisplay,value=(fmt%(cell[7])),style=wx.TE_READONLY)
390                volVal.SetBackgroundColour(VERY_LIGHT_GREY)
391                cellSizer.Add(volVal,0,wx.ALIGN_CENTER_VERTICAL)
392        mainSizer.Add(cellSizer,0)
393        mainSizer.Add((5,5),0)
394       
395        if len(generalData['AtomTypes']):
396            mass = 0.
397            for i,elem in enumerate(generalData['AtomTypes']):
398                mass += generalData['NoAtoms'][elem]*generalData['AtomMass'][i]
399            denSizer = wx.BoxSizer(wx.HORIZONTAL)
400            denSizer.Add(wx.StaticText(dataDisplay,-1,' Density: '),0,wx.ALIGN_CENTER_VERTICAL)
401            Volume = generalData['Cell'][7]
402            density = mass/(0.6022137*Volume)
403            denTxt = wx.TextCtrl(dataDisplay,-1,'%.3f'%(density),style=wx.TE_READONLY)
404            denTxt.SetBackgroundColour(VERY_LIGHT_GREY)
405            denSizer.Add(denTxt,0,wx.ALIGN_CENTER_VERTICAL)       
406            if generalData['Type'] == 'macromolecular' and mass > 0.0:
407                denSizer.Add(wx.StaticText(dataDisplay,-1,' Matthews coeff.: '),
408                    0,wx.ALIGN_CENTER_VERTICAL)
409                mattTxt = wx.TextCtrl(dataDisplay,-1,'%.3f'%(Volume/mass),style=wx.TE_READONLY)
410                mattTxt.SetBackgroundColour(VERY_LIGHT_GREY)
411                denSizer.Add(mattTxt,0,wx.ALIGN_CENTER_VERTICAL)
412            mainSizer.Add(denSizer)
413            mainSizer.Add((5,5),0)
414           
415            elemSizer = wx.FlexGridSizer(7,len(generalData['AtomTypes'])+1,1,1)
416            elemSizer.Add(wx.StaticText(dataDisplay,label='Elements'),0,wx.ALIGN_CENTER_VERTICAL)
417            for elem in generalData['AtomTypes']:
418                typTxt = wx.TextCtrl(dataDisplay,value=elem,style=wx.TE_READONLY)
419                typTxt.SetBackgroundColour(VERY_LIGHT_GREY)
420                elemSizer.Add(typTxt,0,wx.ALIGN_CENTER_VERTICAL)
421            elemSizer.Add(wx.StaticText(dataDisplay,label='No. per cell'),0,wx.ALIGN_CENTER_VERTICAL)
422            for elem in generalData['AtomTypes']:
423                numbTxt = wx.TextCtrl(dataDisplay,value='%.1f'%(generalData['NoAtoms'][elem]),
424                    style=wx.TE_READONLY)
425                numbTxt.SetBackgroundColour(VERY_LIGHT_GREY)
426                elemSizer.Add(numbTxt,0,wx.ALIGN_CENTER_VERTICAL)
427            elemSizer.Add(wx.StaticText(dataDisplay,label='Atom weight'),0,wx.ALIGN_CENTER_VERTICAL)
428            for wt in generalData['AtomMass']:
429                wtTxt = wx.TextCtrl(dataDisplay,value='%.3f'%(wt),style=wx.TE_READONLY)
430                wtTxt.SetBackgroundColour(VERY_LIGHT_GREY)
431                elemSizer.Add(wtTxt,0,wx.ALIGN_CENTER_VERTICAL)
432            elemSizer.Add(wx.StaticText(dataDisplay,label='Bond radii'),0,wx.ALIGN_CENTER_VERTICAL)
433            for rad in generalData['BondRadii']:
434                bondRadii = wx.TextCtrl(dataDisplay,value='%.2f'%(rad),style=wx.TE_READONLY)
435                bondRadii.SetBackgroundColour(VERY_LIGHT_GREY)
436                elemSizer.Add(bondRadii,0,wx.ALIGN_CENTER_VERTICAL)
437            elemSizer.Add(wx.StaticText(dataDisplay,label='Angle radii'),0,wx.ALIGN_CENTER_VERTICAL)
438            for rad in generalData['AngleRadii']:
439                elemTxt = wx.TextCtrl(dataDisplay,value='%.2f'%(rad),style=wx.TE_READONLY)
440                elemTxt.SetBackgroundColour(VERY_LIGHT_GREY)
441                elemSizer.Add(elemTxt,0,wx.ALIGN_CENTER_VERTICAL)
442            elemSizer.Add(wx.StaticText(dataDisplay,label='van der Waals radii'),0,wx.ALIGN_CENTER_VERTICAL)
443            for rad in generalData['vdWRadii']:
444                elemTxt = wx.TextCtrl(dataDisplay,value='%.2f'%(rad),style=wx.TE_READONLY)
445                elemTxt.SetBackgroundColour(VERY_LIGHT_GREY)
446                elemSizer.Add(elemTxt,0,wx.ALIGN_CENTER_VERTICAL)
447            elemSizer.Add(wx.StaticText(dataDisplay,label='Default color'),0,wx.ALIGN_CENTER_VERTICAL)
448            for color in generalData['Color']:
449                colorTxt = wx.TextCtrl(dataDisplay,value='',style=wx.TE_READONLY)
450                colorTxt.SetBackgroundColour(color)
451                elemSizer.Add(colorTxt,0,wx.ALIGN_CENTER_VERTICAL)
452            mainSizer.Add(elemSizer)
453           
454        elif generalData['Type'] == 'Pawley':
455            pawlSizer = wx.BoxSizer(wx.HORIZONTAL)
456            pawlSizer.Add(wx.StaticText(dataDisplay,label=' Pawley dmin: '),0,wx.ALIGN_CENTER_VERTICAL)
457            pawlVal = wx.TextCtrl(dataDisplay,value='%.3f'%(generalData['Pawley dmin']),style=wx.TE_PROCESS_ENTER)
458            pawlVal.Bind(wx.EVT_TEXT_ENTER,OnPawleyVal)       
459            pawlVal.Bind(wx.EVT_KILL_FOCUS,OnPawleyVal)
460            pawlSizer.Add(pawlVal,0,wx.ALIGN_CENTER_VERTICAL)
461            mainSizer.Add(pawlSizer)
462
463        dataDisplay.SetSizer(mainSizer)
464        Size = mainSizer.Fit(self.dataFrame)
465        Size[1] += 26                           #compensate for status bar
466        dataDisplay.SetSize(Size)
467        self.dataFrame.setSizePosLeft(Size)
468
469    def FillAtomsGrid():
470
471        self.dataFrame.setSizePosLeft([700,300])
472        generalData = data['General']
473        atomData = data['Atoms']
474        Items = [G2gd.wxID_ATOMSEDITINSERT, G2gd.wxID_ATOMSEDITDELETE, G2gd.wxID_ATOMSREFINE, 
475            G2gd.wxID_ATOMSMODIFY, G2gd.wxID_ATOMSTRANSFORM, G2gd.wxID_ATONTESTINSERT]
476        if atomData:
477            for item in Items:   
478                self.dataFrame.AtomsMenu.Enable(item,True)
479        else:
480            for item in Items:
481                self.dataFrame.AtomsMenu.Enable(item,False)           
482           
483        AAchoice = ": ,ALA,ARG,ASN,ASP,CYS,GLN,GLU,GLY,HIS,ILE,LEU,LYS,MET,PHE,PRO,SER,THR,TRP,TYR,VAL,MSE,HOH,UNK"
484        Types = [wg.GRID_VALUE_STRING,wg.GRID_VALUE_STRING,wg.GRID_VALUE_CHOICE+": ,X,XU,U,F,FX,FXU,FU",]+ \
485            3*[wg.GRID_VALUE_FLOAT+':10,5',]+[wg.GRID_VALUE_FLOAT+':10,4', #x,y,z,frac
486            wg.GRID_VALUE_STRING,wg.GRID_VALUE_STRING,wg.GRID_VALUE_CHOICE+":I,A",]
487        Types += 7*[wg.GRID_VALUE_FLOAT+':10,5',]
488        colLabels = ['Name','Type','refine','x','y','z','frac','site sym','mult','I/A','Uiso','U11','U22','U33','U12','U13','U23']
489        if generalData['Type'] == 'magnetic':
490            colLabels += ['Mx','My','Mz']
491            Types[2] = wg.GRID_VALUE_CHOICE+": ,X,XU,U,M,MX,MXU,MU,F,FX,FXU,FU,FM,FMX,FMU,"
492            Types += 3*[wg.GRID_VALUE_FLOAT+':10,4',]
493        elif generalData['Type'] == 'macromolecular':
494            colLabels = ['res no','residue','chain'] + colLabels
495            Types = [wg.GRID_VALUE_STRING,
496                wg.GRID_VALUE_CHOICE+AAchoice,
497                wg.GRID_VALUE_STRING] + Types
498        elif generalData['Type'] == 'modulated':
499            Types += []
500            colLabels += []
501
502        def RefreshAtomGrid(event):
503
504            r,c =  event.GetRow(),event.GetCol()
505            if r < 0 and c < 0:
506                for row in range(Atoms.GetNumberRows()):
507                    Atoms.SelectRow(row,True)                   
508            if r < 0:                          #double click on col label! Change all atoms!
509                sel = -1
510                noSkip = True
511                if Atoms.GetColLabelValue(c) == 'refine':
512                    Type = generalData['Type']
513                    if Type in ['nuclear','macromolecular']:
514                        choice = ['F - site fraction','X - coordinates','U - thermal parameters']
515                    elif Type in ['magnetic',]:
516                        choice = ['F - site fraction','X - coordinates','U - thermal parameters','M - magnetic moment']
517                    dlg = wx.MultiChoiceDialog(self,'Select','Refinement controls',choice)
518                    if dlg.ShowModal() == wx.ID_OK:
519                        sel = dlg.GetSelections()
520                        parms = ''
521                        for x in sel:
522                            parms += choice[x][0]
523                    dlg.Destroy()
524                elif Atoms.GetColLabelValue(c) == 'I/A':
525                    choice = ['Isotropic','Anisotropic']
526                    dlg = wx.SingleChoiceDialog(self,'Select','Thermal Motion',choice)
527                    if dlg.ShowModal() == wx.ID_OK:
528                        sel = dlg.GetSelection()
529                        parms = choice[sel][0]
530                    dlg.Destroy()
531                elif Atoms.GetColLabelValue(c) == 'Type':
532                    choice = generalData['AtomTypes']
533                    dlg = wx.SingleChoiceDialog(self,'Select','Atom types',choice)
534                    if dlg.ShowModal() == wx.ID_OK:
535                        sel = dlg.GetSelection()
536                        parms = choice[sel]
537                        noSkip = False
538                        Atoms.ClearSelection()
539                        for row in range(Atoms.GetNumberRows()):
540                            if parms == atomData[row][c]:
541                                Atoms.SelectRow(row,True)
542                elif Atoms.GetColLabelValue(c) == 'residue':
543                    choice = []
544                    for r in range(Atoms.GetNumberRows()):
545                        if str(atomData[r][c]) not in choice:
546                            choice.append(str(atomData[r][c]))
547                    choice.sort()
548                    dlg = wx.SingleChoiceDialog(self,'Select','Residue',choice)
549                    if dlg.ShowModal() == wx.ID_OK:
550                        sel = dlg.GetSelection()
551                        parms = choice[sel]
552                        noSkip = False
553                        Atoms.ClearSelection()
554                        for row in range(Atoms.GetNumberRows()):
555                            if parms == atomData[row][c]:
556                                Atoms.SelectRow(row,True)
557                elif Atoms.GetColLabelValue(c) == 'res no':
558                    choice = []
559                    for r in range(Atoms.GetNumberRows()):
560                        if str(atomData[r][c]) not in choice:
561                            choice.append(str(atomData[r][c]))
562                    dlg = wx.SingleChoiceDialog(self,'Select','Residue no.',choice)
563                    if dlg.ShowModal() == wx.ID_OK:
564                        sel = dlg.GetSelection()
565                        parms = choice[sel]
566                        noSkip = False
567                        Atoms.ClearSelection()
568                        for row in range(Atoms.GetNumberRows()):
569                            if int(parms) == atomData[row][c]:
570                                Atoms.SelectRow(row,True)
571                elif Atoms.GetColLabelValue(c) == 'chain':
572                    choice = []
573                    for r in range(Atoms.GetNumberRows()):
574                        if atomData[r][c] not in choice:
575                            choice.append(atomData[r][c])
576                    dlg = wx.SingleChoiceDialog(self,'Select','Chain',choice)
577                    if dlg.ShowModal() == wx.ID_OK:
578                        sel = dlg.GetSelection()
579                        parms = choice[sel]
580                        noSkip = False
581                        Atoms.ClearSelection()
582                        for row in range(Atoms.GetNumberRows()):
583                            if parms == atomData[row][c]:
584                                Atoms.SelectRow(row,True)
585                    dlg.Destroy()
586                elif Atoms.GetColLabelValue(c) == 'Uiso':       #this needs to ask for value
587                    pass                                        #& then change all 'I' atoms
588                if sel >= 0 and noSkip:
589                    ui = colLabels.index('U11')
590                    us = colLabels.index('Uiso')
591                    ss = colLabels.index('site sym')
592                    for r in range(Atoms.GetNumberRows()):
593                        ID = atomData[r][-1]
594                        if parms != atomData[r][c] and Atoms.GetColLabelValue(c) == 'I/A':
595                            if parms == 'A':                #'I' --> 'A'
596                                Uiso = float(Atoms.GetCellValue(r,us))
597                                sytsym = atomData[r][ss]
598                                CSI = G2spc.GetCSuinel(sytsym)
599                                atomData[r][ui:ui+6] = Uiso*np.array(CSI[3])
600                                atomData[r][us] = 0.0
601                                Atoms.SetCellStyle(r,us,VERY_LIGHT_GREY,True)
602                                for i in range(6):
603                                    ci = ui+i
604                                    Atoms.SetCellStyle(r,ci,VERY_LIGHT_GREY,True)
605                                    if CSI[2][i]:
606                                        Atoms.SetCellStyle(r,ci,WHITE,False)
607                            else:                           #'A' --> 'I'
608                                Uij = atomData[r][ui:ui+6]
609                                Uiso = (Uij[0]+Uij[1]+Uij[2])/3.0
610                                atomData[r][us] = Uiso
611                                Atoms.SetCellStyle(r,us,WHITE,False)
612                                for i in range(6):
613                                    ci = ui+i
614                                    atomData[r][ci] = 0.0
615                                    Atoms.SetCellStyle(r,ci,VERY_LIGHT_GREY,True)
616                        atomData[r][c] = parms
617                        if 'Atoms' in data['Drawing']:
618                            DrawAtomsReplaceByID(data['Drawing'],atomData[r],ID)
619                    FillAtomsGrid()
620                   
621        def ChangeAtomCell(event):
622           
623            def chkUij(Uij,CSI): #needs to do something!!!
624                return Uij
625
626            r,c =  event.GetRow(),event.GetCol()
627            if r >= 0 and c >= 0:
628                ID = atomData[r][-1]
629                if Atoms.GetColLabelValue(c) in ['x','y','z']:
630                    ci = colLabels.index('x')
631                    XYZ = atomData[r][ci:ci+3]
632                    if None in XYZ:
633                        XYZ = [0,0,0]
634                    SScol = colLabels.index('site sym')
635                    Mulcol = colLabels.index('mult')
636                    E,SGData = G2spc.SpcGroup(generalData['SGData']['SpGrp'])
637                    Sytsym,Mult = G2spc.SytSym(XYZ,SGData)
638                    atomData[r][SScol] = Sytsym
639                    atomData[r][Mulcol] = Mult
640                    if atomData[r][colLabels.index('I/A')] == 'A':
641                        ui = colLabels.index('U11')
642                        CSI = G2spc.GetCSuinel(Sytsym)
643                        atomData[r][ui:ui+6] = chkUij(atomData[r][ui:ui+6],Sytsym)
644                        for i in range(6):
645                            ci = i+ui
646                            Atoms.SetCellStyle(r,ci,VERY_LIGHT_GREY,True)
647                            if CSI[2][i]:
648                                Atoms.SetCellStyle(r,ci,WHITE,False)
649                    SetupGeneral()
650                elif Atoms.GetColLabelValue(c) == 'I/A':            #note use of text color to make it vanish!
651                    if atomData[r][c] == 'I':
652                        Uij = atomData[r][c+2:c+8]
653                        atomData[r][c+1] = (Uij[0]+Uij[1]+Uij[2])/3.0
654                        Atoms.SetCellStyle(r,c+1,WHITE,False)
655                        Atoms.SetCellTextColour(r,c+1,BLACK)
656                        for i in range(6):
657                            ci = i+colLabels.index('U11')
658                            Atoms.SetCellStyle(r,ci,VERY_LIGHT_GREY,True)
659                            Atoms.SetCellTextColour(r,ci,VERY_LIGHT_GREY)
660                            atomData[r][ci] = 0.0
661                    else:
662                        value = atomData[r][c+1]
663                        CSI = G2spc.GetCSuinel(atomData[r][colLabels.index('site sym')])
664                        atomData[r][c+1] =  0.0
665                        Atoms.SetCellStyle(r,c+1,VERY_LIGHT_GREY,True)
666                        Atoms.SetCellTextColour(r,c+1,VERY_LIGHT_GREY)
667                        for i in range(6):
668                            ci = i+colLabels.index('U11')
669                            atomData[r][ci] = value*CSI[3][i]
670                            Atoms.SetCellStyle(r,ci,VERY_LIGHT_GREY,True)
671                            Atoms.SetCellTextColour(r,ci,BLACK)
672                            if CSI[2][i]:
673                                Atoms.SetCellStyle(r,ci,WHITE,False)
674                elif Atoms.GetColLabelValue(c) in ['U11','U22','U33','U12','U13','U23']:
675                    value = atomData[r][c]
676                    CSI = G2spc.GetCSuinel(atomData[r][colLabels.index('site sym')])
677                    iUij = CSI[0][c-colLabels.index('U11')]
678                    for i in range(6):
679                        if iUij == CSI[0][i]:
680                            atomData[r][i+colLabels.index('U11')] = value*CSI[1][i]
681                if 'Atoms' in data['Drawing']:
682                    DrawAtomsReplaceByID(data['Drawing'],atomData[r],ID)
683                    FindBonds()
684                   
685        def AtomTypeSelect(event):
686            r,c =  event.GetRow(),event.GetCol()
687            if Atoms.GetColLabelValue(c) == 'Type':
688                PE = G2elem.PickElement(self)
689                if PE.ShowModal() == wx.ID_OK:
690                    atomData[r][c] = PE.Elem.strip()
691                    name = atomData[r][c]
692                    if len(name) in [2,4]:
693                        atomData[r][c-1] = name[:2]+'(%d)'%(r+1)
694                    else:
695                        atomData[r][c-1] = name[:1]+'(%d)'%(r+1)
696                PE.Destroy()
697                SetupGeneral()
698                FillAtomsGrid()
699                value = Atoms.GetCellValue(r,c)
700                atomData[r][c] = value
701                ID = atomData[r][-1]
702                if 'Atoms' in data['Drawing']:
703                    DrawAtomsReplaceByID(data['Drawing'],atomData[r],ID)
704            else:
705                event.Skip()
706
707        def RowSelect(event):
708            r,c =  event.GetRow(),event.GetCol()
709            if r < 0 and c < 0:
710                if Atoms.IsSelection():
711                    Atoms.ClearSelection()
712            elif c < 0:                   #only row clicks
713                if event.ControlDown():                   
714                    if r in Atoms.GetSelectedRows():
715                        Atoms.DeselectRow(r)
716                    else:
717                        Atoms.SelectRow(r,True)
718                elif event.ShiftDown():
719                    for row in range(r+1):
720                        Atoms.SelectRow(row,True)
721                else:
722                    Atoms.ClearSelection()
723                    Atoms.SelectRow(r,True)               
724               
725        def ChangeSelection(event):
726            r,c =  event.GetRow(),event.GetCol()
727            if r < 0 and c < 0:
728                Atoms.ClearSelection()
729            if c < 0:
730                if r in Atoms.GetSelectedRows():
731                    Atoms.DeselectRow(r)
732                else:
733                    Atoms.SelectRow(r,True)
734            if r < 0:
735                if c in Atoms.GetSelectedCols():
736                    Atoms.DeselectCol(c)
737                else:
738                    Atoms.SelectCol(c,True)
739
740        table = []
741        rowLabels = []
742        for i,atom in enumerate(atomData):
743            table.append(atom)
744            rowLabels.append(str(i))
745        atomTable = G2gd.Table(table,rowLabels=rowLabels,colLabels=colLabels,types=Types)
746        Atoms.SetTable(atomTable, True)
747        Atoms.Bind(wg.EVT_GRID_CELL_CHANGE, ChangeAtomCell)
748        Atoms.Bind(wg.EVT_GRID_CELL_LEFT_DCLICK, AtomTypeSelect)
749        Atoms.Bind(wg.EVT_GRID_LABEL_LEFT_DCLICK, RefreshAtomGrid)
750        Atoms.Bind(wg.EVT_GRID_LABEL_LEFT_CLICK, RowSelect)
751        Atoms.Bind(wg.EVT_GRID_LABEL_RIGHT_CLICK, ChangeSelection)
752        Atoms.SetMargins(0,0)
753        Atoms.AutoSizeColumns(False)
754        colType = colLabels.index('Type')
755        colSS = colLabels.index('site sym')
756        colIA = colLabels.index('I/A')
757        colU11 = colLabels.index('U11')
758        colUiso = colLabels.index('Uiso')
759        for i in range(colU11-1,colU11+6):
760            Atoms.SetColSize(i,50)           
761        for row in range(Atoms.GetNumberRows()):
762            Atoms.SetReadOnly(row,colType,True)
763            Atoms.SetReadOnly(row,colSS,True)                         #site sym
764            Atoms.SetReadOnly(row,colSS+1,True)                       #Mult
765            if Atoms.GetCellValue(row,colIA) == 'A':
766                CSI = G2spc.GetCSuinel(atomData[row][colLabels.index('site sym')])
767                Atoms.SetCellStyle(row,colUiso,VERY_LIGHT_GREY,True)
768                Atoms.SetCellTextColour(row,colUiso,VERY_LIGHT_GREY)
769                for i in range(6):
770                    ci = colU11+i
771                    Atoms.SetCellTextColour(row,ci,BLACK)
772                    Atoms.SetCellStyle(row,ci,VERY_LIGHT_GREY,True)
773                    if CSI[2][i]:
774                        Atoms.SetCellStyle(row,ci,WHITE,False)
775            else:
776                Atoms.SetCellStyle(row,colUiso,WHITE,False)
777                Atoms.SetCellTextColour(row,colUiso,BLACK)
778                for i in range(6):
779                    ci = colU11+i
780                    Atoms.SetCellStyle(row,ci,VERY_LIGHT_GREY,True)
781                    Atoms.SetCellTextColour(row,ci,VERY_LIGHT_GREY)
782
783    def OnAtomAdd(event):
784        AtomAdd(0,0,0)
785        FillAtomsGrid()
786        event.StopPropagation()
787       
788    def OnAtomTestAdd(event):
789        try:
790            drawData = data['Drawing']
791            x,y,z = drawData['testPos'][0]
792            AtomAdd(x,y,z)
793        except:
794            AtomAdd(0,0,0)
795        FillAtomsGrid()
796        event.StopPropagation()
797               
798    def AtomAdd(x,y,z):
799        atomData = data['Atoms']
800        generalData = data['General']
801        Ncol = Atoms.GetNumberCols()
802        atId = ran.randint(0,sys.maxint)
803        E,SGData = G2spc.SpcGroup(generalData['SGData']['SpGrp'])
804        Sytsym,Mult = G2spc.SytSym([x,y,z],SGData)
805        if generalData['Type'] == 'macromolecular':
806            atomData.append([0,'UNK','','UNK','H','',x,y,z,1,Sytsym,Mult,'I',0.10,0,0,0,0,0,0,atId])
807        elif generalData['Type'] == 'nuclear':
808            atomData.append(['UNK','H','',x,y,z,1,Sytsym,Mult,'I',0.01,0,0,0,0,0,0,atId])
809        elif generalData['Type'] == 'magnetic':
810            atomData.append(['UNK','H','',x,y,z,1,Sytsym,Mult,0,'I',0.01,0,0,0,0,0,0,0,0,0,atId])
811        SetupGeneral()
812        if 'Atoms' in data['Drawing']:           
813            DrawAtomAdd(data['Drawing'],atomData[-1])
814            G2plt.PlotStructure(self,data)
815
816    def OnAtomInsert(event):
817        AtomInsert(0,0,0)
818        FillAtomsGrid()
819        event.StopPropagation()
820       
821    def OnAtomTestInsert(event):
822        if 'Drawing' in data:
823            drawData = data['Drawing']
824            x,y,z = drawData['testPos'][0]
825            AtomAdd(x,y,z)
826            FillAtomsGrid()
827        event.StopPropagation()
828           
829    def AtomInsert(x,y,z):
830        indx = Atoms.GetSelectedRows()
831        if indx:
832            indx = indx[0]
833            atomData = data['Atoms']
834            generalData = data['General']
835            Ncol = Atoms.GetNumberCols()
836            E,SGData = G2spc.SpcGroup(generalData['SGData']['SpGrp'])
837            Sytsym,Mult = G2spc.SytSym([0,0,0],SGData)
838            atId = ran.randint(0,sys.maxint)
839            if generalData['Type'] == 'macromolecular':
840                atomData.insert(indx,[0,'UNK','','UNK','UNK','',x,y,z,1,Sytsym,Mult,'I',0.10,0,0,0,0,0,0,atId])
841            elif generalData['Type'] == 'nuclear':
842                atomData.insert(indx,['UNK','UNK','',x,y,z,1,Sytsym,Mult,'I',0.01,0,0,0,0,0,0,atId])
843            elif generalData['Type'] == 'magnetic':
844                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])
845            SetupGeneral()
846
847    def AtomDelete(event):
848        indx = Atoms.GetSelectedRows()
849        IDs = []
850        if indx:
851            atomData = data['Atoms']
852            indx.reverse()
853            for ind in indx:
854                atom = atomData[ind]
855                IDs.append(atom[-1])
856                del atomData[ind]
857            if 'Atoms' in data['Drawing']:
858                DrawAtomsDeleteByIDs(IDs)
859                FillAtomsGrid()
860                G2plt.PlotStructure(self,data)
861        event.StopPropagation()
862
863    def AtomRefine(event):
864        colLabels = [Atoms.GetColLabelValue(c) for c in range(Atoms.GetNumberCols())]
865        c = colLabels.index('refine')
866        indx = Atoms.GetSelectedRows()
867        if indx:
868            atomData = data['Atoms']
869            generalData = data['General']
870            Type = generalData['Type']
871            if Type in ['nuclear','macromolecular']:
872                choice = ['F - site fraction','X - coordinates','U - thermal parameters']
873            elif Type == 'magnetic':
874                choice = ['F - site fraction','X - coordinates','U - thermal parameters','M - magnetic moment']
875            dlg = wx.MultiChoiceDialog(self,'Select','Refinement controls',choice)
876            if dlg.ShowModal() == wx.ID_OK:
877                sel = dlg.GetSelections()
878                parms = ''
879                for x in sel:
880                    parms += choice[x][0]
881                for r in indx:
882                    atomData[r][c] = parms
883                Atoms.ForceRefresh()
884            dlg.Destroy()
885
886    def AtomModify(event):                  #intent to implement global modifications (+,-,*,/, etc.)?
887        indx = Atoms.GetSelectedRows()
888        if indx:
889            atomData = data['Atoms']
890            generalData = data['General']
891
892    def AtomTransform(event):
893        indx = Atoms.GetSelectedRows()
894        if indx:
895            colLabels = [Atoms.GetColLabelValue(c) for c in range(Atoms.GetNumberCols())]
896            cx = colLabels.index('x')
897            cuia = colLabels.index('I/A')
898            cuij = colLabels.index('U11')
899            css = colLabels.index('site sym')
900            atomData = data['Atoms']
901            generalData = data['General']
902            SGData = generalData['SGData']
903            dlg = SymOpDialog(self,SGData,True)
904            try:
905                if dlg.ShowModal() == wx.ID_OK:
906                    Inv,Cent,Opr,Cell,New = dlg.GetSelection()
907                    Cell = np.array(Cell)
908                    cent = SGData['SGCen'][Cent]
909                    M,T = SGData['SGOps'][Opr]
910                    for ind in indx:
911                        XYZ = np.array(atomData[ind][cx:cx+3])
912                        XYZ = np.inner(M,XYZ)+T
913                        if Inv:
914                            XYZ = -XYZ
915                        XYZ = XYZ+cent+Cell
916                        if New:
917                            atom = copy.copy(atomData[ind])
918                        else:
919                            atom = atomData[ind]
920                        atom[cx:cx+3] = XYZ
921                        atom[css:css+2] = G2spc.SytSym(XYZ,SGData)
922                        if atom[cuia] == 'A':
923                            Uij = atom[cuij:cuij+6]
924                            U = G2spc.Uij2U(Uij)
925                            U = np.inner(np.inner(M,U),M)
926                            Uij = G2spc.U2Uij(U)
927                            atom[cuij:cuij+6] = Uij
928                        if New:
929                            atomData.append(atom)
930            finally:
931                dlg.Destroy()
932            Atoms.ClearSelection()
933            if New:
934                FillAtomsGrid()
935            else:
936                Atoms.ForceRefresh()
937               
938#Structure drawing GUI stuff               
939
940    def SetupDrawingData():
941        generalData = data['General']
942        atomData = data['Atoms']
943        AA3letter = ['ALA','ARG','ASN','ASP','CYS','GLN','GLU','GLY','HIS','ILE',
944            'LEU','LYS','MET','PHE','PRO','SER','THR','TRP','TYR','VAL','MSE','HOH','WAT','UNK']
945        AA1letter = ['A','R','N','D','C','Q','E','G','H','I',
946            'L','K','M','F','P','S','T','W','Y','V','M',' ',' ',' ']
947        defaultDrawing = {'viewPoint':[[0.5,0.5,0.5],[]],'showHydrogen':True,'backColor':[0,0,0],'depthFog':False,
948            'Zclip':50.0,'cameraPos':50.,'radiusFactor':0.85,
949            'bondRadius':0.1,'ballScale':0.33,'vdwScale':0.67,'ellipseProb':50,'sizeH':0.50,
950            'unitCellBox':False,'showABC':True,'selectedAtoms':[],
951            'Rotation':[0.0,0.0,0.0,[]],'bondList':{},'testPos':[[-.1,-.1,-.1],[0.0,0.0,0.0],[0,0]]}
952        try:
953            drawingData = data['Drawing']
954        except KeyError:
955            data['Drawing'] = {}
956            drawingData = data['Drawing']
957        if not drawingData:                 #fill with defaults if empty
958            drawingData = copy.copy(defaultDrawing)
959            drawingData['Atoms'] = []
960        cx,ct,cs = [0,0,0]
961        if generalData['Type'] == 'nuclear':
962            cx,ct,cs = [2,1,6]         #x, type & style
963        elif generalData['Type'] == 'macromolecular':
964            cx,ct,cs = [5,4,9]         #x, type & style
965        elif generalData['Type'] == 'magnetic':
966            cx,ct,cs = [2,1,6]         #x, type & style
967#        elif generalData['Type'] == 'modulated':
968#           ?????   for future
969        if not drawingData['Atoms']:
970            for atom in atomData:
971                DrawAtomAdd(drawingData,atom)
972            drawingData['atomPtrs'] = [cx,ct,cs]
973            data['Drawing'] = drawingData
974           
975    def MakeDrawAtom(atom,oldatom=None):
976        AA3letter = ['ALA','ARG','ASN','ASP','CYS','GLN','GLU','GLY','HIS','ILE',
977            'LEU','LYS','MET','PHE','PRO','SER','THR','TRP','TYR','VAL','MSE','HOH','WAT','UNK']
978        AA1letter = ['A','R','N','D','C','Q','E','G','H','I',
979            'L','K','M','F','P','S','T','W','Y','V','M',' ',' ',' ']
980        generalData = data['General']
981        SGData = generalData['SGData']
982        if generalData['Type'] == 'nuclear':
983            if oldatom:
984                opr = oldatom[5]
985                if atom[9] == 'A':                   
986                    X,U = G2spc.ApplyStringOps(opr,SGData,atom[3:6],atom[11:17])
987                    atomInfo = [atom[:2]+list(X)+oldatom[5:9]+atom[9:11]+list(U)+oldatom[17:]][0]
988                else:
989                    X = G2spc.ApplyStringOps(opr,SGData,atom[3:6])
990                    atomInfo = [atom[:2]+list(X)+oldatom[5:9]+atom[9:]+[oldatom[-1]]][0]
991            else:
992                atomInfo = [atom[:2]+atom[3:6]+['1',]+['vdW balls',]+
993                    ['',]+[[255,255,255],]+atom[9:]+[[],[]]][0]
994            ct,cs = [1,8]         #type & color
995        elif generalData['Type'] == 'macromolecular':
996            try:
997                oneLetter = AA3letter.index(atom[1])
998            except ValueError:
999                oneLetter = -1
1000            atomInfo = [[atom[1].strip()+atom[0],]+
1001                [AA1letter[oneLetter]+atom[0],]+atom[2:5]+
1002                atom[6:9]+['1',]+['sticks',]+['',]+[[255,255,255],]+atom[12:]+[[],[]]][0]
1003            ct,cs = [4,11]         #type & color
1004        elif generalData['Type'] == 'magnetic':
1005            if oldatom:
1006                atomInfo = [atom[:2]+oldatom[3:]][0]
1007            else:
1008                atomInfo = [atom[:2]+atom[3:6]+['vdW balls',]+['',]+atom[9:]+[[],[]]][0]
1009            ct,cs = [1,8]         #type & color
1010#        elif generalData['Type'] == 'modulated':
1011#           ?????   for future
1012        atNum = generalData['AtomTypes'].index(atom[ct])
1013        atomInfo[cs] = list(generalData['Color'][atNum])
1014        return atomInfo
1015           
1016    def DrawAtomAdd(drawingData,atom):
1017        drawingData['Atoms'].append(MakeDrawAtom(atom))
1018       
1019    def DrawAtomsReplaceByID(drawingData,atom,ID):
1020        IDs = [ID,]
1021        atomData = drawingData['Atoms']
1022        indx = FindAtomIndexByIDs(atomData,IDs)
1023        for ind in indx:
1024            atomData[ind] = MakeDrawAtom(atom,atomData[ind])
1025           
1026    def UpdateDrawAtoms():
1027        generalData = data['General']
1028        SetupDrawingData()
1029        drawingData = data['Drawing']
1030        cx,ct,cs = drawingData['atomPtrs']
1031        atomData = drawingData['Atoms']
1032        Types = [wg.GRID_VALUE_STRING,wg.GRID_VALUE_STRING,]+3*[wg.GRID_VALUE_FLOAT+':10,5',]+ \
1033            [wg.GRID_VALUE_STRING,wg.GRID_VALUE_CHOICE+": ,lines,vdW balls,sticks,balls & sticks,ellipsoids,polyhedra",
1034            wg.GRID_VALUE_CHOICE+": ,type,name,number",wg.GRID_VALUE_STRING,wg.GRID_VALUE_STRING,]
1035        styleChoice = [' ','lines','vdW balls','sticks','balls & sticks','ellipsoids','polyhedra']
1036        labelChoice = [' ','type','name','number']
1037        colLabels = ['Name','Type','x','y','z','Sym Op','Style','Label','Color','I/A']
1038        if generalData['Type'] == 'macromolecular':
1039            colLabels = ['Residue','1-letter','Chain'] + colLabels
1040            Types = 3*[wg.GRID_VALUE_STRING,]+Types
1041            Types[8] = wg.GRID_VALUE_CHOICE+": ,lines,vdW balls,sticks,balls & sticks,ellipsoids,backbone,ribbons,schematic"
1042            styleChoice = [' ','lines','vdW balls','sticks','balls & sticks','ellipsoids','backbone','ribbons','schematic']
1043            labelChoice = [' ','type','name','number','residue','1-letter','chain']
1044            Types[9] = wg.GRID_VALUE_CHOICE+": ,type,name,number,residue,1-letter,chain"
1045#        elif generalData['Type'] == 'modulated':
1046#            Types += []
1047#            colLabels += []
1048
1049        def RefreshAtomGrid(event):
1050
1051            def SetChoice(name,c,n=0):
1052                choice = []
1053                for r in range(len(atomData)):
1054                    if n:
1055                        srchStr = str(atomData[r][c][:n])
1056                    else:
1057                        srchStr = str(atomData[r][c])
1058                    if srchStr not in choice:
1059                        if n:
1060                            choice.append(str(atomData[r][c][:n]))
1061                        else:
1062                            choice.append(str(atomData[r][c]))
1063                choice.sort()
1064
1065                dlg = wx.MultiChoiceDialog(self,'Select',name,choice)
1066                if dlg.ShowModal() == wx.ID_OK:
1067                    sel = dlg.GetSelections()
1068                    parms = []
1069                    for x in sel:
1070                        parms.append(choice[x])
1071                    noSkip = False
1072                    drawAtoms.ClearSelection()
1073                    drawingData['selectedAtoms'] = []
1074                    for row in range(len(atomData)):
1075                        test = atomData[row][c]
1076                        if n:
1077                            test = test[:n]
1078                        if  test in parms:
1079                            drawAtoms.SelectRow(row,True)
1080                            drawingData['selectedAtoms'].append(row)
1081                    G2plt.PlotStructure(self,data)                   
1082                dlg.Destroy()
1083               
1084            r,c =  event.GetRow(),event.GetCol()
1085            if r < 0 and c < 0:
1086                for row in range(drawAtoms.GetNumberRows()):
1087                    drawingData['selectedAtoms'].append(row)
1088                    drawAtoms.SelectRow(row,True)                   
1089            elif r < 0:                          #dclick on col label
1090                sel = -1
1091                Parms = False
1092                noSkip = True
1093                if drawAtoms.GetColLabelValue(c) == 'Style':
1094                    dlg = wx.SingleChoiceDialog(self,'Select','Atom drawing style',styleChoice)
1095                    if dlg.ShowModal() == wx.ID_OK:
1096                        sel = dlg.GetSelection()
1097                        parms = styleChoice[sel]
1098                        for r in range(len(atomData)):
1099                            atomData[r][c] = parms
1100                            drawAtoms.SetCellValue(r,c,parms)
1101                        FindBonds()
1102                        G2plt.PlotStructure(self,data)
1103                    dlg.Destroy()
1104                elif drawAtoms.GetColLabelValue(c) == 'Label':
1105                    dlg = wx.SingleChoiceDialog(self,'Select','Atom labelling style',labelChoice)
1106                    if dlg.ShowModal() == wx.ID_OK:
1107                        sel = dlg.GetSelection()
1108                        parms = labelChoice[sel]
1109                        for r in range(len(atomData)):
1110                            atomData[r][c] = parms
1111                            drawAtoms.SetCellValue(r,c,parms)
1112                    dlg.Destroy()                   
1113                elif drawAtoms.GetColLabelValue(c) == 'Color':
1114                    dlg = wx.ColourDialog(self)
1115                    if dlg.ShowModal() == wx.ID_OK:
1116                        color = dlg.GetColourData().GetColour()
1117                        attr = wg.GridCellAttr()                #needs to be here - gets lost if outside loop!
1118                        attr.SetReadOnly(True)
1119                        attr.SetBackgroundColour(color)
1120                        for r in range(len(atomData)):
1121                            atomData[r][c] = color
1122                            drawingData['Atoms'][r][c] = color
1123                            drawAtoms.SetAttr(r,c,attr)
1124                        UpdateDrawAtoms()
1125                    dlg.Destroy()
1126                elif drawAtoms.GetColLabelValue(c) == 'Residue':
1127                    SetChoice('Residue',c,3)
1128                elif drawAtoms.GetColLabelValue(c) == '1-letter':
1129                    SetChoice('1-letter',c,1)
1130                elif drawAtoms.GetColLabelValue(c) == 'Chain':
1131                    SetChoice('Chain',c)
1132                elif drawAtoms.GetColLabelValue(c) == 'Name':
1133                    SetChoice('Name',c)
1134                elif drawAtoms.GetColLabelValue(c) == 'Sym Op':
1135                    SetChoice('Name',c)
1136                elif drawAtoms.GetColLabelValue(c) == 'Type':
1137                    SetChoice('Type',c)
1138                elif drawAtoms.GetColLabelValue(c) in ['x','y','z','I/A']:
1139                    drawAtoms.ClearSelection()
1140            else:
1141                if drawAtoms.GetColLabelValue(c) in ['Style','Label']:
1142                    atomData[r][c] = drawAtoms.GetCellValue(r,c)
1143                    FindBonds()
1144                elif drawAtoms.GetColLabelValue(c) == 'Color':
1145                    color = atomData[r][c]
1146                    colors = wx.ColourData()
1147                    colors.SetChooseFull(True)
1148                    colors.SetCustomColour(0,color)
1149                    colors.SetColour(color)
1150                    dlg = wx.ColourDialog(self,colors)
1151                    dlg.GetColourData().SetCustomColour(0,color)
1152                    if dlg.ShowModal() == wx.ID_OK:
1153                        color = dlg.GetColourData().GetColour()
1154                        attr = wg.GridCellAttr()                #needs to be here - gets lost if outside loop!
1155                        attr.SetReadOnly(True)
1156                        attr.SetBackgroundColour(color)
1157                        atomData[r][c] = color
1158                        drawingData['Atoms'][r][c] = color
1159                        drawAtoms.SetAttr(i,cs+2,attr)
1160                    dlg.Destroy()
1161                    event.StopPropagation()
1162                    UpdateDrawAtoms()
1163            G2plt.PlotStructure(self,data)
1164                   
1165        def RowSelect(event):
1166            r,c =  event.GetRow(),event.GetCol()
1167            if r < 0 and c < 0:
1168                if drawAtoms.IsSelection():
1169                    drawAtoms.ClearSelection()
1170            elif c < 0:                   #only row clicks
1171                if event.ControlDown():                   
1172                    if r in drawAtoms.GetSelectedRows():
1173                        drawAtoms.DeselectRow(r)
1174                    else:
1175                        drawAtoms.SelectRow(r,True)
1176                elif event.ShiftDown():
1177                    for row in range(r+1):
1178                        drawAtoms.SelectRow(row,True)
1179                else:
1180                    drawAtoms.ClearSelection()
1181                    drawAtoms.SelectRow(r,True)               
1182            drawingData['selectedAtoms'] = []
1183            drawingData['selectedAtoms'] = drawAtoms.GetSelectedRows()
1184            G2plt.PlotStructure(self,data)                   
1185               
1186        table = []
1187        rowLabels = []
1188        for i,atom in enumerate(drawingData['Atoms']):
1189            table.append(atom[:colLabels.index('I/A')+1])
1190            rowLabels.append(str(i))
1191
1192        atomTable = G2gd.Table(table,rowLabels=rowLabels,colLabels=colLabels,types=Types)
1193        drawAtoms.SetTable(atomTable, True)
1194        drawAtoms.SetMargins(0,0)
1195        drawAtoms.AutoSizeColumns(True)
1196        drawAtoms.SetColSize(colLabels.index('Style'),80)
1197        drawAtoms.SetColSize(colLabels.index('Color'),50)
1198        drawAtoms.Bind(wg.EVT_GRID_CELL_CHANGE, RefreshAtomGrid)
1199        drawAtoms.Bind(wg.EVT_GRID_LABEL_LEFT_DCLICK, RefreshAtomGrid)
1200        drawAtoms.Bind(wg.EVT_GRID_CELL_LEFT_DCLICK, RefreshAtomGrid)
1201        drawAtoms.Bind(wg.EVT_GRID_LABEL_LEFT_CLICK, RowSelect)
1202        for i,atom in enumerate(drawingData['Atoms']):
1203            attr = wg.GridCellAttr()                #needs to be here - gets lost if outside loop!
1204            attr.SetReadOnly(True)
1205            attr.SetBackgroundColour(atom[cs+2])
1206            drawAtoms.SetAttr(i,cs+2,attr)
1207            drawAtoms.SetCellValue(i,cs+2,'')
1208        indx = drawingData['selectedAtoms']
1209        if indx:
1210            for r in range(len(atomData)):
1211                if r in indx:
1212                    drawAtoms.SelectRow(r)
1213        for c in range(len(colLabels)):
1214           attr = wg.GridCellAttr()                #needs to be here - gets lost if outside loop!
1215           attr.SetReadOnly(True)
1216           attr.SetBackgroundColour(VERY_LIGHT_GREY)
1217           if colLabels[c] not in ['Style','Label','Color']:
1218                drawAtoms.SetColAttr(c,attr)
1219        self.dataFrame.setSizePosLeft([600,300])
1220       
1221        FindBonds()
1222        drawAtoms.ClearSelection()
1223        G2plt.PlotStructure(self,data)
1224
1225    def DrawAtomStyle(event):
1226        indx = drawAtoms.GetSelectedRows()
1227        if indx:
1228            generalData = data['General']
1229            atomData = data['Drawing']['Atoms']
1230            cx,ct,cs = data['Drawing']['atomPtrs']
1231            styleChoice = [' ','lines','vdW balls','sticks','balls & sticks','ellipsoids','polyhedra']
1232            if generalData['Type'] == 'macromolecular':
1233                styleChoice = [' ','lines','vdW balls','sticks','balls & sticks','ellipsoids',
1234                'backbone','ribbons','schematic']
1235            dlg = wx.SingleChoiceDialog(self,'Select','Atom drawing style',styleChoice)
1236            if dlg.ShowModal() == wx.ID_OK:
1237                sel = dlg.GetSelection()
1238                parms = styleChoice[sel]
1239                for r in indx:
1240                    atomData[r][cs] = parms
1241                    drawAtoms.SetCellValue(r,cs,parms)
1242            dlg.Destroy()
1243            FindBonds()
1244            drawAtoms.ClearSelection()
1245            G2plt.PlotStructure(self,data)
1246
1247    def DrawAtomLabel(event):
1248        indx = drawAtoms.GetSelectedRows()
1249        if indx:
1250            generalData = data['General']
1251            atomData = data['Drawing']['Atoms']
1252            cx,ct,cs = data['Drawing']['atomPtrs']
1253            styleChoice = [' ','type','name','number']
1254            if generalData['Type'] == 'macromolecular':
1255                styleChoice = [' ','type','name','number','residue','1-letter','chain']
1256            dlg = wx.SingleChoiceDialog(self,'Select','Atom label style',styleChoice)
1257            if dlg.ShowModal() == wx.ID_OK:
1258                sel = dlg.GetSelection()
1259                parms = styleChoice[sel]
1260                for r in indx:
1261                    atomData[r][cs+1] = parms
1262                    drawAtoms.SetCellValue(r,cs+1,parms)
1263            dlg.Destroy()
1264            drawAtoms.ClearSelection()
1265            G2plt.PlotStructure(self,data)
1266           
1267    def DrawAtomColor(event):
1268
1269        indx = drawAtoms.GetSelectedRows()
1270        if indx:
1271            if len(indx) > 1:
1272                self.dataFrame.SetStatusText('Select Custom Color, change color, Add to Custom Colors, then OK')
1273            else:
1274                self.dataFrame.SetStatusText('Change color, Add to Custom Colors, then OK')
1275            generalData = data['General']
1276            atomData = data['Drawing']['Atoms']
1277            cx,ct,cs = data['Drawing']['atomPtrs']
1278            atmColors = []
1279            atmTypes = []
1280            for r in indx:
1281                if atomData[r][cs+2] not in atmColors:
1282                    atmColors.append(atomData[r][cs+2])
1283                    atmTypes.append(atomData[r][ct])
1284                    if len(atmColors) > 16:
1285                        break
1286            colors = wx.ColourData()
1287            colors.SetChooseFull(True)
1288            for i,color in enumerate(atmColors):
1289                colors.SetCustomColour(i,color)
1290            dlg = wx.ColourDialog(self,colors)
1291            if dlg.ShowModal() == wx.ID_OK:
1292                for i in range(len(atmColors)):                   
1293                    atmColors[i] = dlg.GetColourData().GetCustomColour(i)
1294                colorDict = dict(zip(atmTypes,atmColors))
1295                for r in indx:
1296                    color = colorDict[atomData[r][ct]]
1297                    atomData[r][cs+2] = color
1298                    attr = wg.GridCellAttr()                #needs to be here - gets lost if outside loop!
1299                    attr.SetBackgroundColour(color)
1300                    drawAtoms.SetAttr(r,cs+2,attr)
1301                    data['Drawing']['Atoms'][r][cs+2] = color
1302            drawAtoms.ClearSelection()
1303            dlg.Destroy()
1304            self.dataFrame.SetStatusText('')
1305           
1306    def ResetAtomColors(event):
1307        generalData = data['General']
1308        atomData = data['Drawing']['Atoms']
1309        cx,ct,cs = data['Drawing']['atomPtrs']
1310        for atom in atomData:           
1311            atNum = generalData['AtomTypes'].index(atom[ct])
1312            atom[cs+2] = list(generalData['Color'][atNum])
1313        UpdateDrawAtoms()
1314        drawAtoms.ClearSelection()
1315        G2plt.PlotStructure(self,data)       
1316       
1317    def SetViewPoint(event):
1318        indx = drawAtoms.GetSelectedRows()
1319        if indx:
1320            atomData = data['Drawing']['Atoms']
1321            cx = data['Drawing']['atomPtrs'][0]
1322            data['Drawing']['viewPoint'] = [atomData[indx[0]][cx:cx+3],[indx[0],0]]
1323            drawAtoms.ClearSelection()                                  #do I really want to do this?
1324            G2plt.PlotStructure(self,data)
1325           
1326    def noDuplicate(xyz,atomData):                  #be careful where this is used - it's slow
1327        cx = data['Drawing']['atomPtrs'][0]
1328        if True in [np.allclose(np.array(xyz),np.array(atom[cx:cx+3]),atol=0.0002) for atom in atomData]:
1329            return False
1330        else:
1331            return True
1332               
1333    def AddSymEquiv(event):
1334        indx = drawAtoms.GetSelectedRows()
1335        indx.sort()
1336        if indx:
1337            colLabels = [drawAtoms.GetColLabelValue(c) for c in range(drawAtoms.GetNumberCols())]
1338            cx = colLabels.index('x')
1339            cuia = colLabels.index('I/A')
1340            cuij = cuia+2
1341            atomData = data['Drawing']['Atoms']
1342            generalData = data['General']
1343            SGData = generalData['SGData']
1344            dlg = SymOpDialog(self,SGData,False)
1345            try:
1346                if dlg.ShowModal() == wx.ID_OK:
1347                    Inv,Cent,Opr,Cell,New = dlg.GetSelection()
1348                    Cell = np.array(Cell)
1349                    cent = SGData['SGCen'][Cent]
1350                    M,T = SGData['SGOps'][Opr]
1351                    for ind in indx:
1352                        XYZ = np.array(atomData[ind][cx:cx+3])
1353                        XYZ = np.inner(M,XYZ)+T
1354                        if Inv:
1355                            XYZ = -XYZ
1356                        XYZ = XYZ+cent+Cell
1357                        if noDuplicate(XYZ,atomData):
1358                            atom = copy.copy(atomData[ind])
1359                            atom[cx:cx+3] = XYZ
1360                            atomOp = atom[cx+3]
1361                            newOp = str(((Opr+1)+100*Cent)*(1-2*Inv))+'+'+ \
1362                                str(int(Cell[0]))+','+str(int(Cell[1]))+','+str(int(Cell[2]))                           
1363                            atom[cx+3] = G2spc.StringOpsProd(atomOp,newOp,SGData)
1364                            if atom[cuia] == 'A':
1365                                Uij = atom[cuij:cuij+6]
1366                                U = G2spc.Uij2U(Uij)
1367                                U = np.inner(np.inner(M,U),M)
1368                                Uij = G2spc.U2Uij(U)
1369                                atom[cuij:cuij+6] = Uij
1370                            atomData.append(atom)
1371            finally:
1372                dlg.Destroy()
1373            UpdateDrawAtoms()
1374            drawAtoms.ClearSelection()
1375            G2plt.PlotStructure(self,data)
1376           
1377    def TransformSymEquiv(event):
1378        indx = drawAtoms.GetSelectedRows()
1379        indx.sort()
1380        if indx:
1381            atomData = data['Drawing']['Atoms']
1382            colLabels = [drawAtoms.GetColLabelValue(c) for c in range(drawAtoms.GetNumberCols())]
1383            cx = colLabels.index('x')
1384            cuia = colLabels.index('I/A')
1385            cuij = cuia+2
1386            atomData = data['Drawing']['Atoms']
1387            generalData = data['General']
1388            SGData = generalData['SGData']
1389            dlg = SymOpDialog(self,SGData,False)
1390            try:
1391                if dlg.ShowModal() == wx.ID_OK:
1392                    Inv,Cent,Opr,Cell,New = dlg.GetSelection()
1393                    Cell = np.array(Cell)
1394                    cent = SGData['SGCen'][Cent]
1395                    M,T = SGData['SGOps'][Opr]
1396                    for ind in indx:
1397                        XYZ = np.array(atomData[ind][cx:cx+3])
1398                        XYZ = np.inner(M,XYZ)+T
1399                        if Inv:
1400                            XYZ = -XYZ
1401                        XYZ = XYZ+cent+Cell
1402                        atom = atomData[ind]
1403                        atom[cx:cx+3] = XYZ
1404                        atomOp = atom[cx+3]
1405                        newOp = str(((Opr+1)+100*Cent)*(1-2*Inv))+'+'+ \
1406                            str(int(Cell[0]))+','+str(int(Cell[1]))+','+str(int(Cell[2]))
1407                        atom[cx+3] = G2spc.StringOpsProd(atomOp,newOp,SGData)
1408                        if atom[cuia] == 'A':
1409                            Uij = atom[cuij:cuij+6]
1410                            U = G2spc.Uij2U(Uij)
1411                            U = np.inner(np.inner(M,U),M)
1412                            Uij = G2spc.U2Uij(U)
1413                            atom[cuij:cuij+6] = Uij
1414                    data['Drawing']['Atoms'] = atomData
1415            finally:
1416                dlg.Destroy()
1417            UpdateDrawAtoms()
1418            drawAtoms.ClearSelection()
1419            G2plt.PlotStructure(self,data)
1420           
1421    def FillCoordSphere(event):
1422        generalData = data['General']
1423        Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7])
1424        radii = generalData['BondRadii']
1425        atomTypes = generalData['AtomTypes']
1426        try:
1427            indH = atomTypes.index('H')
1428            radii[indH] = 0.5
1429        except:
1430            pass           
1431        indx = drawAtoms.GetSelectedRows()
1432        if indx:
1433            indx.sort()
1434            atomData = data['Drawing']['Atoms']
1435            numAtoms = len(atomData)
1436            cx,ct,cs = data['Drawing']['atomPtrs']
1437            generalData = data['General']
1438            SGData = generalData['SGData']
1439            cellArray = G2lat.CellBlock(1)
1440            for ind in indx:
1441                atomA = atomData[ind]
1442                xyzA = np.array(atomA[cx:cx+3])
1443                indA = atomTypes.index(atomA[ct])
1444                for atomB in atomData[:numAtoms]:
1445                    indB = atomTypes.index(atomB[ct])
1446                    sumR = radii[indA]+radii[indB]
1447                    xyzB = np.array(atomB[cx:cx+3])
1448                    for xyz in cellArray+xyzB:
1449                        dist = np.sqrt(np.sum(np.inner(Amat,xyz-xyzA)**2))
1450                        if 0 < dist <= data['Drawing']['radiusFactor']*sumR:
1451                            if noDuplicate(xyz,atomData):
1452                                oprB = atomB[cx+3]
1453                                C = xyz-xyzB
1454                                newOp = '1+'+str(int(round(C[0])))+','+str(int(round(C[1])))+','+str(int(round(C[2])))
1455                                newAtom = atomB[:]
1456                                newAtom[cx:cx+3] = xyz
1457                                newAtom[cx+3] = G2spc.StringOpsProd(oprB,newOp,SGData)
1458                                atomData.append(newAtom)
1459            data['Drawing']['Atoms'] = atomData
1460            UpdateDrawAtoms()
1461            drawAtoms.ClearSelection()
1462            G2plt.PlotStructure(self,data)
1463           
1464    def FillUnitCell(event):
1465        indx = drawAtoms.GetSelectedRows()
1466        indx.sort()
1467        if indx:
1468            atomData = data['Drawing']['Atoms']
1469            colLabels = [drawAtoms.GetColLabelValue(c) for c in range(drawAtoms.GetNumberCols())]
1470            cx = colLabels.index('x')
1471            cuia = colLabels.index('I/A')
1472            cuij = cuia+2
1473            generalData = data['General']
1474            SGData = generalData['SGData']
1475            for ind in indx:
1476                atom = atomData[ind]
1477                XYZ = np.array(atom[cx:cx+3])
1478                if atom[cuia] == 'A':
1479                    Uij = atom[cuij:cuij+6]
1480                    result = G2spc.GenAtom(XYZ,SGData,False,Uij)
1481                    for item in result:
1482                        atom = copy.copy(atomData[ind])
1483                        atom[cx:cx+3] = item[0]
1484                        atom[cx+3] = str(item[2])+'+' \
1485                            +str(item[3][0])+','+str(item[3][1])+','+str(item[3][2])
1486                        atom[cuij:cuij+6] = item[1]
1487                        Opp = G2spc.Opposite(item[0])
1488                        for xyz in Opp:
1489                            if noDuplicate(xyz,atomData):
1490                                cell = np.asarray(np.rint(xyz-atom[cx:cx+3]),dtype=np.int32)
1491                                cell = '1'+'+'+ \
1492                                    str(cell[0])+','+str(cell[1])+','+str(cell[2])
1493                                atom[cx:cx+3] = xyz
1494                                atom[cx+3] = G2spc.StringOpsProd(cell,atom[cx+3],SGData)
1495                                atomData.append(atom[:])
1496                else:
1497                    result = G2spc.GenAtom(XYZ,SGData,False)
1498                    for item in result:
1499                        atom = copy.copy(atomData[ind])
1500                        atom[cx:cx+3] = item[0]
1501                        atom[cx+3] = str(item[1])+'+' \
1502                            +str(item[2][0])+','+str(item[2][1])+','+str(item[2][2])
1503                        Opp = G2spc.Opposite(item[0])
1504                        for xyz in Opp:
1505                            if noDuplicate(xyz,atomData):
1506                                cell = np.asarray(np.rint(xyz-atom[cx:cx+3]),dtype=np.int32)
1507                                cell = '1'+'+'+ \
1508                                    str(cell[0])+','+str(cell[1])+','+str(cell[2])
1509                                atom[cx:cx+3] = xyz
1510                                atom[cx+3] = G2spc.StringOpsProd(cell,atom[cx+3],SGData)
1511                                atomData.append(atom[:])               
1512                data['Drawing']['Atoms'] = atomData
1513            UpdateDrawAtoms()
1514            drawAtoms.ClearSelection()
1515            G2plt.PlotStructure(self,data)
1516           
1517    def FindBondsToo():                         #works but slow for large structures - keep as reference
1518        cx,ct,cs = data['Drawing']['atomPtrs']
1519        atomData = data['Drawing']['Atoms']
1520        generalData = data['General']
1521        Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7])
1522        radii = generalData['BondRadii']
1523        atomTypes = generalData['AtomTypes']
1524        try:
1525            indH = atomTypes.index('H')
1526            radii[indH] = 0.5
1527        except:
1528            pass           
1529        for atom in atomData:
1530            atom[-1] = []
1531        Atoms = []
1532        for i,atom in enumerate(atomData):
1533            Atoms.append([i,np.array(atom[cx:cx+3]),atom[cs],radii[atomTypes.index(atom[ct])]])
1534        for atomA in Atoms:
1535            if atomA[2] in ['lines','sticks','ellipsoids','balls & sticks','polyhedra']:
1536                for atomB in Atoms:                   
1537                    Dx = atomB[1]-atomA[1]
1538                    DX = np.inner(Amat,Dx)
1539                    dist = np.sqrt(np.sum(DX**2))
1540                    sumR = atomA[3]+atomB[3]
1541                    if 0.5 < dist <= 0.85*sumR:
1542                        i = atomA[0]
1543                        if atomA[2] == 'polyhedra':
1544                            atomData[i][-1].append(DX)
1545                        elif atomB[1] != 'polyhedra':
1546                            j = atomB[0]
1547                            atomData[i][-1].append(Dx*atomA[3]/sumR)
1548                            atomData[j][-1].append(-Dx*atomB[3]/sumR)
1549                   
1550    def FindBonds():                    #uses numpy & masks - very fast even for proteins!
1551        import numpy.ma as ma
1552        cx,ct,cs = data['Drawing']['atomPtrs']
1553        hydro = data['Drawing']['showHydrogen']
1554        atomData = data['Drawing']['Atoms']
1555        generalData = data['General']
1556        Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7])
1557        radii = generalData['BondRadii']
1558        atomTypes = generalData['AtomTypes']
1559        try:
1560            indH = atomTypes.index('H')
1561            radii[indH] = 0.5
1562        except:
1563            pass           
1564        for atom in atomData:
1565            atom[-2] = []               #clear out old bonds/polyhedra
1566            atom[-1] = []
1567        Indx = range(len(atomData))
1568        Atoms = []
1569        Styles = []
1570        Radii = []
1571        for atom in atomData:
1572            Atoms.append(np.array(atom[cx:cx+3]))
1573            Styles.append(atom[cs])
1574            try:
1575                if not hydro and atom[ct] == 'H':
1576                    Radii.append(0.0)
1577                else:
1578                    Radii.append(radii[atomTypes.index(atom[ct])])
1579            except ValueError:          #changed atom type!
1580                Radii.append(0.20)
1581        Atoms = np.array(Atoms)
1582        Radii = np.array(Radii)
1583        IASR = zip(Indx,Atoms,Styles,Radii)
1584        for atomA in IASR:
1585            if atomA[2] in ['lines','sticks','ellipsoids','balls & sticks','polyhedra']:
1586                Dx = Atoms-atomA[1]
1587                dist = ma.masked_less(np.sqrt(np.sum(np.inner(Amat,Dx)**2,axis=0)),0.5) #gets rid of self & disorder "bonds" < 0.5A
1588                sumR = atomA[3]+Radii
1589                IndB = ma.nonzero(ma.masked_greater(dist-data['Drawing']['radiusFactor']*sumR,0.))                 #get indices of bonded atoms
1590                i = atomA[0]
1591                for j in IndB[0]:
1592                    if Styles[i] == 'polyhedra':
1593                        atomData[i][-2].append(np.inner(Amat,Dx[j]))
1594                    elif Styles[j] != 'polyhedra' and j > i:
1595                        atomData[i][-2].append(Dx[j]*Radii[i]/sumR[j])
1596                        atomData[j][-2].append(-Dx[j]*Radii[j]/sumR[j])
1597                if Styles[i] == 'polyhedra':
1598                    Bonds = atomData[i][-2]
1599                    Faces = []
1600                    if len(Bonds) > 2:
1601                        FaceGen = G2lat.uniqueCombinations(Bonds,3)     #N.B. this is a generator
1602                        for face in FaceGen:
1603                            vol = nl.det(face)
1604                            if abs(vol) > 1. or len(Bonds) == 3:
1605                                if vol < 0.:
1606                                    face = [face[0],face[2],face[1]]
1607                                face = np.array(face)
1608                                if not np.array([np.array(nl.det(face-bond))+0.0001 < 0 for bond in Bonds]).any():
1609                                    norm = np.cross(face[1]-face[0],face[2]-face[0])
1610                                    norm /= np.sqrt(np.sum(norm**2))
1611                                    Faces.append([face,norm])
1612                        atomData[i][-1] = Faces
1613                       
1614    def DrawAtomsDelete(event):   
1615        indx = drawAtoms.GetSelectedRows()
1616        indx.sort()
1617        if indx:
1618            atomData = data['Drawing']['Atoms']
1619            indx.reverse()
1620            for ind in indx:
1621                del atomData[ind]
1622            UpdateDrawAtoms()
1623            drawAtoms.ClearSelection()
1624            G2plt.PlotStructure(self,data)
1625        event.StopPropagation()
1626       
1627    def OnReloadDrawAtoms(event):
1628        data['Drawing']['Atoms'] = []
1629        UpdateDrawAtoms()
1630        drawAtoms.ClearSelection()
1631        G2plt.PlotStructure(self,data)
1632        event.StopPropagation()
1633       
1634    def FindAtomIndexByIDs(atomData,IDs):
1635        indx = []
1636        for i,atom in enumerate(atomData):
1637            if atom[-2] in IDs:
1638                indx.append(i)
1639        return indx
1640       
1641    def DrawAtomsDeleteByIDs(IDs):
1642        atomData = data['Drawing']['Atoms']
1643        indx = FindAtomIndexByIDs(atomData,IDs)
1644        indx.reverse()
1645        for ind in indx:
1646            del atomData[ind]
1647           
1648    def ChangeDrawAtomsByIDs(colName,IDs,value):
1649        atomData = data['Drawing']['Atoms']
1650        cx,ct,cs = data['Drawing']['atomPtrs']
1651        if colName == 'Name':
1652            col = ct-1
1653        elif colName == 'Type':
1654            col = ct
1655        elif colName == 'I/A':
1656            col = cs
1657        indx = FindAtomIndexByIDs(atomData,IDs)
1658        for ind in indx:
1659            atomData[ind][col] = value
1660               
1661    def UpdateDrawOptions():
1662        import copy
1663        import wx.lib.colourselect as wcs
1664        generalData = data['General']
1665        SetupDrawingData()
1666        drawingData = data['Drawing']
1667        if generalData['Type'] == 'nuclear':
1668            pickChoice = ['Atoms','Bonds','Torsions','Planes']
1669        elif generalData['Type'] == 'macromolecular':
1670            pickChoice = ['Atoms','Residues','Chains','Bonds','Torsions','Planes','phi/psi']
1671
1672        def OnZclip(event):
1673            drawingData['Zclip'] = Zclip.GetValue()
1674            ZclipTxt.SetLabel('Z clipping: '+'%.2fA'%(drawingData['Zclip']*drawingData['cameraPos']/100.))
1675            G2plt.PlotStructure(self,data)
1676           
1677        def OnCameraPos(event):
1678            drawingData['cameraPos'] = cameraPos.GetValue()
1679            cameraPosTxt.SetLabel('Camera Distance: '+'%.2f'%(drawingData['cameraPos']))
1680            ZclipTxt.SetLabel('Z clipping: '+'%.2fA'%(drawingData['Zclip']*drawingData['cameraPos']/100.))
1681            G2plt.PlotStructure(self,data)
1682
1683        def OnBackColor(event):
1684            drawingData['backColor'] = event.GetValue()
1685            G2plt.PlotStructure(self,data)
1686
1687        def OnBallScale(event):
1688            drawingData['ballScale'] = ballScale.GetValue()/100.
1689            ballScaleTxt.SetLabel('Ball scale: '+'%.2f'%(drawingData['ballScale']))
1690            G2plt.PlotStructure(self,data)
1691
1692        def OnVdWScale(event):
1693            drawingData['vdwScale'] = vdwScale.GetValue()/100.
1694            vdwScaleTxt.SetLabel('van der Waals scale: '+'%.2f'%(drawingData['vdwScale']))
1695            G2plt.PlotStructure(self,data)
1696
1697        def OnEllipseProb(event):
1698            drawingData['ellipseProb'] = ellipseProb.GetValue()
1699            ellipseProbTxt.SetLabel('Ellipsoid probability: '+'%d%%'%(drawingData['ellipseProb']))
1700            G2plt.PlotStructure(self,data)
1701
1702        def OnBondRadius(event):
1703            drawingData['bondRadius'] = bondRadius.GetValue()/100.
1704            bondRadiusTxt.SetLabel('Bond radius, A: '+'%.2f'%(drawingData['bondRadius']))
1705            G2plt.PlotStructure(self,data)
1706
1707        def OnShowABC(event):
1708            drawingData['showABC'] = showABC.GetValue()
1709            G2plt.PlotStructure(self,data)
1710
1711        def OnShowUnitCell(event):
1712            drawingData['unitCellBox'] = unitCellBox.GetValue()
1713            G2plt.PlotStructure(self,data)
1714
1715        def OnShowHyd(event):
1716            drawingData['showHydrogen'] = showHydrogen.GetValue()
1717            FindBonds()
1718            G2plt.PlotStructure(self,data)
1719
1720        def OnSizeHatoms(event):
1721            try:
1722                value = max(0.1,min(1.2,float(sizeH.GetValue())))
1723            except ValueError:
1724                value = 0.5
1725            drawingData['sizeH'] = value
1726            sizeH.SetValue("%.2f"%(value))
1727            G2plt.PlotStructure(self,data)
1728           
1729        def OnRadFactor(event):
1730            try:
1731                value = max(0.1,min(1.2,float(radFactor.GetValue())))
1732            except ValueError:
1733                value = 0.85
1734            drawingData['radiusFactor'] = value
1735            radFactor.SetValue("%.2f"%(value))
1736            FindBonds()
1737            G2plt.PlotStructure(self,data)
1738
1739        dataDisplay = wx.Panel(drawOptions)
1740        mainSizer = wx.BoxSizer(wx.VERTICAL)
1741        mainSizer.Add((5,5),0)
1742        mainSizer.Add(wx.StaticText(dataDisplay,-1,'Drawing controls:'),0,wx.ALIGN_CENTER_VERTICAL)
1743        mainSizer.Add((5,5),0)
1744       
1745        slopSizer = wx.BoxSizer(wx.HORIZONTAL)
1746        slideSizer = wx.FlexGridSizer(6,2)
1747        slideSizer.AddGrowableCol(1,1)
1748
1749        cameraPosTxt = wx.StaticText(dataDisplay,-1,
1750            'Camera Distance: '+'%.2f'%(drawingData['cameraPos']),name='cameraPos')
1751        slideSizer.Add(cameraPosTxt,0,wx.ALIGN_CENTER_VERTICAL)
1752        cameraPos = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=drawingData['cameraPos'],name='cameraSlider')
1753        cameraPos.SetRange(10,500)
1754        cameraPos.Bind(wx.EVT_SLIDER, OnCameraPos)
1755        slideSizer.Add(cameraPos,1,wx.EXPAND|wx.RIGHT)
1756       
1757        ZclipTxt = wx.StaticText(dataDisplay,-1,'Z clipping: '+'%.2fA'%(drawingData['Zclip']*drawingData['cameraPos']/100.))
1758        slideSizer.Add(ZclipTxt,0,wx.ALIGN_CENTER_VERTICAL)
1759        Zclip = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=drawingData['Zclip'])
1760        Zclip.SetRange(1,99)
1761        Zclip.Bind(wx.EVT_SLIDER, OnZclip)
1762        slideSizer.Add(Zclip,1,wx.EXPAND|wx.RIGHT)
1763       
1764        vdwScaleTxt = wx.StaticText(dataDisplay,-1,'van der Waals scale: '+'%.2f'%(drawingData['vdwScale']))
1765        slideSizer.Add(vdwScaleTxt,0,wx.ALIGN_CENTER_VERTICAL)
1766        vdwScale = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=int(100*drawingData['vdwScale']))
1767        vdwScale.Bind(wx.EVT_SLIDER, OnVdWScale)
1768        slideSizer.Add(vdwScale,1,wx.EXPAND|wx.RIGHT)
1769
1770        ellipseProbTxt = wx.StaticText(dataDisplay,-1,'Ellipsoid probability: '+'%d%%'%(drawingData['ellipseProb']))
1771        slideSizer.Add(ellipseProbTxt,0,wx.ALIGN_CENTER_VERTICAL)
1772        ellipseProb = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=drawingData['ellipseProb'])
1773        ellipseProb.SetRange(1,99)
1774        ellipseProb.Bind(wx.EVT_SLIDER, OnEllipseProb)
1775        slideSizer.Add(ellipseProb,1,wx.EXPAND|wx.RIGHT)
1776
1777        ballScaleTxt = wx.StaticText(dataDisplay,-1,'Ball scale: '+'%.2f'%(drawingData['ballScale']))
1778        slideSizer.Add(ballScaleTxt,0,wx.ALIGN_CENTER_VERTICAL)
1779        ballScale = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=int(100*drawingData['ballScale']))
1780        ballScale.Bind(wx.EVT_SLIDER, OnBallScale)
1781        slideSizer.Add(ballScale,1,wx.EXPAND|wx.RIGHT)
1782
1783        bondRadiusTxt = wx.StaticText(dataDisplay,-1,'Bond radius, A: '+'%.2f'%(drawingData['bondRadius']))
1784        slideSizer.Add(bondRadiusTxt,0,wx.ALIGN_CENTER_VERTICAL)
1785        bondRadius = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=int(100*drawingData['bondRadius']))
1786        bondRadius.SetRange(1,25)
1787        bondRadius.Bind(wx.EVT_SLIDER, OnBondRadius)
1788        slideSizer.Add(bondRadius,1,wx.EXPAND|wx.RIGHT)
1789       
1790        slopSizer.Add(slideSizer,1,wx.EXPAND|wx.RIGHT)
1791        slopSizer.Add((10,5),0)
1792        slopSizer.SetMinSize(wx.Size(300,10))
1793        mainSizer.Add(slopSizer,0)
1794        mainSizer.Add((5,5),0)
1795
1796        flexSizer = wx.FlexGridSizer(5,2,5,0)
1797        flexSizer.Add(wx.StaticText(dataDisplay,-1,'View Point:  '),0,wx.ALIGN_CENTER_VERTICAL)
1798        VP = drawingData['viewPoint'][0]
1799        viewPoint = wx.TextCtrl(dataDisplay,value='%.3f, %.3f, %.3f'%(VP[0],VP[1],VP[2]),
1800            style=wx.TE_READONLY,size=wx.Size(120,20),name='viewPoint')
1801        viewPoint.SetBackgroundColour(VERY_LIGHT_GREY)
1802        flexSizer.Add(viewPoint,0,wx.ALIGN_CENTER_VERTICAL)
1803       
1804        showABC = wx.CheckBox(dataDisplay,-1,label='Show test point?')
1805        showABC.Bind(wx.EVT_CHECKBOX, OnShowABC)
1806        showABC.SetValue(drawingData['showABC'])
1807        flexSizer.Add(showABC,0,wx.ALIGN_CENTER_VERTICAL)
1808
1809        unitCellBox = wx.CheckBox(dataDisplay,-1,label='Show unit cell?')
1810        unitCellBox.Bind(wx.EVT_CHECKBOX, OnShowUnitCell)
1811        unitCellBox.SetValue(drawingData['unitCellBox'])
1812        flexSizer.Add(unitCellBox,0,wx.ALIGN_CENTER_VERTICAL)
1813
1814        showHydrogen = wx.CheckBox(dataDisplay,-1,label='Show hydrogens?')
1815        showHydrogen.Bind(wx.EVT_CHECKBOX, OnShowHyd)
1816        showHydrogen.SetValue(drawingData['showHydrogen'])
1817        flexSizer.Add(showHydrogen,0,wx.ALIGN_CENTER_VERTICAL)
1818
1819        lineSizer = wx.BoxSizer(wx.HORIZONTAL)
1820        lineSizer.Add(wx.StaticText(dataDisplay,-1,'Background color:'),0,wx.ALIGN_CENTER_VERTICAL)
1821        backColor = wcs.ColourSelect(dataDisplay, -1,colour=drawingData['backColor'],size=wx.Size(25,25))
1822        backColor.Bind(wcs.EVT_COLOURSELECT, OnBackColor)
1823        lineSizer.Add(backColor,0,wx.ALIGN_CENTER_VERTICAL)
1824        flexSizer.Add(lineSizer,0,)
1825
1826        flexSizer.Add(wx.StaticText(dataDisplay,-1,'Hydrogen radius, A:  '),0,wx.ALIGN_CENTER_VERTICAL)
1827        sizeH = wx.TextCtrl(dataDisplay,-1,value='%.2f'%(drawingData['sizeH']),style=wx.TE_PROCESS_ENTER)
1828        sizeH.Bind(wx.EVT_TEXT_ENTER,OnSizeHatoms)
1829        sizeH.Bind(wx.EVT_KILL_FOCUS,OnSizeHatoms)
1830        flexSizer.Add(sizeH,0,wx.ALIGN_CENTER_VERTICAL)
1831
1832        flexSizer.Add(wx.StaticText(dataDisplay,-1,'Bond search factor:  '),0,wx.ALIGN_CENTER_VERTICAL)
1833        radFactor = wx.TextCtrl(dataDisplay,value='%.2f'%(drawingData['radiusFactor']),style=wx.TE_PROCESS_ENTER)
1834        radFactor.Bind(wx.EVT_TEXT_ENTER,OnRadFactor)
1835        radFactor.Bind(wx.EVT_KILL_FOCUS,OnRadFactor)
1836        flexSizer.Add(radFactor,0,wx.ALIGN_CENTER_VERTICAL)
1837        mainSizer.Add(flexSizer,0,)
1838
1839        dataDisplay.SetSizer(mainSizer)
1840        Size = mainSizer.Fit(self.dataFrame)
1841        Size[1] += 26                           #compensate for status bar
1842        dataDisplay.SetSize(Size)
1843        self.dataFrame.setSizePosLeft(Size)
1844       
1845    def UpdateTexture():
1846        generalData = data['General']       
1847        SGData = generalData['SGData']
1848        try:
1849            textureData = generalData['SH Texture']
1850        except KeyError:            #fix old files!
1851            textureData = generalData['SH Texture'] = {'Order':0,'Model':'cylindrical',
1852                'Sample omega':[False,0.0],'Sample chi':[False,0.0],'Sample phi':[False,0.0],
1853                'SH Coeff':[False,{}],'SHShow':False,'PFhkl':[0,0,1],
1854                'PFxyz':[0,0,1.],'PlotType':'Pole figure'}
1855        if 'SHShow' not in textureData:     #another fix
1856            textureData.update({'SHShow':False,'PFhkl':[0,0,1],'PFxyz':[0,0,1.],'PlotType':'Pole figure'})
1857        try:                        #another fix!
1858            x = textureData['PlotType']
1859        except KeyError:
1860            textureData.update({'PFxyz':[0,0,1.],'PlotType':'Pole figure'})
1861        shModels = ['cylindrical','none','shear - 2/m','rolling - mmm']
1862        SamSym = dict(zip(shModels,['0','-1','2/m','mmm']))
1863       
1864        shAngles = ['omega','chi','phi']
1865       
1866        def SetSHCoef():
1867            cofNames = G2lat.GenSHCoeff(SGData['SGLaue'],SamSym[textureData['Model']],textureData['Order'])
1868            newSHCoef = dict(zip(cofNames,np.zeros(len(cofNames))))
1869            SHCoeff = textureData['SH Coeff'][1]
1870            for cofName in SHCoeff:
1871                if cofName in  cofNames:
1872                    newSHCoef[cofName] = SHCoeff[cofName]
1873            return newSHCoef
1874       
1875        def OnShOrder(event):
1876            Obj = event.GetEventObject()
1877            textureData['Order'] = int(Obj.GetValue())
1878            textureData['SH Coeff'][1] = SetSHCoef()
1879            UpdateTexture()
1880            G2plt.PlotTexture(self,data,newPlot=False)
1881                       
1882        def OnShModel(event):
1883            Obj = event.GetEventObject()
1884            textureData['Model'] = Obj.GetValue()
1885            textureData['SH Coeff'][1] = SetSHCoef()
1886            UpdateTexture()
1887            G2plt.PlotTexture(self,data,newPlot=False)
1888           
1889        def OnSHRefine(event):
1890            Obj = event.GetEventObject()
1891            textureData['SH Coeff'][0] = Obj.GetValue()
1892           
1893        def OnSHShow(event):
1894            Obj = event.GetEventObject()
1895            textureData['SHShow'] = Obj.GetValue()
1896            UpdateTexture()
1897           
1898        def OnProjSel(event):
1899            Obj = event.GetEventObject()
1900            self.Projection = Obj.GetValue()
1901            G2plt.PlotTexture(self,data,newPlot=False)
1902           
1903        def OnColorSel(event):
1904            Obj = event.GetEventObject()
1905            self.ContourColor = Obj.GetValue()
1906            G2plt.PlotTexture(self,data,newPlot=False)
1907           
1908        def OnAngRef(event):
1909            Obj = event.GetEventObject()
1910            textureData[angIndx[Obj.GetId()]][0] = Obj.GetValue()
1911           
1912        def OnAngValue(event):
1913            Obj = event.GetEventObject()
1914            try:
1915                value =  float(Obj.GetValue())
1916            except ValueError:
1917                value = textureData[valIndx[Obj.GetId()]][1]
1918            Obj.SetValue('%8.2f'%(value))
1919            textureData[valIndx[Obj.GetId()]][1] = value
1920           
1921        def OnODFValue(event): 
1922            Obj = event.GetEventObject()
1923            try:
1924                value =  float(Obj.GetValue())
1925            except ValueError:
1926                value = textureData['SH Coeff'][1][ODFIndx[Obj.GetId()]]
1927            Obj.SetValue('%8.3f'%(value))
1928            textureData['SH Coeff'][1][ODFIndx[Obj.GetId()]] = value
1929            G2plt.PlotTexture(self,data,newPlot=False)
1930           
1931        def OnPfType(event):
1932            Obj = event.GetEventObject()
1933            textureData['PlotType'] = Obj.GetValue()
1934            UpdateTexture()
1935            G2plt.PlotTexture(self,data)
1936           
1937        def OnPFValue(event):
1938            Obj = event.GetEventObject()
1939            if textureData['PlotType'] in ['Pole figure','Axial pole distribution']:
1940                try:
1941                    value = '['+Obj.GetValue()+']'
1942                    hkl = eval(value)
1943                except:
1944                    value = str(textureData['PFhkl'])
1945                    hkl = eval(value)
1946                Obj.SetValue('%d %d d'%(hkl[0],hkl[1],hkl[2]))
1947                textureData['PFhkl'] = hkl
1948            else:
1949                try:
1950                    value =  '['+Obj.GetValue()+']'
1951                    xyz = eval(value)
1952                except:
1953                    value = str(textureData['PFhkl'])
1954                    xyz = eval(value)
1955                Obj.SetValue('%3.1f %3.1f %3.1f'%(xyz[0],xyz[1],xyz[2]))
1956                textureData['PFxyz'] = xyz
1957            G2plt.PlotTexture(self,data)
1958               
1959        Texture.DestroyChildren()
1960        dataDisplay = wx.Panel(Texture)
1961        mainSizer = wx.BoxSizer(wx.VERTICAL)
1962        titleSizer = wx.BoxSizer(wx.HORIZONTAL)
1963        titleSizer.Add(wx.StaticText(dataDisplay,-1,'Spherical harmonics texture data for '+PhaseName+':'),0,wx.ALIGN_CENTER_VERTICAL)
1964        titleSizer.Add(wx.StaticText(dataDisplay,-1,
1965            ' Texture Index J = %7.3f'%(G2lat.textureIndex(textureData['SH Coeff'][1]))),
1966            0,wx.ALIGN_CENTER_VERTICAL)
1967        mainSizer.Add(titleSizer,0)
1968        mainSizer.Add((0,5),0)
1969        shSizer = wx.FlexGridSizer(1,6,5,5)
1970        shSizer.Add(wx.StaticText(dataDisplay,-1,'Texture model: '),0,wx.ALIGN_CENTER_VERTICAL)
1971        shModel = wx.ComboBox(dataDisplay,-1,value=textureData['Model'],choices=shModels,
1972            style=wx.CB_READONLY|wx.CB_DROPDOWN)
1973        shModel.Bind(wx.EVT_COMBOBOX,OnShModel)
1974        shSizer.Add(shModel,0,wx.ALIGN_CENTER_VERTICAL)
1975        shSizer.Add(wx.StaticText(dataDisplay,-1,'  Harmonic order: '),0,wx.ALIGN_CENTER_VERTICAL)
1976        shOrder = wx.ComboBox(dataDisplay,-1,value=str(textureData['Order']),choices=[str(2*i) for i in range(18)],
1977            style=wx.CB_READONLY|wx.CB_DROPDOWN)
1978        shOrder.Bind(wx.EVT_COMBOBOX,OnShOrder)
1979        shSizer.Add(shOrder,0,wx.ALIGN_CENTER_VERTICAL)
1980        shRef = wx.CheckBox(dataDisplay,-1,label=' Refine texture?')
1981        shRef.SetValue(textureData['SH Coeff'][0])
1982        shRef.Bind(wx.EVT_CHECKBOX, OnSHRefine)
1983        shSizer.Add(shRef,0,wx.ALIGN_CENTER_VERTICAL)
1984        shShow = wx.CheckBox(dataDisplay,-1,label=' Show coeff.?')
1985        shShow.SetValue(textureData['SHShow'])
1986        shShow.Bind(wx.EVT_CHECKBOX, OnSHShow)
1987        shSizer.Add(shShow,0,wx.ALIGN_CENTER_VERTICAL)
1988        mainSizer.Add(shSizer,0,0)
1989        mainSizer.Add((0,5),0)
1990        PTSizer = wx.FlexGridSizer(2,4,5,5)
1991        PTSizer.Add(wx.StaticText(dataDisplay,-1,' Texture plot type: '),0,wx.ALIGN_CENTER_VERTICAL)
1992        choices = ['Axial pole distribution','Pole figure','Inverse pole figure']           
1993        pfType = wx.ComboBox(dataDisplay,-1,value=str(textureData['PlotType']),choices=choices,
1994            style=wx.CB_READONLY|wx.CB_DROPDOWN)
1995        pfType.Bind(wx.EVT_COMBOBOX,OnPfType)
1996        PTSizer.Add(pfType,0,wx.ALIGN_CENTER_VERTICAL)
1997        PTSizer.Add(wx.StaticText(dataDisplay,-1,' Projection type: '),0,wx.ALIGN_CENTER_VERTICAL)
1998        projSel = wx.ComboBox(dataDisplay,-1,value=self.Projection,choices=['equal area','stereographic'],
1999            style=wx.CB_READONLY|wx.CB_DROPDOWN)
2000        projSel.Bind(wx.EVT_COMBOBOX,OnProjSel)
2001        PTSizer.Add(projSel,0,wx.ALIGN_CENTER_VERTICAL)
2002        if textureData['PlotType'] in ['Pole figure','Axial pole distribution']:
2003            PTSizer.Add(wx.StaticText(dataDisplay,-1,' Pole figure HKL: '),0,wx.ALIGN_CENTER_VERTICAL)
2004            PH = textureData['PFhkl']
2005            pfVal = wx.TextCtrl(dataDisplay,-1,'%d %d %d'%(PH[0],PH[1],PH[2]),style=wx.TE_PROCESS_ENTER)
2006        else:
2007            PTSizer.Add(wx.StaticText(dataDisplay,-1,' Inverse pole figure XYZ: '),0,wx.ALIGN_CENTER_VERTICAL)
2008            PX = textureData['PFxyz']
2009            pfVal = wx.TextCtrl(dataDisplay,-1,'%3.1f %3.1f %3.1f'%(PX[0],PX[1],PX[2]),style=wx.TE_PROCESS_ENTER)
2010        pfVal.Bind(wx.EVT_TEXT_ENTER,OnPFValue)
2011        pfVal.Bind(wx.EVT_KILL_FOCUS,OnPFValue)
2012        PTSizer.Add(pfVal,0,wx.ALIGN_CENTER_VERTICAL)
2013        PTSizer.Add(wx.StaticText(dataDisplay,-1,' Color scheme'),0,wx.ALIGN_CENTER_VERTICAL)
2014        choice = [m for m in mpl.cm.datad.keys() if not m.endswith("_r")]
2015        choice.sort()
2016        colorSel = wx.ComboBox(dataDisplay,-1,value=self.ContourColor,choices=choice,
2017            style=wx.CB_READONLY|wx.CB_DROPDOWN)
2018        colorSel.Bind(wx.EVT_COMBOBOX,OnColorSel)
2019        PTSizer.Add(colorSel,0,wx.ALIGN_CENTER_VERTICAL)       
2020        mainSizer.Add(PTSizer,0,wx.ALIGN_CENTER_VERTICAL)
2021        mainSizer.Add((0,5),0)
2022        if textureData['SHShow']:
2023            mainSizer.Add(wx.StaticText(dataDisplay,-1,'Spherical harmonic coefficients: '),0,wx.ALIGN_CENTER_VERTICAL)
2024            mainSizer.Add((0,5),0)
2025            ODFSizer = wx.FlexGridSizer(2,8,2,2)
2026            ODFIndx = {}
2027            ODFkeys = textureData['SH Coeff'][1].keys()
2028            ODFkeys.sort()
2029            for item in ODFkeys:
2030                ODFSizer.Add(wx.StaticText(dataDisplay,-1,item),0,wx.ALIGN_CENTER_VERTICAL)
2031                ODFval = wx.TextCtrl(dataDisplay,wx.ID_ANY,'%8.3f'%(textureData['SH Coeff'][1][item]),style=wx.TE_PROCESS_ENTER)
2032                ODFIndx[ODFval.GetId()] = item
2033                ODFval.Bind(wx.EVT_TEXT_ENTER,OnODFValue)
2034                ODFval.Bind(wx.EVT_KILL_FOCUS,OnODFValue)
2035                ODFSizer.Add(ODFval,0,wx.ALIGN_CENTER_VERTICAL)
2036            mainSizer.Add(ODFSizer,0,wx.ALIGN_CENTER_VERTICAL)
2037            mainSizer.Add((0,5),0)
2038        mainSizer.Add((0,5),0)
2039        mainSizer.Add(wx.StaticText(dataDisplay,-1,'Sample orientation angles: '),0,wx.ALIGN_CENTER_VERTICAL)
2040        mainSizer.Add((0,5),0)
2041        angSizer = wx.BoxSizer(wx.HORIZONTAL)
2042        angIndx = {}
2043        valIndx = {}
2044        for item in ['Sample omega','Sample chi','Sample phi']:
2045            angRef = wx.CheckBox(dataDisplay,-1,label=item+': ')
2046            angRef.SetValue(textureData[item][0])
2047            angIndx[angRef.GetId()] = item
2048            angRef.Bind(wx.EVT_CHECKBOX, OnAngRef)
2049            angSizer.Add(angRef,0,wx.ALIGN_CENTER_VERTICAL)
2050            angVal = wx.TextCtrl(dataDisplay,wx.ID_ANY,'%8.2f'%(textureData[item][1]),style=wx.TE_PROCESS_ENTER)
2051            valIndx[angVal.GetId()] = item
2052            angVal.Bind(wx.EVT_TEXT_ENTER,OnAngValue)
2053            angVal.Bind(wx.EVT_KILL_FOCUS,OnAngValue)
2054            angSizer.Add(angVal,0,wx.ALIGN_CENTER_VERTICAL)
2055            angSizer.Add((5,0),0)
2056        mainSizer.Add(angSizer,0,wx.ALIGN_CENTER_VERTICAL)
2057        dataDisplay.SetSizer(mainSizer,True)
2058        mainSizer.Fit(self.dataFrame)
2059        Size = mainSizer.GetMinSize()
2060        Size[0] += 40
2061        Size[1] = max(Size[1],250) + 20
2062        dataDisplay.SetSize(Size)
2063        Texture.SetScrollbars(10,10,Size[0]/10-4,Size[1]/10-1)
2064        Size[1] = min(Size[1],450)
2065        self.dataFrame.setSizePosLeft(Size)
2066       
2067    def UpdateDData():
2068        UseList = data['Histograms']
2069        if UseList:
2070            self.dataFrame.DataMenu.Enable(G2gd.wxID_DATADELETE,True)
2071            self.Refine.Enable(True)
2072        else:
2073            self.dataFrame.DataMenu.Enable(G2gd.wxID_DATADELETE,False)
2074            self.Refine.Enable(False)           
2075        generalData = data['General']       
2076        SGData = generalData['SGData']
2077        keyList = UseList.keys()
2078        keyList.sort()
2079        Indx = {}
2080       
2081        def OnShowData(event):
2082            Obj = event.GetEventObject()
2083            hist = Indx[Obj.GetId()]
2084            UseList[hist]['Show'] = Obj.GetValue()
2085            UpdateDData()
2086            G2plt.PlotStrain(self,data)
2087           
2088        def OnScaleRef(event):
2089            Obj = event.GetEventObject()
2090            UseList[Indx[Obj.GetId()]]['Scale'][1] = Obj.GetValue()
2091           
2092        def OnScaleVal(event):
2093            Obj = event.GetEventObject()
2094            try:
2095                scale = float(Obj.GetValue())
2096                if scale > 0:
2097                    UseList[Indx[Obj.GetId()]]['Scale'][0] = scale
2098            except ValueError:
2099                pass
2100            Obj.SetValue("%.4f"%(UseList[Indx[Obj.GetId()]]['Scale'][0]))          #reset in case of error
2101           
2102        def OnSizeType(event):
2103            Obj = event.GetEventObject()
2104            hist = Indx[Obj.GetId()]
2105            UseList[hist]['Size'][0] = Obj.GetValue()
2106            UpdateDData()
2107           
2108        def OnSizeRef(event):
2109            Obj = event.GetEventObject()
2110            hist,pid = Indx[Obj.GetId()]
2111            if UseList[hist]['Size'][0] == 'ellipsoidal':
2112                UseList[hist]['Size'][5][pid] = Obj.GetValue()               
2113            else:
2114                UseList[hist]['Size'][2][pid] = Obj.GetValue()
2115           
2116        def OnSizeVal(event):
2117            Obj = event.GetEventObject()
2118            hist,pid = Indx[Obj.GetId()]
2119            if UseList[hist]['Size'][0] == 'ellipsoidal':
2120                try:
2121                    size = float(Obj.GetValue())
2122                    if pid < 3 and size <= 0.01:            #10A lower limit!
2123                        raise ValueError                   
2124                except ValueError:
2125                    pass
2126            else:
2127                try:
2128                    size = float(Obj.GetValue())
2129                    if size <= 0.01:            #10A lower limit!
2130                        raise ValueError
2131                    UseList[hist]['Size'][1][pid] = size
2132                except ValueError:
2133                    pass
2134            Obj.SetValue("%.1f"%(UseList[hist]['Size'][1][pid]))          #reset in case of error
2135           
2136        def OnSizeAxis(event):           
2137            Obj = event.GetEventObject()
2138            hist = Indx[Obj.GetId()]
2139            Saxis = Obj.GetValue().split()
2140            try:
2141                hkl = [int(Saxis[i]) for i in range(3)]
2142            except (ValueError,IndexError):
2143                hkl = UseList[hist]['Size'][3]
2144            if not np.any(np.array(hkl)):
2145                hkl = UseList[hist]['Size'][3]
2146            UseList[hist]['Size'][3] = hkl
2147            h,k,l = hkl
2148            Obj.SetValue('%3d %3d %3d'%(h,k,l)) 
2149                       
2150        def OnStrainType(event):
2151            Obj = event.GetEventObject()
2152            hist = Indx[Obj.GetId()]
2153            UseList[hist]['Mustrain'][0] = Obj.GetValue()
2154            UpdateDData()
2155            G2plt.PlotStrain(self,data)
2156           
2157        def OnStrainRef(event):
2158            Obj = event.GetEventObject()
2159            hist,pid = Indx[Obj.GetId()]
2160            if UseList[hist]['Mustrain'][0] == 'generalized':
2161                UseList[hist]['Mustrain'][5][pid] = Obj.GetValue()
2162            else:
2163                UseList[hist]['Mustrain'][2][pid] = Obj.GetValue()
2164           
2165        def OnStrainVal(event):
2166            Snames = G2spc.MustrainNames(SGData)
2167            Obj = event.GetEventObject()
2168            hist,pid = Indx[Obj.GetId()]
2169            try:
2170                strain = float(Obj.GetValue())
2171                if UseList[hist]['Mustrain'][0] == 'generalized':
2172                    if '4' in Snames[pid] and strain < 0:
2173                        raise ValueError
2174                    UseList[hist]['Mustrain'][4][pid] = strain
2175                else:
2176                    if strain <= 0:
2177                        raise ValueError
2178                    UseList[hist]['Mustrain'][1][pid] = strain
2179            except ValueError:
2180                pass
2181            if UseList[hist]['Mustrain'][0] == 'generalized':
2182                Obj.SetValue("%.3f"%(UseList[hist]['Mustrain'][4][pid]))          #reset in case of error
2183            else:
2184                Obj.SetValue("%.3f"%(UseList[hist]['Mustrain'][1][pid]))          #reset in case of error
2185            G2plt.PlotStrain(self,data)
2186           
2187        def OnStrainAxis(event):
2188            Obj = event.GetEventObject()
2189            hist = Indx[Obj.GetId()]
2190            Saxis = Obj.GetValue().split()
2191            try:
2192                hkl = [int(Saxis[i]) for i in range(3)]
2193            except (ValueError,IndexError):
2194                hkl = UseList[hist]['Mustrain'][3]
2195            if not np.any(np.array(hkl)):
2196                hkl = UseList[hist]['Mustrain'][3]
2197            UseList[hist]['Mustrain'][3] = hkl
2198            h,k,l = hkl
2199            Obj.SetValue('%3d %3d %3d'%(h,k,l)) 
2200            G2plt.PlotStrain(self,data)
2201           
2202        def OnHstrainRef(event):
2203            Obj = event.GetEventObject()
2204            hist,pid = Indx[Obj.GetId()]
2205            UseList[hist]['HStrain'][1][pid] = Obj.GetValue()
2206           
2207        def OnHstrainVal(event):
2208            Snames = G2spc.HStrainNames(SGData)
2209            Obj = event.GetEventObject()
2210            hist,pid = Indx[Obj.GetId()]
2211            try:
2212                strain = float(Obj.GetValue())
2213                UseList[hist]['HStrain'][0][pid] = strain
2214            except ValueError:
2215                pass
2216            Obj.SetValue("%.5f"%(UseList[hist]['HStrain'][0][pid]))          #reset in case of error
2217
2218        def OnPOType(event):
2219            Obj = event.GetEventObject()
2220            hist = Indx[Obj.GetId()]
2221            if 'March' in POType.GetValue():
2222                UseList[hist]['Pref.Ori.'][0] = 'MD'
2223            else:
2224                UseList[hist]['Pref.Ori.'][0] = 'SH'
2225            UpdateDData()           
2226
2227        def OnPORef(event):
2228            Obj = event.GetEventObject()
2229            hist = Indx[Obj.GetId()]
2230            UseList[hist]['Pref.Ori.'][2] = Obj.GetValue()
2231           
2232        def OnPOVal(event):
2233            Obj = event.GetEventObject()
2234            hist = Indx[Obj.GetId()]
2235            try:
2236                mdVal = float(Obj.GetValue())
2237                if mdVal > 0:
2238                    UseList[hist]['Pref.Ori.'][1] = mdVal
2239            except ValueError:
2240                pass
2241            Obj.SetValue("%.3f"%(UseList[hist]['Pref.Ori.'][1]))          #reset in case of error
2242           
2243        def OnPOAxis(event):
2244            Obj = event.GetEventObject()
2245            hist = Indx[Obj.GetId()]
2246            Saxis = Obj.GetValue().split()
2247            try:
2248                hkl = [int(Saxis[i]) for i in range(3)]
2249            except (ValueError,IndexError):
2250                hkl = UseList[hist]['Pref.Ori.'][3]
2251            if not np.any(np.array(hkl)):
2252                hkl = UseList[hist]['Pref.Ori.'][3]
2253            UseList[hist]['Pref.Ori.'][3] = hkl
2254            h,k,l = hkl
2255            Obj.SetValue('%3d %3d %3d'%(h,k,l)) 
2256           
2257        def OnPOOrder(event):
2258            Obj = event.GetEventObject()
2259            hist = Indx[Obj.GetId()]
2260            Order = int(Obj.GetValue())
2261            UseList[hist]['Pref.Ori.'][4] = Order
2262            UseList[hist]['Pref.Ori.'][5] = SetPOCoef(Order,hist)
2263            UpdateDData()
2264
2265        def SetPOCoef(Order,hist):
2266            cofNames = G2lat.GenSHCoeff(SGData['SGLaue'],None,Order)     #cylindrical sample symmetry
2267            newPOCoef = dict(zip(cofNames,np.zeros(len(cofNames))))
2268            POCoeff = UseList[hist]['Pref.Ori.'][5]
2269            for cofName in POCoeff:
2270                if cofName in  cofNames:
2271                    newPOCoef[cofName] = POCoeff[cofName]
2272            return newPOCoef
2273       
2274        def OnExtRef(event):
2275            Obj = event.GetEventObject()
2276            UseList[Indx[Obj.GetId()]]['Extinction'][1] = Obj.GetValue()
2277           
2278        def OnExtVal(event):
2279            Obj = event.GetEventObject()
2280            try:
2281                ext = float(Obj.GetValue())
2282                if ext >= 0:
2283                    UseList[Indx[Obj.GetId()]]['Extinction'][0] = ext
2284            except ValueError:
2285                pass
2286            Obj.SetValue("%.2f"%(UseList[Indx[Obj.GetId()]]['Extinction'][0]))          #reset in case of error
2287           
2288        def checkAxis(axis):
2289            if not np.any(np.array(axis)):
2290                return False
2291            return axis
2292           
2293        DData.DestroyChildren()
2294        dataDisplay = wx.Panel(DData)
2295        mainSizer = wx.BoxSizer(wx.VERTICAL)
2296        mainSizer.Add(wx.StaticText(dataDisplay,-1,'Histogram data for '+PhaseName+':'),0,wx.ALIGN_CENTER_VERTICAL)
2297        for item in keyList:
2298            histData = UseList[item]
2299            mainSizer.Add((5,5),0)
2300            showData = wx.CheckBox(dataDisplay,-1,label=' Show '+item)
2301            showData.SetValue(UseList[item]['Show'])
2302            Indx[showData.GetId()] = item
2303            showData.Bind(wx.EVT_CHECKBOX, OnShowData)
2304            mainSizer.Add(showData,0,wx.ALIGN_CENTER_VERTICAL)
2305            mainSizer.Add((0,5),0)
2306            if UseList[item]['Show']:
2307                scaleSizer = wx.BoxSizer(wx.HORIZONTAL)
2308                scaleRef = wx.CheckBox(dataDisplay,-1,label=' Phase fraction: ')
2309                scaleRef.SetValue(UseList[item]['Scale'][1])
2310                Indx[scaleRef.GetId()] = item
2311                scaleRef.Bind(wx.EVT_CHECKBOX, OnScaleRef)
2312                scaleSizer.Add(scaleRef,0,wx.ALIGN_CENTER_VERTICAL)
2313                scaleVal = wx.TextCtrl(dataDisplay,wx.ID_ANY,
2314                    '%.4f'%(UseList[item]['Scale'][0]),style=wx.TE_PROCESS_ENTER)
2315                Indx[scaleVal.GetId()] = item
2316                scaleVal.Bind(wx.EVT_TEXT_ENTER,OnScaleVal)
2317                scaleVal.Bind(wx.EVT_KILL_FOCUS,OnScaleVal)
2318                scaleSizer.Add(scaleVal,0,wx.ALIGN_CENTER_VERTICAL)
2319                mainSizer.Add(scaleSizer)
2320                mainSizer.Add((0,5),0)
2321               
2322            if item[:4] == 'PWDR' and UseList[item]['Show']:
2323                sizeSizer = wx.BoxSizer(wx.HORIZONTAL)
2324                sizeSizer.Add(wx.StaticText(dataDisplay,-1,' Size model: '),0,wx.ALIGN_CENTER_VERTICAL)
2325                choices = ['isotropic','uniaxial','ellipsoidal']
2326                sizeType = wx.ComboBox(dataDisplay,wx.ID_ANY,value=UseList[item]['Size'][0],choices=choices,
2327                    style=wx.CB_READONLY|wx.CB_DROPDOWN)
2328                sizeType.Bind(wx.EVT_COMBOBOX, OnSizeType)
2329                Indx[sizeType.GetId()] = item
2330                sizeSizer.Add(sizeType)
2331                sizeSizer.Add((5,0),0)
2332                if UseList[item]['Size'][0] == 'isotropic':
2333                    sizeRef = wx.CheckBox(dataDisplay,-1,label=' Cryst. size(\xb5m): ')
2334                    sizeRef.thisown = False
2335                    sizeRef.SetValue(UseList[item]['Size'][2][0])
2336                    Indx[sizeRef.GetId()] = [item,0]
2337                    sizeRef.Bind(wx.EVT_CHECKBOX, OnSizeRef)
2338                    sizeSizer.Add(sizeRef,0,wx.ALIGN_CENTER_VERTICAL)
2339                    sizeVal = wx.TextCtrl(dataDisplay,wx.ID_ANY,
2340                        '%.3f'%(UseList[item]['Size'][1][0]),style=wx.TE_PROCESS_ENTER)
2341                    Indx[sizeVal.GetId()] = [item,0]
2342                    sizeVal.Bind(wx.EVT_TEXT_ENTER,OnSizeVal)
2343                    sizeVal.Bind(wx.EVT_KILL_FOCUS,OnSizeVal)
2344                    sizeSizer.Add(sizeVal,0,wx.ALIGN_CENTER_VERTICAL)
2345                    mainSizer.Add(sizeSizer)
2346                    mainSizer.Add((0,5),0)                   
2347                elif UseList[item]['Size'][0] == 'uniaxial':
2348                    sizeSizer.Add(wx.StaticText(dataDisplay,-1,' Unique axis, H K L: '),0,wx.ALIGN_CENTER_VERTICAL)
2349                    h,k,l = UseList[item]['Size'][3]
2350                    sizeAxis = wx.TextCtrl(dataDisplay,-1,'%3d %3d %3d'%(h,k,l),style=wx.TE_PROCESS_ENTER)
2351                    Indx[sizeAxis.GetId()] = item
2352                    sizeAxis.Bind(wx.EVT_TEXT_ENTER,OnSizeAxis)
2353                    sizeAxis.Bind(wx.EVT_KILL_FOCUS,OnSizeAxis)
2354                    sizeSizer.Add(sizeAxis,0,wx.ALIGN_CENTER_VERTICAL)
2355                    mainSizer.Add(sizeSizer)
2356                    mainSizer.Add((0,5),0)
2357                    sizeSizer2 = wx.BoxSizer(wx.HORIZONTAL)
2358                    parms = zip([' Equatorial size(\xb5m): ',' Axial size(\xb5m): '],
2359                        UseList[item]['Size'][1],UseList[item]['Size'][2],range(2))
2360                    for Pa,val,ref,id in parms:
2361                        sizeRef = wx.CheckBox(dataDisplay,-1,label=Pa)
2362                        sizeRef.thisown = False
2363                        sizeRef.SetValue(ref)
2364                        Indx[sizeRef.GetId()] = [item,id]
2365                        sizeRef.Bind(wx.EVT_CHECKBOX, OnSizeRef)
2366                        sizeSizer2.Add(sizeRef,0,wx.ALIGN_CENTER_VERTICAL)
2367                        sizeVal = wx.TextCtrl(dataDisplay,wx.ID_ANY,'%.3f'%(val),style=wx.TE_PROCESS_ENTER)
2368                        Indx[sizeVal.GetId()] = [item,id]
2369                        sizeVal.Bind(wx.EVT_TEXT_ENTER,OnSizeVal)
2370                        sizeVal.Bind(wx.EVT_KILL_FOCUS,OnSizeVal)
2371                        sizeSizer2.Add(sizeVal,0,wx.ALIGN_CENTER_VERTICAL)
2372                        sizeSizer2.Add((5,0),0)
2373                    sizeSizer2.Add((5,0),0)                   
2374                    mainSizer.Add(sizeSizer2)
2375                elif UseList[item]['Size'][0] == 'ellipsoidal':
2376                    sizeSizer.Add(wx.StaticText(dataDisplay,-1,' Coefficients(\xb5m): '),0,wx.ALIGN_CENTER_VERTICAL)
2377                    mainSizer.Add(sizeSizer)
2378                    mainSizer.Add((0,5),0)
2379                    parms = zip(['S11','S22','S33','S12','S13','S23'],UseList[item]['Size'][4],
2380                        UseList[item]['Size'][5],range(6))
2381                    sizeSizer3 = wx.FlexGridSizer(2,6,5,5)
2382                    for Pa,val,ref,id in parms:
2383                        sizeRef = wx.CheckBox(dataDisplay,-1,label=Pa)
2384                        sizeRef.thisown = False
2385                        sizeRef.SetValue(ref)
2386                        Indx[sizeRef.GetId()] = [item,id]
2387                        sizeRef.Bind(wx.EVT_CHECKBOX, OnSizeRef)
2388                        sizeSizer3.Add(sizeRef,0,wx.ALIGN_CENTER_VERTICAL)
2389                        sizeVal = wx.TextCtrl(dataDisplay,wx.ID_ANY,'%.3f'%(val),style=wx.TE_PROCESS_ENTER)
2390                        Indx[sizeVal.GetId()] = [item,id]
2391                        sizeVal.Bind(wx.EVT_TEXT_ENTER,OnSizeVal)
2392                        sizeVal.Bind(wx.EVT_KILL_FOCUS,OnSizeVal)
2393                        sizeSizer3.Add(sizeVal,0,wx.ALIGN_CENTER_VERTICAL)
2394                    mainSizer.Add(sizeSizer3)
2395               
2396                strainSizer = wx.BoxSizer(wx.HORIZONTAL)
2397                strainSizer.Add(wx.StaticText(dataDisplay,-1,' Mustrain model: '),0,wx.ALIGN_CENTER_VERTICAL)
2398                choices = ['isotropic','uniaxial','generalized',]
2399                strainType = wx.ComboBox(dataDisplay,wx.ID_ANY,value=UseList[item]['Mustrain'][0],choices=choices,
2400                    style=wx.CB_READONLY|wx.CB_DROPDOWN)
2401                strainType.Bind(wx.EVT_COMBOBOX, OnStrainType)
2402                Indx[strainType.GetId()] = item
2403                strainSizer.Add(strainType)
2404                strainSizer.Add((5,0),0)
2405                if UseList[item]['Mustrain'][0] == 'isotropic':
2406                    strainRef = wx.CheckBox(dataDisplay,-1,label=' microstrain: ')
2407                    strainRef.SetValue(UseList[item]['Mustrain'][2][0])
2408                    Indx[strainRef.GetId()] = [item,0]
2409                    strainRef.Bind(wx.EVT_CHECKBOX, OnStrainRef)
2410                    strainSizer.Add(strainRef,0,wx.ALIGN_CENTER_VERTICAL)
2411                    strainVal = wx.TextCtrl(dataDisplay,wx.ID_ANY,
2412                        '%.1f'%(UseList[item]['Mustrain'][1][0]),style=wx.TE_PROCESS_ENTER)
2413                    Indx[strainVal.GetId()] = [item,0]
2414                    strainVal.Bind(wx.EVT_TEXT_ENTER,OnStrainVal)
2415                    strainVal.Bind(wx.EVT_KILL_FOCUS,OnStrainVal)
2416                    strainSizer.Add(strainVal,0,wx.ALIGN_CENTER_VERTICAL)
2417                    mainSizer.Add(strainSizer)
2418                    mainSizer.Add((0,5),0)
2419                elif UseList[item]['Mustrain'][0] == 'uniaxial':
2420                    strainSizer.Add(wx.StaticText(dataDisplay,-1,' Unique axis, H K L: '),0,wx.ALIGN_CENTER_VERTICAL)
2421                    h,k,l = UseList[item]['Mustrain'][3]
2422                    strAxis = wx.TextCtrl(dataDisplay,-1,'%3d %3d %3d'%(h,k,l),style=wx.TE_PROCESS_ENTER)
2423                    Indx[strAxis.GetId()] = item
2424                    strAxis.Bind(wx.EVT_TEXT_ENTER,OnStrainAxis)
2425                    strAxis.Bind(wx.EVT_KILL_FOCUS,OnStrainAxis)
2426                    strainSizer.Add(strAxis,0,wx.ALIGN_CENTER_VERTICAL)
2427                    mainSizer.Add(strainSizer)
2428                    mainSizer.Add((0,5),0)
2429                    strainSizer = wx.BoxSizer(wx.HORIZONTAL)
2430                    parms = zip([' Equatorial mustrain: ',' Axial mustrain: '],
2431                        UseList[item]['Mustrain'][1],UseList[item]['Mustrain'][2],range(2))
2432                    for Pa,val,ref,id in parms:
2433                        strainRef = wx.CheckBox(dataDisplay,-1,label=Pa)
2434                        strainRef.thisown = False
2435                        strainRef.SetValue(ref)
2436                        Indx[strainRef.GetId()] = [item,id]
2437                        strainRef.Bind(wx.EVT_CHECKBOX, OnStrainRef)
2438                        strainSizer.Add(strainRef,0,wx.ALIGN_CENTER_VERTICAL)
2439                        strainVal = wx.TextCtrl(dataDisplay,wx.ID_ANY,'%.1f'%(val),style=wx.TE_PROCESS_ENTER)
2440                        Indx[strainVal.GetId()] = [item,id]
2441                        strainVal.Bind(wx.EVT_TEXT_ENTER,OnStrainVal)
2442                        strainVal.Bind(wx.EVT_KILL_FOCUS,OnStrainVal)
2443                        strainSizer.Add(strainVal,0,wx.ALIGN_CENTER_VERTICAL)
2444                        strainSizer.Add((5,0),0)
2445                    strainSizer.Add((5,0),0)                   
2446                    mainSizer.Add(strainSizer)
2447                elif UseList[item]['Mustrain'][0] == 'generalized':
2448                    strainSizer.Add(wx.StaticText(dataDisplay,-1,' Coefficients: '),0,wx.ALIGN_CENTER_VERTICAL)
2449                    mainSizer.Add(strainSizer)
2450                    mainSizer.Add((0,5),0)
2451                    Snames = G2spc.MustrainNames(SGData)
2452                    numb = len(Snames)
2453                    if len(UseList[item]['Mustrain'][4]) < numb:
2454                        UseList[item]['Mustrain'][4] = numb*[0.0,]
2455                        UseList[item]['Mustrain'][5] = numb*[False,]
2456                    parms = zip(Snames,UseList[item]['Mustrain'][4],UseList[item]['Mustrain'][5],range(numb))
2457                    strainSizer = wx.FlexGridSizer(1,6,5,5)
2458                    for Pa,val,ref,id in parms:
2459                        strainRef = wx.CheckBox(dataDisplay,-1,label=Pa)
2460                        strainRef.thisown = False
2461                        strainRef.SetValue(ref)
2462                        Indx[strainRef.GetId()] = [item,id]
2463                        strainRef.Bind(wx.EVT_CHECKBOX, OnStrainRef)
2464                        strainSizer.Add(strainRef,0,wx.ALIGN_CENTER_VERTICAL)
2465                        strainVal = wx.TextCtrl(dataDisplay,wx.ID_ANY,'%.5f'%(val),style=wx.TE_PROCESS_ENTER)
2466                        Indx[strainVal.GetId()] = [item,id]
2467                        strainVal.Bind(wx.EVT_TEXT_ENTER,OnStrainVal)
2468                        strainVal.Bind(wx.EVT_KILL_FOCUS,OnStrainVal)
2469                        strainSizer.Add(strainVal,0,wx.ALIGN_CENTER_VERTICAL)
2470                    mainSizer.Add(strainSizer)
2471                mainSizer.Add(wx.StaticText(dataDisplay,-1,' Hydrostatic strain:'))
2472                hstrainSizer = wx.FlexGridSizer(1,6,5,5)
2473                Hsnames = G2spc.HStrainNames(SGData)
2474                parms = zip(Hsnames,UseList[item]['HStrain'][0],UseList[item]['HStrain'][1],range(len(Hsnames)))
2475                for Pa,val,ref,id in parms:
2476                    hstrainRef = wx.CheckBox(dataDisplay,-1,label=Pa)
2477                    hstrainRef.thisown = False
2478                    hstrainRef.SetValue(ref)
2479                    Indx[hstrainRef.GetId()] = [item,id]
2480                    hstrainRef.Bind(wx.EVT_CHECKBOX, OnHstrainRef)
2481                    hstrainSizer.Add(hstrainRef,0,wx.ALIGN_CENTER_VERTICAL)
2482                    hstrainVal = wx.TextCtrl(dataDisplay,wx.ID_ANY,'%.5f'%(val),style=wx.TE_PROCESS_ENTER)
2483                    Indx[hstrainVal.GetId()] = [item,id]
2484                    hstrainVal.Bind(wx.EVT_TEXT_ENTER,OnHstrainVal)
2485                    hstrainVal.Bind(wx.EVT_KILL_FOCUS,OnHstrainVal)
2486                    hstrainSizer.Add(hstrainVal,0,wx.ALIGN_CENTER_VERTICAL)
2487                mainSizer.Add(hstrainSizer)
2488                   
2489                #texture  'Pref. Ori.':['MD',1.0,False,[0,0,1],0,[]] last two for 'SH' are SHorder & coeff
2490                poSizer = wx.FlexGridSizer(1,6,5,5)
2491                POData = UseList[item]['Pref.Ori.']
2492                choice = ['March-Dollase','Spherical harmonics']
2493                POtype = choice[['MD','SH'].index(POData[0])]
2494                poSizer.Add(wx.StaticText(dataDisplay,-1,' Preferred orientation model '),0,wx.ALIGN_CENTER_VERTICAL)
2495                POType = wx.ComboBox(dataDisplay,wx.ID_ANY,value=POtype,choices=choice,
2496                    style=wx.CB_READONLY|wx.CB_DROPDOWN)
2497                Indx[POType.GetId()] = item
2498                POType.Bind(wx.EVT_COMBOBOX, OnPOType)
2499                poSizer.Add(POType)
2500                if POData[0] == 'MD':
2501                    mainSizer.Add(poSizer)
2502                    poSizer = wx.BoxSizer(wx.HORIZONTAL)
2503                    poRef = wx.CheckBox(dataDisplay,-1,label=' March-Dollase ratio: ')
2504                    poRef.SetValue(POData[2])
2505                    Indx[poRef.GetId()] = item
2506                    poRef.Bind(wx.EVT_CHECKBOX,OnPORef)
2507                    poSizer.Add(poRef,0,wx.ALIGN_CENTER_VERTICAL)
2508                    poVal = wx.TextCtrl(dataDisplay,wx.ID_ANY,
2509                        '%.3f'%(POData[1]),style=wx.TE_PROCESS_ENTER)
2510                    Indx[poVal.GetId()] = item
2511                    poVal.Bind(wx.EVT_TEXT_ENTER,OnPOVal)
2512                    poVal.Bind(wx.EVT_KILL_FOCUS,OnPOVal)
2513                    poSizer.Add(poVal,0,wx.ALIGN_CENTER_VERTICAL)
2514                    poSizer.Add(wx.StaticText(dataDisplay,-1,' Unique axis, H K L: '),0,wx.ALIGN_CENTER_VERTICAL)
2515                    h,k,l =POData[3]
2516                    poAxis = wx.TextCtrl(dataDisplay,-1,'%3d %3d %3d'%(h,k,l),style=wx.TE_PROCESS_ENTER)
2517                    Indx[poAxis.GetId()] = item
2518                    poAxis.Bind(wx.EVT_TEXT_ENTER,OnPOAxis)
2519                    poAxis.Bind(wx.EVT_KILL_FOCUS,OnPOAxis)
2520                    poSizer.Add(poAxis,0,wx.ALIGN_CENTER_VERTICAL)
2521                    mainSizer.Add(poSizer)
2522                else:           #'SH'
2523                    poSizer.Add(wx.StaticText(dataDisplay,-1,' Harmonic order: '),0,wx.ALIGN_CENTER_VERTICAL)
2524                    poOrder = wx.ComboBox(dataDisplay,wx.ID_ANY,value=str(POData[4]),choices=[str(2*i) for i in range(18)],
2525                        style=wx.CB_READONLY|wx.CB_DROPDOWN)
2526                    Indx[poOrder.GetId()] = item
2527                    poOrder.Bind(wx.EVT_COMBOBOX,OnPOOrder)
2528                    poSizer.Add(poOrder,0,wx.ALIGN_CENTER_VERTICAL)
2529                    poRef = wx.CheckBox(dataDisplay,-1,label=' Refine? ')
2530                    poRef.SetValue(POData[2])
2531                    Indx[poRef.GetId()] = item
2532                    poRef.Bind(wx.EVT_CHECKBOX,OnPORef)
2533                    poSizer.Add(poRef,0,wx.ALIGN_CENTER_VERTICAL)
2534                    mainSizer.Add(poSizer)
2535                    if POData[4]:
2536                        mainSizer.Add(wx.StaticText(dataDisplay,-1,' Spherical harmonic coefficients: '),0,wx.ALIGN_CENTER_VERTICAL)
2537                        mainSizer.Add((0,5),0)
2538                        ODFSizer = wx.FlexGridSizer(2,8,2,2)
2539                        ODFIndx = {}
2540                        ODFkeys = POData[5].keys()
2541                        ODFkeys.sort()
2542                        for odf in ODFkeys:
2543                            ODFSizer.Add(wx.StaticText(dataDisplay,-1,odf),0,wx.ALIGN_CENTER_VERTICAL)
2544                            ODFval = wx.TextCtrl(dataDisplay,wx.ID_ANY,'%8.3f'%(POData[5][odf]),style=wx.TE_PROCESS_ENTER)
2545                            ODFIndx[ODFval.GetId()] = odf
2546    #                        ODFval.Bind(wx.EVT_TEXT_ENTER,OnODFValue)
2547    #                        ODFval.Bind(wx.EVT_KILL_FOCUS,OnODFValue)
2548                            ODFSizer.Add(ODFval,0,wx.ALIGN_CENTER_VERTICAL)
2549                        mainSizer.Add(ODFSizer,0,wx.ALIGN_CENTER_VERTICAL)
2550                        mainSizer.Add((0,5),0)
2551                mainSizer.Add((0,5),0)               
2552                #Extinction  'Extinction':[0.0,False]
2553                extSizer = wx.BoxSizer(wx.HORIZONTAL)
2554                extRef = wx.CheckBox(dataDisplay,-1,label=' Extinction: ')
2555                extRef.SetValue(UseList[item]['Extinction'][1])
2556                Indx[extRef.GetId()] = item
2557                extRef.Bind(wx.EVT_CHECKBOX, OnExtRef)
2558                extSizer.Add(extRef,0,wx.ALIGN_CENTER_VERTICAL)
2559                extVal = wx.TextCtrl(dataDisplay,wx.ID_ANY,
2560                    '%.2f'%(UseList[item]['Extinction'][0]),style=wx.TE_PROCESS_ENTER)
2561                Indx[extVal.GetId()] = item
2562                extVal.Bind(wx.EVT_TEXT_ENTER,OnExtVal)
2563                extVal.Bind(wx.EVT_KILL_FOCUS,OnExtVal)
2564                extSizer.Add(extVal,0,wx.ALIGN_CENTER_VERTICAL)
2565                mainSizer.Add(extSizer)
2566                mainSizer.Add((0,5),0)
2567            elif item[:4] == 'HKLF' and UseList[item]['Show']:
2568                pass
2569        mainSizer.Add((5,5),0)
2570
2571        dataDisplay.SetSizer(mainSizer,True)
2572        mainSizer.Fit(self.dataFrame)
2573        Size = mainSizer.GetMinSize()
2574        Size[0] += 40
2575        Size[1] = max(Size[1],250) + 20
2576        dataDisplay.SetSize(Size)
2577        DData.SetScrollbars(10,10,Size[0]/10-4,Size[1]/10-1)
2578        Size[1] = min(Size[1],450)
2579        self.dataFrame.setSizePosLeft(Size)
2580       
2581    def OnHklfAdd(event):
2582        UseList = data['Histograms']
2583        keyList = UseList.keys()
2584        TextList = []
2585        if self.PatternTree.GetCount():
2586            item, cookie = self.PatternTree.GetFirstChild(self.root)
2587            while item:
2588                name = self.PatternTree.GetItemText(item)
2589                if name not in keyList and 'HKLF' in name:
2590                    TextList.append(name)
2591                item, cookie = self.PatternTree.GetNextChild(self.root, cookie)                       
2592            dlg = wx.MultiChoiceDialog(self, 'Which new data to use?', 'Use data', TextList, wx.CHOICEDLG_STYLE)
2593            try:
2594                if dlg.ShowModal() == wx.ID_OK:
2595                    result = dlg.GetSelections()
2596                    for i in result:
2597                        histoName = TextList[i]
2598                        UseList[histoName] = {'Histogram':histoName,'Show':False,'Scale':[1.0,True],
2599                            'Extinction':['Lorentzian','Secondary Type I',{'Eg':[0.0,False]},]}                       
2600                    data['Histograms'] = UseList
2601                    UpdateDData()
2602            finally:
2603                dlg.Destroy()
2604       
2605    def OnPwdrAdd(event):
2606        generalData = data['General']
2607        SGData = generalData['SGData']
2608        UseList = data['Histograms']
2609        NShkl = len(G2spc.MustrainNames(SGData))
2610        NDij = len(G2spc.HStrainNames(SGData))
2611        keyList = UseList.keys()
2612        TextList = []
2613        if self.PatternTree.GetCount():
2614            item, cookie = self.PatternTree.GetFirstChild(self.root)
2615            while item:
2616                name = self.PatternTree.GetItemText(item)
2617                if name not in keyList and 'PWDR' in name:
2618                    TextList.append(name)
2619                item, cookie = self.PatternTree.GetNextChild(self.root, cookie)
2620            dlg = wx.MultiChoiceDialog(self, 'Which new data to use?', 'Use data', TextList, wx.CHOICEDLG_STYLE)
2621            try:
2622                if dlg.ShowModal() == wx.ID_OK:
2623                    result = dlg.GetSelections()
2624                    for i in result: 
2625                        histoName = TextList[i]
2626                        pId = G2gd.GetPatternTreeItemId(self,self.root,histoName)
2627                        UseList[histoName] = {'Histogram':histoName,'Show':False,
2628                            'Scale':[1.0,False],'Pref.Ori.':['MD',1.0,False,[0,0,1],0,{}],
2629                            'Size':['isotropic',[4.,4.,],[False,False],[0,0,1],6*[0.0,],6*[False,]],
2630                            'Mustrain':['isotropic',[1000.0,1000.0],[False,False],[0,0,1],
2631                                NShkl*[0.01,],NShkl*[False,]],
2632                            'HStrain':[NDij*[0.0,],NDij*[False,]],                         
2633                            'Extinction':[0.0,False]}
2634                        refList = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,pId,'Reflection Lists'))
2635                        refList[generalData['Name']] = []                       
2636                    data['Histograms'] = UseList
2637                    UpdateDData()
2638            finally:
2639                dlg.Destroy()
2640       
2641    def OnDataDelete(event):
2642        UseList = data['Histograms']
2643        keyList = UseList.keys()
2644        keyList.sort()
2645        DelList = []
2646        if UseList:
2647            DelList = []
2648            dlg = wx.MultiChoiceDialog(self, 
2649                'Which histogram to delete from this phase?', 'Delete histogram', 
2650                keyList, wx.CHOICEDLG_STYLE)
2651            try:
2652                if dlg.ShowModal() == wx.ID_OK:
2653                    result = dlg.GetSelections()
2654                    for i in result: DelList.append(keyList[i])
2655                    for i in DelList:
2656                        del UseList[i]
2657                    UpdateDData()
2658            finally:
2659                dlg.Destroy()
2660
2661    def FillPawleyReflectionsGrid():
2662                       
2663        def KeyEditPawleyGrid(event):
2664            colList = self.PawleyRefl.GetSelectedCols()
2665            PawleyPeaks = data['Pawley ref']
2666            if event.GetKeyCode() == wx.WXK_RETURN:
2667                event.Skip(True)
2668            elif event.GetKeyCode() == wx.WXK_CONTROL:
2669                event.Skip(True)
2670            elif event.GetKeyCode() == wx.WXK_SHIFT:
2671                event.Skip(True)
2672            elif colList:
2673                self.PawleyRefl.ClearSelection()
2674                key = event.GetKeyCode()
2675                for col in colList:
2676                    if PawleyTable.GetTypeName(0,col) == wg.GRID_VALUE_BOOL:
2677                        if key == 89: #'Y'
2678                            for row in range(PawleyTable.GetNumberRows()): PawleyPeaks[row][col]=True
2679                        elif key == 78:  #'N'
2680                            for row in range(PawleyTable.GetNumberRows()): PawleyPeaks[row][col]=False
2681                        FillPawleyReflectionsGrid()
2682           
2683        if 'Pawley ref' in data:
2684            PawleyPeaks = data['Pawley ref']                       
2685            rowLabels = []
2686            for i in range(len(PawleyPeaks)): rowLabels.append(str(i))
2687            colLabels = ['h','k','l','mul','d','refine','Fsq(hkl)','sig(Fsq)']
2688            Types = 4*[wg.GRID_VALUE_LONG,]+[wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_BOOL,]+ \
2689                2*[wg.GRID_VALUE_FLOAT+':10,2',]
2690            PawleyTable = G2gd.Table(PawleyPeaks,rowLabels=rowLabels,colLabels=colLabels,types=Types)
2691            self.PawleyRefl.SetTable(PawleyTable, True)
2692            self.PawleyRefl.Bind(wx.EVT_KEY_DOWN, KeyEditPawleyGrid)                 
2693            self.PawleyRefl.SetMargins(0,0)
2694            self.PawleyRefl.AutoSizeColumns(False)
2695            self.dataFrame.setSizePosLeft([500,300])
2696                   
2697    def OnPawleyLoad(event):
2698        generalData = data['General']
2699        dmin = generalData['Pawley dmin']
2700        cell = generalData['Cell'][1:7]
2701        A = G2lat.cell2A(cell)
2702        SGData = generalData['SGData']
2703        HKLd = np.array(G2lat.GenHLaue(dmin,SGData,A))
2704        PawleyPeaks = []
2705        wx.BeginBusyCursor()
2706        try:
2707            for h,k,l,d in HKLd:
2708                ext,mul = G2spc.GenHKLf([h,k,l],SGData)[:2]
2709                if not ext:
2710                    PawleyPeaks.append([h,k,l,mul,d,False,100.0,1.0])
2711        finally:
2712            wx.EndBusyCursor()
2713        data['Pawley ref'] = PawleyPeaks
2714        FillPawleyReflectionsGrid()
2715       
2716    def OnPawleyEstimate(event):
2717        try:
2718            Refs = data['Pawley ref']
2719            Histograms = data['Histograms']
2720        except KeyError:
2721            print '**** Error - no histograms defined for this phase ****'
2722            return
2723        HistoNames = Histograms.keys()
2724        PatternId = G2gd.GetPatternTreeItemId(self,self.root,HistoNames[0])
2725        xdata = self.PatternTree.GetItemPyData(PatternId)[1]
2726        Inst = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,PatternId,'Instrument Parameters'))
2727        Inst = dict(zip(Inst[3],Inst[1]))
2728        Sample = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,PatternId,'Sample Parameters'))
2729        if 'Lam' in Inst:
2730            wave = Inst['Lam']
2731        else:
2732            wave = Inst['Lam1']
2733       
2734        posCorr = Inst['Zero']
2735        print Sample
2736        const = 9.e-2/(np.pi*Sample['Gonio. radius'])                  #shifts in microns
2737       
2738        for ref in Refs:
2739            pos = 2.0*asind(wave/(2.0*ref[4]))
2740            if 'Bragg' in Sample['Type']:
2741                pos -= const*(4.*Sample['Shift'][0]*cosd(pos/2.0)+ \
2742                    Sample['Transparency'][0]*sind(pos)*100.0)            #trans(=1/mueff) in cm
2743            else:               #Debye-Scherrer - simple but maybe not right
2744                pos -= const*(Sample['DisplaceX'][0]*cosd(pos)+Sample['DisplaceY'][0]*sind(pos))
2745            indx = np.searchsorted(xdata[0],pos)
2746            try:
2747                ref[6] = xdata[1][indx]
2748                print ref[:7],indx,pos
2749            except IndexError:
2750                pass
2751        FillPawleyReflectionsGrid()
2752                           
2753    def OnPawleyDelete(event):
2754        dlg = wx.MessageDialog(self,'Do you really want to delete Pawley reflections?','Delete', 
2755            wx.YES_NO | wx.ICON_QUESTION)
2756        try:
2757            result = dlg.ShowModal()
2758        finally:
2759            dlg.Destroy()
2760        if result == wx.ID_YES: 
2761            data['Pawley ref'] = []
2762            FillPawleyReflectionsGrid()
2763           
2764    def OnTextureClear(event):
2765        event.Skip()
2766
2767    def OnPageChanged(event):
2768        page = event.GetSelection()
2769        text = self.dataDisplay.GetPageText(page)
2770        if text == 'Atoms':
2771            self.dataFrame.SetMenuBar(self.dataFrame.AtomsMenu)
2772            self.dataFrame.Bind(wx.EVT_MENU, OnAtomAdd, id=G2gd.wxID_ATOMSEDITADD)
2773            self.dataFrame.Bind(wx.EVT_MENU, OnAtomTestAdd, id=G2gd.wxID_ATOMSTESTADD)
2774            self.dataFrame.Bind(wx.EVT_MENU, OnAtomInsert, id=G2gd.wxID_ATOMSEDITINSERT)
2775            self.dataFrame.Bind(wx.EVT_MENU, OnAtomTestInsert, id=G2gd.wxID_ATONTESTINSERT)
2776            self.dataFrame.Bind(wx.EVT_MENU, AtomDelete, id=G2gd.wxID_ATOMSEDITDELETE)
2777            self.dataFrame.Bind(wx.EVT_MENU, AtomRefine, id=G2gd.wxID_ATOMSREFINE)
2778            self.dataFrame.Bind(wx.EVT_MENU, AtomModify, id=G2gd.wxID_ATOMSMODIFY)
2779            self.dataFrame.Bind(wx.EVT_MENU, AtomTransform, id=G2gd.wxID_ATOMSTRANSFORM)
2780            self.dataFrame.Bind(wx.EVT_MENU, OnReloadDrawAtoms, id=G2gd.wxID_RELOADDRAWATOMS)
2781            FillAtomsGrid()
2782        elif text == 'General':
2783            UpdateGeneral()
2784            self.dataFrame.SetMenuBar(self.dataFrame.BlankMenu)
2785        elif text == 'Data':
2786            self.dataFrame.SetMenuBar(self.dataFrame.DataMenu)
2787            self.dataFrame.Bind(wx.EVT_MENU, OnPwdrAdd, id=G2gd.wxID_PWDRADD)
2788            self.dataFrame.Bind(wx.EVT_MENU, OnHklfAdd, id=G2gd.wxID_HKLFADD)
2789            self.dataFrame.Bind(wx.EVT_MENU, OnDataDelete, id=G2gd.wxID_DATADELETE)
2790            UpdateDData()
2791            G2plt.PlotStrain(self,data)
2792        elif text == 'Draw Options':
2793            self.dataFrame.SetMenuBar(self.dataFrame.BlankMenu)
2794            UpdateDrawOptions()
2795            G2plt.PlotStructure(self,data)
2796        elif text == 'Draw Atoms':
2797            self.dataFrame.SetMenuBar(self.dataFrame.DrawAtomsMenu)
2798            self.dataFrame.Bind(wx.EVT_MENU, DrawAtomStyle, id=G2gd.wxID_DRAWATOMSTYLE)
2799            self.dataFrame.Bind(wx.EVT_MENU, DrawAtomLabel, id=G2gd.wxID_DRAWATOMLABEL)
2800            self.dataFrame.Bind(wx.EVT_MENU, DrawAtomColor, id=G2gd.wxID_DRAWATOMCOLOR)
2801            self.dataFrame.Bind(wx.EVT_MENU, ResetAtomColors, id=G2gd.wxID_DRAWATOMRESETCOLOR)
2802            self.dataFrame.Bind(wx.EVT_MENU, SetViewPoint, id=G2gd.wxID_DRAWVIEWPOINT)
2803            self.dataFrame.Bind(wx.EVT_MENU, AddSymEquiv, id=G2gd.wxID_DRAWADDEQUIV)
2804            self.dataFrame.Bind(wx.EVT_MENU, TransformSymEquiv, id=G2gd.wxID_DRAWTRANSFORM)
2805            self.dataFrame.Bind(wx.EVT_MENU, FillCoordSphere, id=G2gd.wxID_DRAWFILLCOORD)           
2806            self.dataFrame.Bind(wx.EVT_MENU, FillUnitCell, id=G2gd.wxID_DRAWFILLCELL)
2807            self.dataFrame.Bind(wx.EVT_MENU, DrawAtomsDelete, id=G2gd.wxID_DRAWDELETE)
2808            UpdateDrawAtoms()
2809            G2plt.PlotStructure(self,data)
2810        elif text == 'Pawley reflections':
2811            self.dataFrame.SetMenuBar(self.dataFrame.PawleyMenu)
2812            self.dataFrame.Bind(wx.EVT_MENU, OnPawleyLoad, id=G2gd.wxID_PAWLEYLOAD)
2813            self.dataFrame.Bind(wx.EVT_MENU, OnPawleyEstimate, id=G2gd.wxID_PAWLEYESTIMATE)
2814            self.dataFrame.Bind(wx.EVT_MENU, OnPawleyDelete, id=G2gd.wxID_PAWLEYDELETE)           
2815            FillPawleyReflectionsGrid()
2816        elif text == 'Texture':
2817            self.dataFrame.SetMenuBar(self.dataFrame.TextureMenu)
2818            self.dataFrame.Bind(wx.EVT_MENU, OnTextureClear, id=G2gd.wxID_CLEARTEXTURE)
2819            UpdateTexture()                       
2820            G2plt.PlotTexture(self,data,Start=True)
2821        else:
2822            self.dataFrame.SetMenuBar(self.dataFrame.BlankMenu)
2823        event.Skip()
2824       
2825    General = wx.Window(self.dataDisplay)
2826    self.dataDisplay.AddPage(General,'General')
2827    SetupGeneral()
2828    GeneralData = data['General']
2829    UpdateGeneral()
2830
2831    if GeneralData['Type'] == 'Pawley':
2832        DData = wx.ScrolledWindow(self.dataDisplay)
2833        self.dataDisplay.AddPage(DData,'Data')
2834        self.PawleyRefl = G2gd.GSGrid(self.dataDisplay)
2835        self.dataDisplay.AddPage(self.PawleyRefl,'Pawley reflections')
2836    else:
2837        DData = wx.ScrolledWindow(self.dataDisplay)
2838        self.dataDisplay.AddPage(DData,'Data')
2839        Texture = wx.ScrolledWindow(self.dataDisplay)
2840        self.dataDisplay.AddPage(Texture,'Texture')
2841        Atoms = G2gd.GSGrid(self.dataDisplay)
2842        self.dataDisplay.AddPage(Atoms,'Atoms')
2843        drawOptions = wx.Window(self.dataDisplay)
2844        self.dataDisplay.AddPage(drawOptions,'Draw Options')
2845        drawAtoms = G2gd.GSGrid(self.dataDisplay)
2846        self.dataDisplay.AddPage(drawAtoms,'Draw Atoms')
2847
2848    self.dataDisplay.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, OnPageChanged)
2849    self.dataDisplay.SetSelection(oldPage)
2850   
2851           
Note: See TracBrowser for help on using the repository browser.