source: trunk/GSASIIgrid.py @ 863

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

fix to notebook & comment (not allowed) editing
avoid a dead window problem with comments/notebook
fix atom editing problems with no rigid bodies
work on help text

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Author Revision URL Id
File size: 102.2 KB
Line 
1# -*- coding: utf-8 -*-
2#GSASIIgrid - data display routines
3########### SVN repository information ###################
4# $Date: 2013-03-13 15:43:09 +0000 (Wed, 13 Mar 2013) $
5# $Author: vondreele $
6# $Revision: 863 $
7# $URL: trunk/GSASIIgrid.py $
8# $Id: GSASIIgrid.py 863 2013-03-13 15:43:09Z vondreele $
9########### SVN repository information ###################
10import wx
11import wx.grid as wg
12import wx.wizard as wz
13import time
14import cPickle
15import sys
16import numpy as np
17import numpy.ma as ma
18import os.path
19import wx.html        # could postpone this for quicker startup
20import webbrowser     # could postpone this for quicker startup
21import GSASIIpath
22GSASIIpath.SetVersionNumber("$Revision: 863 $")
23import GSASIImath as G2mth
24import GSASIIIO as G2IO
25import GSASIIlattice as G2lat
26import GSASIIplot as G2plt
27import GSASIIpwdGUI as G2pdG
28import GSASIIimgGUI as G2imG
29import GSASIIphsGUI as G2phG
30import GSASIIstruct as G2str
31import GSASIIspc as G2spc
32import GSASIImapvars as G2mv
33import GSASIIconstrGUI as G2cnstG
34import GSASIIrestrGUI as G2restG
35
36# trig functions in degrees
37sind = lambda x: np.sin(x*np.pi/180.)
38tand = lambda x: np.tan(x*np.pi/180.)
39cosd = lambda x: np.cos(x*np.pi/180.)
40
41# globals we will use later
42__version__ = None # gets overridden in GSASII.py
43path2GSAS2 = os.path.dirname(os.path.realpath(__file__)) # save location of this file
44helpLocDict = {}
45htmlPanel = None
46htmlFrame = None
47helpMode = 'browser'
48#if sys.platform.lower().startswith('win'): helpMode = 'internal' # need a global control to set this
49   
50htmlFirstUse = True
51
52[ wxID_FOURCALC, wxID_FOURSEARCH, wxID_FOURCLEAR, wxID_PEAKSMOVE, wxID_PEAKSCLEAR, 
53    wxID_CHARGEFLIP, wxID_PEAKSUNIQUE, wxID_PEAKSDELETE, wxID_PEAKSDA,
54    wxID_PEAKSDISTVP, wxID_PEAKSVIEWPT, wxID_FINDEQVPEAKS,wxID_SHOWBONDS,
55] = [wx.NewId() for item in range(13)]
56
57[ wxID_PWDRADD, wxID_HKLFADD,wxID_PWDANALYSIS,wxID_DATADELETE,
58] = [wx.NewId() for item in range(4)]
59
60[ wxID_ATOMSEDITADD, wxID_ATOMSEDITINSERT, wxID_ATOMSEDITDELETE, wxID_ATOMSREFINE, 
61    wxID_ATOMSMODIFY, wxID_ATOMSTRANSFORM, wxID_ATOMSVIEWADD, wxID_ATOMVIEWINSERT,
62    wxID_RELOADDRAWATOMS,wxID_ATOMSDISAGL,wxID_ATOMMOVE,wxID_RBAPPEND,wxID_ATOMSREIMPORT,
63    wxID_ASSIGNATMS2RB
64] = [wx.NewId() for item in range(14)]
65
66[ wxID_DRAWATOMSTYLE, wxID_DRAWATOMLABEL, wxID_DRAWATOMCOLOR, wxID_DRAWATOMRESETCOLOR, 
67    wxID_DRAWVIEWPOINT, wxID_DRAWTRANSFORM, wxID_DRAWDELETE, wxID_DRAWFILLCELL, 
68    wxID_DRAWADDEQUIV, wxID_DRAWFILLCOORD, wxID_DRAWDISAGLTOR,  wxID_DRAWPLANE,
69    wxID_DRAWDISTVP,
70] = [wx.NewId() for item in range(13)]
71
72[ wxID_DRAWRESTRBOND, wxID_DRAWRESTRANGLE, wxID_DRAWRESTRPLANE, wxID_DRAWRESTRCHIRAL,
73] = [wx.NewId() for item in range(4)]
74
75[ wxID_CLEARTEXTURE,wxID_REFINETEXTURE,
76] = [wx.NewId() for item in range(2)]
77
78[ wxID_PAWLEYLOAD, wxID_PAWLEYDELETE, wxID_PAWLEYESTIMATE,
79    wxID_PAWLEYUPDATE,
80] = [wx.NewId() for item in range(4)]
81
82[ wxID_IMCALIBRATE,wxID_IMRECALIBRATE,wxID_IMINTEGRATE, wxID_IMCLEARCALIB, 
83    wxID_IMCOPYCONTROLS, wxID_INTEGRATEALL, wxID_IMSAVECONTROLS, wxID_IMLOADCONTROLS,
84] = [wx.NewId() for item in range(8)]
85
86[ wxID_MASKCOPY, wxID_MASKSAVE, wxID_MASKLOAD,
87] = [wx.NewId() for item in range(3)]
88
89[ wxID_STRSTACOPY, wxID_STRSTAFIT, wxID_STRSTASAVE, wxID_STRSTALOAD,wxID_APPENDDZERO,
90] = [wx.NewId() for item in range(5)]
91
92[ wxID_BACKCOPY,wxID_LIMITCOPY,wxID_SAMPLECOPY, wxID_BACKFLAGCOPY, wxID_SAMPLEFLAGCOPY,
93    wxID_SAMPLESAVE, wxID_SAMPLELOAD,
94] = [wx.NewId() for item in range(7)]
95
96[ wxID_INSTPRMRESET,wxID_CHANGEWAVETYPE,wxID_INSTCOPY, wxID_INSTFLAGCOPY, wxID_INSTLOAD,
97    wxID_INSTSAVE,
98] = [wx.NewId() for item in range(6)]
99
100[ wxID_UNDO,wxID_LSQPEAKFIT,wxID_LSQONECYCLE,wxID_RESETSIGGAM,wxID_CLEARPEAKS,wxID_AUTOSEARCH,
101] = [wx.NewId() for item in range(6)]
102
103[  wxID_INDXRELOAD, wxID_INDEXPEAKS, wxID_REFINECELL, wxID_COPYCELL, wxID_MAKENEWPHASE,
104] = [wx.NewId() for item in range(5)]
105
106[ wxID_CONSTRAINTADD,wxID_EQUIVADD,wxID_HOLDADD,wxID_FUNCTADD,
107] = [wx.NewId() for item in range(4)]
108
109[ wxID_RESTRAINTADD, wxID_RESTSELPHASE,wxID_RESTDELETE, wxID_RESRCHANGEVAL, 
110    wxID_RESTCHANGEESD,wxID_AARESTRAINTADD,wxID_AARESTRAINTPLOT,
111] = [wx.NewId() for item in range(7)]
112
113[ wxID_RIGIDBODYADD,wxID_DRAWDEFINERB,wxID_RIGIDBODYIMPORT,wxID_RESIDUETORSSEQ,
114    wxID_AUTOFINDRESRB,wxID_GLOBALRESREFINE,wxID_RBREMOVEALL,wxID_COPYRBPARMS,
115] = [wx.NewId() for item in range(8)]
116
117[ wxID_SAVESEQSEL,
118] = [wx.NewId() for item in range(1)]
119
120[ wxID_SELECTPHASE,
121] = [wx.NewId() for item in range(1)]
122
123[ wxID_PDFCOPYCONTROLS, wxID_PDFSAVECONTROLS, wxID_PDFLOADCONTROLS, 
124    wxID_PDFCOMPUTE, wxID_PDFCOMPUTEALL, wxID_PDFADDELEMENT, wxID_PDFDELELEMENT,
125] = [wx.NewId() for item in range(7)]
126
127VERY_LIGHT_GREY = wx.Colour(235,235,235)
128
129################################################################################
130#### GSAS-II class definitions
131################################################################################
132       
133class SymOpDialog(wx.Dialog):
134    def __init__(self,parent,SGData,New=True,ForceUnit=False):
135        wx.Dialog.__init__(self,parent,-1,'Select symmetry operator',
136            pos=wx.DefaultPosition,style=wx.DEFAULT_DIALOG_STYLE)
137        panel = wx.Panel(self)
138        self.SGData = SGData
139        self.New = New
140        self.Force = ForceUnit
141        self.OpSelected = [0,0,0,[0,0,0],False,False]
142        mainSizer = wx.BoxSizer(wx.VERTICAL)
143        if ForceUnit:
144            choice = ['No','Yes']
145            self.force = wx.RadioBox(panel,-1,'Force to unit cell?',choices=choice)
146            self.force.Bind(wx.EVT_RADIOBOX, self.OnOpSelect)
147            mainSizer.Add(self.force,0,wx.ALIGN_CENTER_VERTICAL)
148        mainSizer.Add((5,5),0)
149        if SGData['SGInv']:
150            choice = ['No','Yes']
151            self.inv = wx.RadioBox(panel,-1,'Choose inversion?',choices=choice)
152            self.inv.Bind(wx.EVT_RADIOBOX, self.OnOpSelect)
153            mainSizer.Add(self.inv,0,wx.ALIGN_CENTER_VERTICAL)
154        mainSizer.Add((5,5),0)
155        if SGData['SGLatt'] != 'P':
156            LattOp = G2spc.Latt2text(SGData['SGLatt']).split(';')
157            self.latt = wx.RadioBox(panel,-1,'Choose cell centering?',choices=LattOp)
158            self.latt.Bind(wx.EVT_RADIOBOX, self.OnOpSelect)
159            mainSizer.Add(self.latt,0,wx.ALIGN_CENTER_VERTICAL)
160        mainSizer.Add((5,5),0)
161        if SGData['SGLaue'] in ['-1','2/m','mmm','4/m','4/mmm']:
162            Ncol = 2
163        else:
164            Ncol = 3
165        OpList = []
166        for M,T in SGData['SGOps']:
167            OpList.append(G2spc.MT2text(M,T))
168        self.oprs = wx.RadioBox(panel,-1,'Choose space group operator?',choices=OpList,
169            majorDimension=Ncol)
170        self.oprs.Bind(wx.EVT_RADIOBOX, self.OnOpSelect)
171        mainSizer.Add(self.oprs,0,wx.ALIGN_CENTER_VERTICAL)
172        mainSizer.Add((5,5),0)
173        mainSizer.Add(wx.StaticText(panel,-1,"   Choose unit cell?"),0,wx.ALIGN_CENTER_VERTICAL)
174        mainSizer.Add((5,5),0)
175        cellSizer = wx.BoxSizer(wx.HORIZONTAL)
176        cellSizer.Add((5,0),0)
177        cellName = ['X','Y','Z']
178        self.cell = []
179        for i in range(3):
180            self.cell.append(wx.SpinCtrl(panel,-1,cellName[i],size=wx.Size(50,20)))
181            self.cell[-1].SetRange(-3,3)
182            self.cell[-1].SetValue(0)
183            self.cell[-1].Bind(wx.EVT_SPINCTRL, self.OnOpSelect)
184            cellSizer.Add(self.cell[-1],0,wx.ALIGN_CENTER_VERTICAL)
185        mainSizer.Add(cellSizer,0,)
186        if self.New:
187            choice = ['No','Yes']
188            self.new = wx.RadioBox(panel,-1,'Generate new positions?',choices=choice)
189            self.new.Bind(wx.EVT_RADIOBOX, self.OnOpSelect)
190            mainSizer.Add(self.new,0,wx.ALIGN_CENTER_VERTICAL)
191        mainSizer.Add((5,5),0)
192
193        OkBtn = wx.Button(panel,-1,"Ok")
194        OkBtn.Bind(wx.EVT_BUTTON, self.OnOk)
195        cancelBtn = wx.Button(panel,-1,"Cancel")
196        cancelBtn.Bind(wx.EVT_BUTTON, self.OnCancel)
197        btnSizer = wx.BoxSizer(wx.HORIZONTAL)
198        btnSizer.Add((20,20),1)
199        btnSizer.Add(OkBtn)
200        btnSizer.Add((20,20),1)
201        btnSizer.Add(cancelBtn)
202        btnSizer.Add((20,20),1)
203
204        mainSizer.Add(btnSizer,0,wx.EXPAND|wx.BOTTOM|wx.TOP, 10)
205        panel.SetSizer(mainSizer)
206        panel.Fit()
207        self.Fit()
208
209    def OnOpSelect(self,event):
210        if self.SGData['SGInv']:
211            self.OpSelected[0] = self.inv.GetSelection()
212        if self.SGData['SGLatt'] != 'P':
213            self.OpSelected[1] = self.latt.GetSelection()
214        self.OpSelected[2] = self.oprs.GetSelection()
215        for i in range(3):
216            self.OpSelected[3][i] = float(self.cell[i].GetValue())
217        if self.New:
218            self.OpSelected[4] = self.new.GetSelection()
219        if self.Force:
220            self.OpSelected[5] = self.force.GetSelection()
221
222    def GetSelection(self):
223        return self.OpSelected
224
225    def OnOk(self,event):
226        parent = self.GetParent()
227        parent.Raise()
228        self.EndModal(wx.ID_OK)
229
230    def OnCancel(self,event):
231        parent = self.GetParent()
232        parent.Raise()
233        self.EndModal(wx.ID_CANCEL)
234
235class DisAglDialog(wx.Dialog):
236   
237    def __default__(self,data,default):
238        if data:
239            self.data = data
240        else:
241            self.data = {}
242            self.data['Name'] = default['Name']
243            self.data['Factors'] = [0.85,0.85]
244            self.data['AtomTypes'] = default['AtomTypes']
245            self.data['BondRadii'] = default['BondRadii']
246            self.data['AngleRadii'] = default['AngleRadii']
247       
248    def __init__(self,parent,data,default):
249        wx.Dialog.__init__(self,parent,-1,'Distance Angle Controls', 
250            pos=wx.DefaultPosition,style=wx.DEFAULT_DIALOG_STYLE)
251        self.default = default
252        self.panel = wx.Panel(self)         #just a dummy - gets destroyed in Draw!
253        self.__default__(data,self.default)
254        self.Draw(self.data)
255               
256    def Draw(self,data):
257        self.panel.Destroy()
258        self.panel = wx.Panel(self)
259        mainSizer = wx.BoxSizer(wx.VERTICAL)
260        mainSizer.Add(wx.StaticText(self.panel,-1,'Controls for phase '+data['Name']),
261            0,wx.ALIGN_CENTER_VERTICAL|wx.LEFT,10)
262        mainSizer.Add((10,10),1)
263       
264        radiiSizer = wx.FlexGridSizer(2,3,5,5)
265        radiiSizer.Add(wx.StaticText(self.panel,-1,' Type'),0,wx.ALIGN_CENTER_VERTICAL)
266        radiiSizer.Add(wx.StaticText(self.panel,-1,'Bond radii'),0,wx.ALIGN_CENTER_VERTICAL)
267        radiiSizer.Add(wx.StaticText(self.panel,-1,'Angle radii'),0,wx.ALIGN_CENTER_VERTICAL)
268        self.objList = {}
269        for id,item in enumerate(self.data['AtomTypes']):
270            radiiSizer.Add(wx.StaticText(self.panel,-1,' '+item),0,wx.ALIGN_CENTER_VERTICAL)
271            bRadii = wx.TextCtrl(self.panel,-1,value='%.3f'%(data['BondRadii'][id]),style=wx.TE_PROCESS_ENTER)
272            self.objList[bRadii.GetId()] = ['BondRadii',id]
273            bRadii.Bind(wx.EVT_TEXT_ENTER,self.OnRadiiVal)
274            bRadii.Bind(wx.EVT_KILL_FOCUS,self.OnRadiiVal)
275            radiiSizer.Add(bRadii,0,wx.ALIGN_CENTER_VERTICAL)
276            aRadii = wx.TextCtrl(self.panel,-1,value='%.3f'%(data['AngleRadii'][id]),style=wx.TE_PROCESS_ENTER)
277            self.objList[aRadii.GetId()] = ['AngleRadii',id]
278            aRadii.Bind(wx.EVT_TEXT_ENTER,self.OnRadiiVal)
279            aRadii.Bind(wx.EVT_KILL_FOCUS,self.OnRadiiVal)
280            radiiSizer.Add(aRadii,0,wx.ALIGN_CENTER_VERTICAL)
281        mainSizer.Add(radiiSizer,0,wx.EXPAND)
282        factorSizer = wx.FlexGridSizer(2,2,5,5)
283        Names = ['Bond','Angle']
284        for i,name in enumerate(Names):
285            factorSizer.Add(wx.StaticText(self.panel,-1,name+' search factor'),0,wx.ALIGN_CENTER_VERTICAL)
286            bondFact = wx.TextCtrl(self.panel,-1,value='%.3f'%(data['Factors'][i]),style=wx.TE_PROCESS_ENTER)
287            self.objList[bondFact.GetId()] = ['Factors',i]
288            bondFact.Bind(wx.EVT_TEXT_ENTER,self.OnRadiiVal)
289            bondFact.Bind(wx.EVT_KILL_FOCUS,self.OnRadiiVal)
290            factorSizer.Add(bondFact)
291        mainSizer.Add(factorSizer,0,wx.EXPAND)
292       
293        OkBtn = wx.Button(self.panel,-1,"Ok")
294        OkBtn.Bind(wx.EVT_BUTTON, self.OnOk)
295        ResetBtn = wx.Button(self.panel,-1,'Reset')
296        ResetBtn.Bind(wx.EVT_BUTTON, self.OnReset)
297        btnSizer = wx.BoxSizer(wx.HORIZONTAL)
298        btnSizer.Add((20,20),1)
299        btnSizer.Add(OkBtn)
300        btnSizer.Add(ResetBtn)
301        btnSizer.Add((20,20),1)
302        mainSizer.Add(btnSizer,0,wx.EXPAND|wx.BOTTOM|wx.TOP, 10)
303        self.panel.SetSizer(mainSizer)
304        self.panel.Fit()
305        self.Fit()
306   
307    def OnRadiiVal(self,event):
308        Obj = event.GetEventObject()
309        item = self.objList[Obj.GetId()]
310        try:
311            self.data[item[0]][item[1]] = float(Obj.GetValue())
312        except ValueError:
313            pass
314        Obj.SetValue("%.3f"%(self.data[item[0]][item[1]]))          #reset in case of error
315       
316    def GetData(self):
317        return self.data
318       
319    def OnOk(self,event):
320        parent = self.GetParent()
321        parent.Raise()
322        self.EndModal(wx.ID_OK)             
323       
324    def OnReset(self,event):
325        data = {}
326        self.__default__(data,self.default)
327        self.Draw(self.data)
328       
329class PickTwoDialog(wx.Dialog):
330   
331    def __init__(self,parent,title,prompt,names,choices):
332        wx.Dialog.__init__(self,parent,-1,title, 
333            pos=wx.DefaultPosition,style=wx.DEFAULT_DIALOG_STYLE)
334        self.panel = wx.Panel(self)         #just a dummy - gets destroyed in Draw!
335        self.prompt = prompt
336        self.choices = choices
337        self.names = names
338        self.Draw()
339
340    def Draw(self):
341        Indx = {}
342       
343        def OnSelection(event):
344            Obj = event.GetEventObject()
345            id = Indx[Obj.GetId()]
346            self.choices[id] = Obj.GetValue().encode()  #to avoid Unicode versions
347            self.Draw()
348           
349        self.panel.DestroyChildren()
350        self.panel.Destroy()
351        self.panel = wx.Panel(self)
352        mainSizer = wx.BoxSizer(wx.VERTICAL)
353        mainSizer.Add(wx.StaticText(self.panel,-1,self.prompt),0,wx.ALIGN_CENTER)
354        for isel,name in enumerate(self.choices):
355            lineSizer = wx.BoxSizer(wx.HORIZONTAL)
356            lineSizer.Add(wx.StaticText(self.panel,-1,'Reference atom '+str(isel+1)),0,wx.ALIGN_CENTER)
357            nameList = self.names[:]
358            if isel:
359                if self.choices[0] in nameList:
360                    nameList.remove(self.choices[0])
361            choice = wx.ComboBox(self.panel,-1,value=name,choices=nameList,
362                style=wx.CB_READONLY|wx.CB_DROPDOWN)
363            Indx[choice.GetId()] = isel
364            choice.Bind(wx.EVT_COMBOBOX, OnSelection)
365            lineSizer.Add(choice,0,wx.ALIGN_CENTER)
366            mainSizer.Add(lineSizer)
367        OkBtn = wx.Button(self.panel,-1,"Ok")
368        OkBtn.Bind(wx.EVT_BUTTON, self.OnOk)
369        CancelBtn = wx.Button(self.panel,-1,'Cancel')
370        CancelBtn.Bind(wx.EVT_BUTTON, self.OnCancel)
371        btnSizer = wx.BoxSizer(wx.HORIZONTAL)
372        btnSizer.Add((20,20),1)
373        btnSizer.Add(OkBtn)
374        btnSizer.Add(CancelBtn)
375        btnSizer.Add((20,20),1)
376        mainSizer.Add(btnSizer,0,wx.EXPAND|wx.BOTTOM|wx.TOP, 10)
377        self.panel.SetSizer(mainSizer)
378        self.panel.Fit()
379        self.Fit()
380       
381    def GetSelection(self):
382        return self.choices
383
384    def OnOk(self,event):
385        parent = self.GetParent()
386        parent.Raise()
387        self.EndModal(wx.ID_OK)             
388       
389    def OnCancel(self,event):
390        parent = self.GetParent()
391        parent.Raise()
392        self.EndModal(wx.ID_CANCEL)
393       
394class SingleFloatDialog(wx.Dialog):
395   
396    def __init__(self,parent,title,prompt,value,limits=[0.,1.],format='%.5g'):
397        wx.Dialog.__init__(self,parent,-1,title, 
398            pos=wx.DefaultPosition,style=wx.DEFAULT_DIALOG_STYLE)
399        self.panel = wx.Panel(self)         #just a dummy - gets destroyed in Draw!
400        self.limits = limits
401        self.value = value
402        self.prompt = prompt
403        self.format = format
404        self.Draw()
405       
406    def Draw(self):
407       
408        def OnValItem(event):
409            try:
410                val = float(valItem.GetValue())
411                if val < self.limits[0] or val > self.limits[1]:
412                    raise ValueError
413            except ValueError:
414                val = self.value
415            self.value = val
416            valItem.SetValue(self.format%(self.value))
417           
418        self.panel.Destroy()
419        self.panel = wx.Panel(self)
420        mainSizer = wx.BoxSizer(wx.VERTICAL)
421        mainSizer.Add(wx.StaticText(self.panel,-1,self.prompt),0,wx.ALIGN_CENTER)
422        valItem = wx.TextCtrl(self.panel,-1,value=self.format%(self.value),style=wx.TE_PROCESS_ENTER)
423        mainSizer.Add(valItem,0,wx.ALIGN_CENTER)
424        valItem.Bind(wx.EVT_TEXT_ENTER,OnValItem)
425        valItem.Bind(wx.EVT_KILL_FOCUS,OnValItem)
426        OkBtn = wx.Button(self.panel,-1,"Ok")
427        OkBtn.Bind(wx.EVT_BUTTON, self.OnOk)
428        CancelBtn = wx.Button(self.panel,-1,'Cancel')
429        CancelBtn.Bind(wx.EVT_BUTTON, self.OnCancel)
430        btnSizer = wx.BoxSizer(wx.HORIZONTAL)
431        btnSizer.Add((20,20),1)
432        btnSizer.Add(OkBtn)
433        btnSizer.Add(CancelBtn)
434        btnSizer.Add((20,20),1)
435        mainSizer.Add(btnSizer,0,wx.EXPAND|wx.BOTTOM|wx.TOP, 10)
436        self.panel.SetSizer(mainSizer)
437        self.panel.Fit()
438        self.Fit()
439
440    def GetValue(self):
441        return self.value
442       
443    def OnOk(self,event):
444        parent = self.GetParent()
445        parent.Raise()
446        self.EndModal(wx.ID_OK)             
447       
448    def OnCancel(self,event):
449        parent = self.GetParent()
450        parent.Raise()
451        self.EndModal(wx.ID_CANCEL)
452       
453class GridFractionEditor(wg.PyGridCellEditor):
454    def __init__(self,grid):
455        wg.PyGridCellEditor.__init__(self)
456
457    def Create(self, parent, id, evtHandler):
458        self._tc = wx.TextCtrl(parent, id, "")
459        self._tc.SetInsertionPoint(0)
460        self.SetControl(self._tc)
461
462        if evtHandler:
463            self._tc.PushEventHandler(evtHandler)
464
465        self._tc.Bind(wx.EVT_CHAR, self.OnChar)
466
467    def SetSize(self, rect):
468        self._tc.SetDimensions(rect.x, rect.y, rect.width+2, rect.height+2,
469                               wx.SIZE_ALLOW_MINUS_ONE)
470
471    def BeginEdit(self, row, col, grid):
472        self.startValue = grid.GetTable().GetValue(row, col)
473        self._tc.SetValue(str(self.startValue))
474        self._tc.SetInsertionPointEnd()
475        self._tc.SetFocus()
476        self._tc.SetSelection(0, self._tc.GetLastPosition())
477
478    def EndEdit(self, row, col, grid):
479        changed = False
480
481        val = self._tc.GetValue().lower()
482       
483        if val != self.startValue:
484            changed = True
485            neg = False
486            if '-' in val:
487                neg = True
488            if '/' in val and '.' not in val:
489                val += '.'
490            elif 's' in val and not 'sind(' in val:
491                if neg:
492                    val = '-sind('+val.strip('-s')+')'
493                else:
494                    val = 'sind('+val.strip('s')+')'
495            elif 'c' in val and not 'cosd(' in val:
496                if neg:
497                    val = '-cosd('+val.strip('-c')+')'
498                else:
499                    val = 'cosd('+val.strip('c')+')'
500            try:
501                val = float(eval(val))
502            except (SyntaxError,NameError):
503                val = self.startValue
504            grid.GetTable().SetValue(row, col, val) # update the table
505
506        self.startValue = ''
507        self._tc.SetValue('')
508        return changed
509
510    def Reset(self):
511        self._tc.SetValue(self.startValue)
512        self._tc.SetInsertionPointEnd()
513
514    def Clone(self):
515        return GridFractionEditor(grid)
516
517    def StartingKey(self, evt):
518        self.OnChar(evt)
519        if evt.GetSkipped():
520            self._tc.EmulateKeyPress(evt)
521
522    def OnChar(self, evt):
523        key = evt.GetKeyCode()
524        if key == 15:
525            return
526        if key > 255:
527            evt.Skip()
528            return
529        char = chr(key)
530        if char in '.+-/0123456789cosind()':
531            self._tc.WriteText(char)
532        else:
533            evt.Skip()
534
535class MyHelp(wx.Menu):
536    '''This class creates the contents of a help menu.
537    The menu will start with two entries:
538      'Help on <helpType>': where helpType is a reference to an HTML page to
539      be opened
540      About: opens an About dialog using OnHelpAbout. N.B. on the Mac this
541      gets moved to the App menu to be consistent with Apple style.
542    NOTE: the title when appending this menu should be '&Help' so the wx handles
543    it correctly. BHT
544    '''
545    def __init__(self,frame,helpType=None,helpLbl=None,morehelpitems=[],title=''):
546        wx.Menu.__init__(self,title)
547        self.HelpById = {}
548        self.frame = frame
549        self.Append(help='', id=wx.ID_ABOUT, kind=wx.ITEM_NORMAL,
550            text='&About GSAS-II')
551        frame.Bind(wx.EVT_MENU, self.OnHelpAbout, id=wx.ID_ABOUT)
552        if GSASIIpath.whichsvn():
553            helpobj = self.Append(
554                help='', id=wx.ID_ANY, kind=wx.ITEM_NORMAL,
555                text='&Check for updates')
556            frame.Bind(wx.EVT_MENU, self.OnCheckUpdates, helpobj)
557        for lbl,indx in morehelpitems:
558            helpobj = self.Append(text=lbl,
559                id=wx.ID_ANY, kind=wx.ITEM_NORMAL)
560            frame.Bind(wx.EVT_MENU, self.OnHelpById, helpobj)
561            self.HelpById[helpobj.GetId()] = indx
562        # add a help item only when helpType is specified
563        if helpType is not None:
564            self.AppendSeparator()
565            if helpLbl is None: helpLbl = helpType
566            helpobj = self.Append(text='Help on '+helpLbl,
567                                  id=wx.ID_ANY, kind=wx.ITEM_NORMAL)
568            frame.Bind(wx.EVT_MENU, self.OnHelpById, helpobj)
569            self.HelpById[helpobj.GetId()] = helpType
570       
571    def OnHelpById(self,event):
572        '''Called when Help on... is pressed in a menu. Brings up
573        a web page for documentation.
574        '''
575        helpType = self.HelpById.get(event.GetId())
576        if helpType is None:
577            print 'Error: help lookup failed!',event.GetEventObject()
578            print 'id=',event.GetId()
579        else:
580            ShowHelp(helpType,self.frame)
581
582    def OnHelpAbout(self, event):
583        "Display an 'About GSAS-II' box"
584        global __version__
585        info = wx.AboutDialogInfo()
586        info.Name = 'GSAS-II'
587        info.Version = __version__ + ' Revision '+str(GSASIIpath.GetVersionNumber())
588        info.Copyright = '''
589Robert B. Von Dreele & Brian H. Toby
590Argonne National Laboratory(C)
591This product includes software developed
592by the UChicago Argonne, LLC, as
593Operator of Argonne National Laboratory.         '''
594        info.Description = '''
595General Structure Analysis System - GSAS-II
596'''
597        wx.AboutBox(info)
598
599    def OnCheckUpdates(self,event):
600        '''Check if the GSAS-II repository has an update for the current source files
601        and perform that update if requested.
602        '''
603        if not GSASIIpath.whichsvn():
604            dlg = wx.MessageDialog(self,'No Subversion','Cannot update GSAS-II because subversion (svn) '+
605                                   'was not found.'
606                                   ,wx.OK)
607            dlg.ShowModal()
608            return
609        wx.BeginBusyCursor()
610        local = GSASIIpath.svnGetRev()
611        if local is None: 
612            wx.EndBusyCursor()
613            dlg = wx.MessageDialog(self.frame,
614                                   'Unable to run subversion on the GSAS-II current directory. Is GSAS-II installed correctly?',
615                                   'Subversion error',
616                                   wx.OK)
617            dlg.ShowModal()
618            return
619        print 'Installed GSAS-II version: '+local
620        repos = GSASIIpath.svnGetRev(local=False)
621        wx.EndBusyCursor()
622        if repos is None: 
623            dlg = wx.MessageDialog(self.frame,
624                                   'Unable to access the GSAS-II server. Is this computer on the internet?',
625                                   'Server unavailable',
626                                   wx.OK)
627            dlg.ShowModal()
628            return
629        print 'GSAS-II version on server: '+repos
630        if local == repos:
631            dlg = wx.MessageDialog(self.frame,
632                                   'GSAS-II is up-to-date. Version '+local+' is already loaded.',
633                                   'GSAS-II Up-to-date',
634                                   wx.OK)
635            dlg.ShowModal()
636            return
637        mods = GSASIIpath.svnFindLocalChanges()
638        if mods:
639            dlg = wx.MessageDialog(self.frame,
640                                   'You have version '+local+
641                                   ' of GSAS-II installed, but the current version is '+repos+
642                                   '. However, you have modified '+str(len(mods))+
643                                   ' file(s) on your local computer have been modified.'
644                                   ' Updating could wipe out your local changes. Press OK to start an update:',
645                                   'Local GSAS-II Mods',
646                                   wx.OK|wx.CANCEL)
647            if dlg.ShowModal() != wx.ID_OK: return
648        else:
649            dlg = wx.MessageDialog(self.frame,
650                                   'You have version '+local+
651                                   ' of GSAS-II installed, but the current version is '+repos+
652                                   '. Press OK to start an update:',
653                                   'GSAS-II Updates',
654                                   wx.OK|wx.CANCEL)
655            if dlg.ShowModal() != wx.ID_OK: return
656        print 'start updates'
657        wx.BeginBusyCursor()
658        moddict = GSASIIpath.svnUpdateDir()
659        wx.EndBusyCursor()
660        if moddict is None: 
661            dlg = wx.MessageDialog(self.frame,
662                                   'Error accessing the GSAS-II server or performing the update. '+
663                                   'Try again later or perform a manual update',
664                                   'Update Error',
665                                   wx.OK)
666            dlg.ShowModal()
667            return
668        modsbytype = {}
669        for key in moddict:
670            typ = moddict[key]
671            if modsbytype.get(typ) is None:
672                modsbytype[typ] = []
673            modsbytype[typ].append(key)
674        msg = 'Update was completed. Changes will take effect when GSAS-II is next updated. The following files were updated, ordered by status:'
675        for key in modsbytype:
676            msg += '\n' + key + ':\n\t'
677            for fil in modsbytype:
678                msg += fil + ', '
679        dlg = wx.MessageDialog(self.frame,msg, 'Update Completed', wx.OK)
680        dlg.ShowModal()
681        return
682
683class AddHelp(wx.Menu):
684    '''This class a single entry for the help menu (used on the Mac only):
685      'Help on <helpType>': where helpType is a reference to an HTML page to
686      be opened
687    NOTE: the title when appending this menu should be '&Help' so the wx handles
688    it correctly. BHT
689    '''
690    def __init__(self,frame,helpType,helpLbl=None,title=''):
691        wx.Menu.__init__(self,title)
692        self.frame = frame
693        if helpLbl is None: helpLbl = helpType
694        # add a help item only when helpType is specified
695        helpobj = self.Append(text='Help on '+helpLbl,
696                              id=wx.ID_ANY, kind=wx.ITEM_NORMAL)
697        frame.Bind(wx.EVT_MENU, self.OnHelpById, helpobj)
698        self.HelpById = helpType
699       
700    def OnHelpById(self,event):
701        '''Called when Help on... is pressed in a menu. Brings up
702        a web page for documentation.
703        '''
704        ShowHelp(self.HelpById,self.frame)
705
706class MyHtmlPanel(wx.Panel):
707    '''Defines a panel to display Help information'''
708    def __init__(self, frame, id):
709        self.frame = frame
710        wx.Panel.__init__(self, frame, id)
711        sizer = wx.BoxSizer(wx.VERTICAL)
712        back = wx.Button(self, -1, "Back")
713        back.Bind(wx.EVT_BUTTON, self.OnBack)
714        self.htmlwin = G2HtmlWindow(self, id, size=(750,450))
715        sizer.Add(self.htmlwin, 1,wx.EXPAND)
716        sizer.Add(back, 0, wx.ALIGN_LEFT, 0)
717        self.SetSizer(sizer)
718        sizer.Fit(frame)       
719        self.Bind(wx.EVT_SIZE,self.OnSize)
720    def OnSize(self,event):         #does the job but weirdly!!
721        anchor = self.htmlwin.GetOpenedAnchor()
722        if anchor:           
723            self.htmlwin.ScrollToAnchor(anchor)
724            wx.CallAfter(self.htmlwin.ScrollToAnchor,anchor)
725            event.Skip()
726    def OnBack(self, event):
727        self.htmlwin.HistoryBack()
728    def LoadFile(self,file):
729        pos = file.rfind('#')
730        if pos != -1:
731            helpfile = file[:pos]
732            helpanchor = file[pos+1:]
733        else:
734            helpfile = file
735            helpanchor = None
736        self.htmlwin.LoadPage(helpfile)
737        if helpanchor is not None:
738            self.htmlwin.ScrollToAnchor(helpanchor)
739            xs,ys = self.htmlwin.GetViewStart()
740            self.htmlwin.Scroll(xs,ys-1)
741
742class G2HtmlWindow(wx.html.HtmlWindow):
743    '''Displays help information in a primitive HTML browser type window
744    '''
745    def __init__(self, parent, *args, **kwargs):
746        self.parent = parent
747        wx.html.HtmlWindow.__init__(self, parent, *args, **kwargs)
748    def LoadPage(self, *args, **kwargs):
749        wx.html.HtmlWindow.LoadPage(self, *args, **kwargs)
750        self.TitlePage()
751    def OnLinkClicked(self, *args, **kwargs):
752        wx.html.HtmlWindow.OnLinkClicked(self, *args, **kwargs)
753        xs,ys = self.GetViewStart()
754        self.Scroll(xs,ys-1)
755        self.TitlePage()
756    def HistoryBack(self, *args, **kwargs):
757        wx.html.HtmlWindow.HistoryBack(self, *args, **kwargs)
758        self.TitlePage()
759    def TitlePage(self):
760        self.parent.frame.SetTitle(self.GetOpenedPage() + ' -- ' + 
761            self.GetOpenedPageTitle())
762
763class DataFrame(wx.Frame):
764    '''Create the dataframe window and its menus
765    '''
766    def PrefillDataMenu(self,menu,helpType,helpLbl=None,empty=False):
767        '''Create the "standard" part of data frame menus. Note that on Linux and
768        Windows, this is the standard help Menu. On Mac, this menu duplicates the
769        tree menu, but adds an extra help command for the data item and a separator.
770        '''
771        self.datamenu = menu
772        self.helpType = helpType
773        self.helpLbl = helpLbl
774        if sys.platform == "darwin": # mac                         
775            self.G2frame.FillMainMenu(menu) # add the data tree menu items
776            if not empty:
777                menu.Append(wx.Menu(title=''),title='|') # add a separator
778        #    menu.Append(AddHelp(self.G2frame,helpType=helpType, helpLbl=helpLbl),
779        #                title='&Help')
780        #else: # other
781        #    menu.Append(menu=MyHelp(self,helpType=helpType, helpLbl=helpLbl),
782        #                title='&Help')
783       
784    def PostfillDataMenu(self,empty=False):
785        '''Create the "standard" part of data frame menus. Note that on Linux and
786        Windows, this is the standard help Menu. On Mac, this menu duplicates the
787        tree menu, but adds an extra help command for the data item and a separator.
788        '''
789        menu = self.datamenu
790        helpType = self.helpType
791        helpLbl = self.helpLbl
792        if sys.platform == "darwin": # mac
793            if not empty:
794                menu.Append(wx.Menu(title=''),title='|') # add another separator
795            menu.Append(AddHelp(self.G2frame,helpType=helpType, helpLbl=helpLbl),
796                        title='&Help')
797        else: # other
798            menu.Append(menu=MyHelp(self,helpType=helpType, helpLbl=helpLbl),
799                        title='&Help')
800
801    def _init_menus(self):
802       
803# define all GSAS-II data frame menus       
804
805# for use where no menu or data frame help is provided
806        self.BlankMenu = wx.MenuBar()
807       
808# Controls
809        self.ControlsMenu = wx.MenuBar()
810        self.PrefillDataMenu(self.ControlsMenu,helpType='Controls',empty=True)
811        self.PostfillDataMenu(empty=True)
812       
813# Notebook
814        self.DataNotebookMenu = wx.MenuBar() 
815        self.PrefillDataMenu(self.DataNotebookMenu,helpType='Notebook',empty=True)
816        self.PostfillDataMenu(empty=True)
817       
818# Comments
819        self.DataCommentsMenu = wx.MenuBar()
820        self.PrefillDataMenu(self.DataCommentsMenu,helpType='Comments',empty=True)
821        self.PostfillDataMenu(empty=True)
822       
823# Constraints
824        self.ConstraintMenu = wx.MenuBar()
825        self.PrefillDataMenu(self.ConstraintMenu,helpType='Constraints')
826        self.ConstraintEdit = wx.Menu(title='')
827        self.ConstraintMenu.Append(menu=self.ConstraintEdit, title='Edit')
828        self.ConstraintEdit.Append(id=wxID_HOLDADD, kind=wx.ITEM_NORMAL,text='Add hold',
829            help='Add hold on a parameter value')
830        self.ConstraintEdit.Append(id=wxID_EQUIVADD, kind=wx.ITEM_NORMAL,text='Add equivalence',
831            help='Add equivalence between parameter values')
832        self.ConstraintEdit.Append(id=wxID_CONSTRAINTADD, kind=wx.ITEM_NORMAL,text='Add constraint',
833            help='Add constraint on parameter values')
834        self.ConstraintEdit.Append(id=wxID_FUNCTADD, kind=wx.ITEM_NORMAL,text='Add New Var',
835            help='Add variable composed of existing parameter')
836        self.PostfillDataMenu()
837       
838# Rigid bodies
839        self.VectorRBEdit = wx.Menu(title='')
840        self.VectorRBEdit.Append(id=wxID_RIGIDBODYADD, kind=wx.ITEM_NORMAL,text='Add rigid body',
841            help='Add vector rigid body')
842        self.ResidueRBMenu = wx.Menu(title='')
843        self.ResidueRBMenu.Append(id=wxID_RIGIDBODYIMPORT, kind=wx.ITEM_NORMAL,text='Import XYZ',
844            help='Import rigid body XYZ from file')
845        self.ResidueRBMenu.Append(id=wxID_RESIDUETORSSEQ, kind=wx.ITEM_NORMAL,text='Define sequence',
846            help='Define torsion sequence')
847        self.ResidueRBMenu.Append(id=wxID_RIGIDBODYADD, kind=wx.ITEM_NORMAL,text='Import residues',
848            help='Import residue rigid bodies from macro file')
849           
850        self.RigidBodyMenu = wx.MenuBar()
851        self.PrefillDataMenu(self.RigidBodyMenu,helpType='Rigid bodies')
852        self.RigidBodyMenu.Append(menu=self.VectorRBEdit, title='Edit')       
853        self.PostfillDataMenu()
854           
855# Restraints
856        self.RestraintEdit = wx.Menu(title='')
857        self.RestraintEdit.Append(id=wxID_RESTSELPHASE, kind=wx.ITEM_NORMAL,text='Select phase',
858            help='Select phase')
859        self.RestraintEdit.Append(id=wxID_RESTRAINTADD, kind=wx.ITEM_NORMAL,text='Add restraints',
860            help='Add restraints')
861        self.RestraintEdit.Enable(wxID_RESTRAINTADD,True)    #gets disenabled if macromolecule phase
862        self.RestraintEdit.Append(id=wxID_AARESTRAINTADD, kind=wx.ITEM_NORMAL,text='Add residue restraints',
863            help='Add residue based restraints for macromolecules from macro file')
864        self.RestraintEdit.Enable(wxID_AARESTRAINTADD,False)    #gets enabled if macromolecule phase
865        self.RestraintEdit.Append(id=wxID_AARESTRAINTPLOT, kind=wx.ITEM_NORMAL,text='Plot residue restraints',
866            help='Plot selected residue based restraints for macromolecules from macro file')
867        self.RestraintEdit.Enable(wxID_AARESTRAINTPLOT,False)    #gets enabled if macromolecule phase
868        self.RestraintEdit.Append(id=wxID_RESRCHANGEVAL, kind=wx.ITEM_NORMAL,text='Change value',
869            help='Change observed value')
870        self.RestraintEdit.Append(id=wxID_RESTCHANGEESD, kind=wx.ITEM_NORMAL,text='Change esd',
871            help='Change esd in observed value')
872        self.RestraintEdit.Append(id=wxID_RESTDELETE, kind=wx.ITEM_NORMAL,text='Delete restraints',
873            help='Delete selected restraints')
874
875        self.RestraintMenu = wx.MenuBar()
876        self.PrefillDataMenu(self.RestraintMenu,helpType='Restraints')
877        self.RestraintMenu.Append(menu=self.RestraintEdit, title='Edit')
878        self.PostfillDataMenu()
879           
880# Sequential results
881        self.SequentialMenu = wx.MenuBar()
882        self.PrefillDataMenu(self.SequentialMenu,helpType='Sequential',helpLbl='Sequential Refinement')
883        self.SequentialFile = wx.Menu(title='')
884        self.SequentialMenu.Append(menu=self.SequentialFile, title='File')
885        self.SequentialFile.Append(id=wxID_SAVESEQSEL, kind=wx.ITEM_NORMAL,text='Save...',
886            help='Save selected sequential refinement results')
887        self.PostfillDataMenu()
888           
889# PDR
890        self.ErrorMenu = wx.MenuBar()
891        self.PrefillDataMenu(self.ErrorMenu,helpType='PWD Analysis',helpLbl='Powder Fit Error Analysis')
892        self.ErrorAnal = wx.Menu(title='')
893        self.ErrorMenu.Append(menu=self.ErrorAnal,title='Analysis')
894        self.ErrorAnal.Append(id=wxID_PWDANALYSIS,kind=wx.ITEM_NORMAL,text='Analyze',
895            help='Error analysis on powder pattern')
896        self.PostfillDataMenu()
897           
898# PDR / Limits
899        self.LimitMenu = wx.MenuBar()
900        self.PrefillDataMenu(self.LimitMenu,helpType='Limits')
901        self.LimitEdit = wx.Menu(title='')
902        self.LimitMenu.Append(menu=self.LimitEdit, title='File')
903        self.LimitEdit.Append(id=wxID_LIMITCOPY, kind=wx.ITEM_NORMAL,text='Copy',
904            help='Copy limits to other histograms')
905        self.PostfillDataMenu()
906           
907# PDR / Background
908        self.BackMenu = wx.MenuBar()
909        self.PrefillDataMenu(self.BackMenu,helpType='Background')
910        self.BackEdit = wx.Menu(title='')
911        self.BackMenu.Append(menu=self.BackEdit, title='File')
912        self.BackEdit.Append(id=wxID_BACKCOPY, kind=wx.ITEM_NORMAL,text='Copy',
913            help='Copy background parameters to other histograms')
914        self.BackEdit.Append(id=wxID_BACKFLAGCOPY, kind=wx.ITEM_NORMAL,text='Copy flags',
915            help='Copy background refinement flags to other histograms')
916        self.PostfillDataMenu()
917           
918# PDR / Instrument Parameters
919        self.InstMenu = wx.MenuBar()
920        self.PrefillDataMenu(self.InstMenu,helpType='Instrument Parameters')
921        self.InstEdit = wx.Menu(title='')
922        self.InstMenu.Append(menu=self.InstEdit, title='Operations')
923        self.InstEdit.Append(help='Reset instrument profile parameters to default', 
924            id=wxID_INSTLOAD, kind=wx.ITEM_NORMAL,text='Load profile...')
925        self.InstEdit.Append(help='Load instrument profile parameters from file', 
926            id=wxID_INSTSAVE, kind=wx.ITEM_NORMAL,text='Save profile...')
927        self.InstEdit.Append(help='Save instrument profile parameters to file', 
928            id=wxID_INSTPRMRESET, kind=wx.ITEM_NORMAL,text='Reset profile')
929        self.InstEdit.Append(help='Copy instrument profile parameters to other histograms', 
930            id=wxID_INSTCOPY, kind=wx.ITEM_NORMAL,text='Copy')
931        self.InstEdit.Append(id=wxID_INSTFLAGCOPY, kind=wx.ITEM_NORMAL,text='Copy flags',
932            help='Copy instrument parameter refinement flags to other histograms')
933#        self.InstEdit.Append(help='Change radiation type (Ka12 - synch)',
934#            id=wxID_CHANGEWAVETYPE, kind=wx.ITEM_NORMAL,text='Change radiation')
935        self.PostfillDataMenu()
936       
937# PDR / Sample Parameters
938        self.SampleMenu = wx.MenuBar()
939        self.PrefillDataMenu(self.SampleMenu,helpType='Sample Parameters')
940        self.SampleEdit = wx.Menu(title='')
941        self.SampleMenu.Append(menu=self.SampleEdit, title='File')
942        self.SampleEdit.Append(id=wxID_SAMPLELOAD, kind=wx.ITEM_NORMAL,text='Load',
943            help='Load sample parameters from file')
944        self.SampleEdit.Append(id=wxID_SAMPLESAVE, kind=wx.ITEM_NORMAL,text='Save',
945            help='Save sample parameters to file')
946        self.SampleEdit.Append(id=wxID_SAMPLECOPY, kind=wx.ITEM_NORMAL,text='Copy',
947            help='Copy refinable sample parameters to other histograms')
948        self.SampleEdit.Append(id=wxID_SAMPLEFLAGCOPY, kind=wx.ITEM_NORMAL,text='Copy flags',
949            help='Copy sample parameter refinement flags to other histograms')
950        self.PostfillDataMenu()
951
952# PDR / Peak List
953        self.PeakMenu = wx.MenuBar()
954        self.PrefillDataMenu(self.PeakMenu,helpType='Peak List')
955        self.PeakEdit = wx.Menu(title='')
956        self.PeakMenu.Append(menu=self.PeakEdit, title='Peak Fitting')
957        self.AutoSearch = self.PeakEdit.Append(help='Automatic peak search', 
958            id=wxID_AUTOSEARCH, kind=wx.ITEM_NORMAL,text='Auto search')
959        self.UnDo = self.PeakEdit.Append(help='Undo last least squares refinement', 
960            id=wxID_UNDO, kind=wx.ITEM_NORMAL,text='UnDo')
961        self.PeakFit = self.PeakEdit.Append(id=wxID_LSQPEAKFIT, kind=wx.ITEM_NORMAL,text='LSQ PeakFit', 
962            help='Peak fitting via least-squares' )
963        self.PFOneCycle = self.PeakEdit.Append(id=wxID_LSQONECYCLE, kind=wx.ITEM_NORMAL,text='LSQ one cycle', 
964            help='One cycle of Peak fitting via least-squares' )
965        self.PeakEdit.Append(id=wxID_RESETSIGGAM, kind=wx.ITEM_NORMAL, 
966            text='Reset sig and gam',help='Reset sigma and gamma to global fit' )
967        self.PeakEdit.Append(id=wxID_CLEARPEAKS, kind=wx.ITEM_NORMAL,text='Clear peaks', 
968            help='Clear the peak list' )
969        self.PostfillDataMenu()
970        self.UnDo.Enable(False)
971        self.PeakFit.Enable(False)
972        self.PFOneCycle.Enable(False)
973       
974# PDR / Index Peak List
975        self.IndPeaksMenu = wx.MenuBar()
976        self.PrefillDataMenu(self.IndPeaksMenu,helpType='Index Peak List')
977        self.IndPeaksEdit = wx.Menu(title='')
978        self.IndPeaksMenu.Append(menu=self.IndPeaksEdit,title='Operations')
979        self.IndPeaksEdit.Append(help='Load/Reload index peaks from peak list',id=wxID_INDXRELOAD, 
980            kind=wx.ITEM_NORMAL,text='Load/Reload')
981        self.PostfillDataMenu()
982       
983# PDR / Unit Cells List
984        self.IndexMenu = wx.MenuBar()
985        self.PrefillDataMenu(self.IndexMenu,helpType='Unit Cells List')
986        self.IndexEdit = wx.Menu(title='')
987        self.IndexMenu.Append(menu=self.IndexEdit, title='Cell Index/Refine')
988        self.IndexPeaks = self.IndexEdit.Append(help='', id=wxID_INDEXPEAKS, kind=wx.ITEM_NORMAL,
989            text='Index Cell')
990        self.CopyCell = self.IndexEdit.Append( id=wxID_COPYCELL, kind=wx.ITEM_NORMAL,text='Copy Cell', 
991            help='Copy selected unit cell from indexing to cell refinement fields')
992        self.RefineCell = self.IndexEdit.Append( id=wxID_REFINECELL, kind=wx.ITEM_NORMAL, 
993            text='Refine Cell',help='Refine unit cell parameters from indexed peaks')
994        self.MakeNewPhase = self.IndexEdit.Append( id=wxID_MAKENEWPHASE, kind=wx.ITEM_NORMAL,
995            text='Make new phase',help='Make new phase from selected unit cell')
996        self.PostfillDataMenu()
997        self.IndexPeaks.Enable(False)
998        self.CopyCell.Enable(False)
999        self.RefineCell.Enable(False)
1000        self.MakeNewPhase.Enable(False)
1001       
1002# PDR / Reflection Lists
1003        self.ReflMenu = wx.MenuBar()
1004        self.PrefillDataMenu(self.ReflMenu,helpType='Reflection List')
1005        self.ReflEdit = wx.Menu(title='')
1006        self.ReflMenu.Append(menu=self.ReflEdit, title='Reflection List')
1007        self.SelectPhase = self.ReflEdit.Append(help='Select phase for reflection list',id=wxID_SELECTPHASE, 
1008            kind=wx.ITEM_NORMAL,text='Select phase')
1009        self.PostfillDataMenu()
1010       
1011# IMG / Image Controls
1012        self.ImageMenu = wx.MenuBar()
1013        self.PrefillDataMenu(self.ImageMenu,helpType='Image Controls')
1014        self.ImageEdit = wx.Menu(title='')
1015        self.ImageMenu.Append(menu=self.ImageEdit, title='Operations')
1016        self.ImageEdit.Append(help='Calibrate detector by fitting to calibrant lines', 
1017            id=wxID_IMCALIBRATE, kind=wx.ITEM_NORMAL,text='Calibrate')
1018        self.ImageEdit.Append(help='Recalibrate detector by fitting to calibrant lines', 
1019            id=wxID_IMRECALIBRATE, kind=wx.ITEM_NORMAL,text='Recalibrate')
1020        self.ImageEdit.Append(help='Clear calibration data points and rings',id=wxID_IMCLEARCALIB, 
1021            kind=wx.ITEM_NORMAL,text='Clear calibration')
1022        self.ImageEdit.Append(help='Integrate selected image',id=wxID_IMINTEGRATE, 
1023            kind=wx.ITEM_NORMAL,text='Integrate')
1024        self.ImageEdit.Append(help='Integrate all images selected from list',id=wxID_INTEGRATEALL,
1025            kind=wx.ITEM_NORMAL,text='Integrate all')
1026        self.ImageEdit.Append(help='Copy image controls to other images', 
1027            id=wxID_IMCOPYCONTROLS, kind=wx.ITEM_NORMAL,text='Copy Controls')
1028        self.ImageEdit.Append(help='Save image controls to file', 
1029            id=wxID_IMSAVECONTROLS, kind=wx.ITEM_NORMAL,text='Save Controls')
1030        self.ImageEdit.Append(help='Load image controls from file', 
1031            id=wxID_IMLOADCONTROLS, kind=wx.ITEM_NORMAL,text='Load Controls')
1032        self.PostfillDataMenu()
1033           
1034# IMG / Masks
1035        self.MaskMenu = wx.MenuBar()
1036        self.PrefillDataMenu(self.MaskMenu,helpType='Image Masks')
1037        self.MaskEdit = wx.Menu(title='')
1038        self.MaskMenu.Append(menu=self.MaskEdit, title='Operations')
1039        self.MaskEdit.Append(help='Copy mask to other images', 
1040            id=wxID_MASKCOPY, kind=wx.ITEM_NORMAL,text='Copy mask')
1041        self.MaskEdit.Append(help='Save mask to file', 
1042            id=wxID_MASKSAVE, kind=wx.ITEM_NORMAL,text='Save mask')
1043        self.MaskEdit.Append(help='Load mask from file', 
1044            id=wxID_MASKLOAD, kind=wx.ITEM_NORMAL,text='Load mask')
1045        self.PostfillDataMenu()
1046           
1047# IMG / Stress/Strain
1048
1049        self.StrStaMenu = wx.MenuBar()
1050        self.PrefillDataMenu(self.StrStaMenu,helpType='Stress/Strain')
1051        self.StrStaEdit = wx.Menu(title='')
1052        self.StrStaMenu.Append(menu=self.StrStaEdit, title='Operations')
1053        self.StrStaEdit.Append(help='Append d-zero for one ring', 
1054            id=wxID_APPENDDZERO, kind=wx.ITEM_NORMAL,text='Append d-zero')
1055        self.StrStaEdit.Append(help='Fit stress/strain data', 
1056            id=wxID_STRSTAFIT, kind=wx.ITEM_NORMAL,text='Fit stress/strain')
1057        self.StrStaEdit.Append(help='Copy stress/strain data to other images', 
1058            id=wxID_STRSTACOPY, kind=wx.ITEM_NORMAL,text='Copy stress/strain')
1059        self.StrStaEdit.Append(help='Save stress/strain data to file', 
1060            id=wxID_STRSTASAVE, kind=wx.ITEM_NORMAL,text='Save stress/strain')
1061        self.StrStaEdit.Append(help='Load stress/strain data from file', 
1062            id=wxID_STRSTALOAD, kind=wx.ITEM_NORMAL,text='Load stress/strain')
1063        self.PostfillDataMenu()
1064           
1065# PDF / PDF Controls
1066        self.PDFMenu = wx.MenuBar()
1067        self.PrefillDataMenu(self.PDFMenu,helpType='PDF Controls')
1068        self.PDFEdit = wx.Menu(title='')
1069        self.PDFMenu.Append(menu=self.PDFEdit, title='PDF Controls')
1070        self.PDFEdit.Append(help='Add element to sample composition',id=wxID_PDFADDELEMENT, kind=wx.ITEM_NORMAL,
1071            text='Add element')
1072        self.PDFEdit.Append(help='Delete element from sample composition',id=wxID_PDFDELELEMENT, kind=wx.ITEM_NORMAL,
1073            text='Delete element')
1074        self.PDFEdit.Append(help='Copy PDF controls', id=wxID_PDFCOPYCONTROLS, kind=wx.ITEM_NORMAL,
1075            text='Copy controls')
1076#        self.PDFEdit.Append(help='Load PDF controls from file',id=wxID_PDFLOADCONTROLS, kind=wx.ITEM_NORMAL,
1077#            text='Load Controls')
1078#        self.PDFEdit.Append(help='Save PDF controls to file', id=wxID_PDFSAVECONTROLS, kind=wx.ITEM_NORMAL,
1079#            text='Save controls')
1080        self.PDFEdit.Append(help='Compute PDF', id=wxID_PDFCOMPUTE, kind=wx.ITEM_NORMAL,
1081            text='Compute PDF')
1082        self.PDFEdit.Append(help='Compute all PDFs', id=wxID_PDFCOMPUTEALL, kind=wx.ITEM_NORMAL,
1083            text='Compute all PDFs')
1084        self.PostfillDataMenu()
1085           
1086# Phase / General tab
1087
1088        self.DataGeneral = wx.MenuBar()
1089        self.PrefillDataMenu(self.DataGeneral,helpType='General', helpLbl='Phase/General')
1090        self.GeneralCalc = wx.Menu(title='')
1091        self.DataGeneral.Append(menu=self.GeneralCalc,title='Compute')
1092        self.GeneralCalc.Append(help='Compute Fourier map',id=wxID_FOURCALC, kind=wx.ITEM_NORMAL,
1093            text='Fourier map')
1094        self.GeneralCalc.Append(help='Search Fourier map',id=wxID_FOURSEARCH, kind=wx.ITEM_NORMAL,
1095            text='Search map')
1096        self.GeneralCalc.Append(help='Run charge flipping',id=wxID_CHARGEFLIP, kind=wx.ITEM_NORMAL,
1097            text='Charge flipping')
1098        self.GeneralCalc.Append(help='Clear map',id=wxID_FOURCLEAR, kind=wx.ITEM_NORMAL,
1099            text='Clear map')
1100        self.PostfillDataMenu()
1101       
1102# Phase / Data tab
1103        self.DataMenu = wx.MenuBar()
1104        self.PrefillDataMenu(self.DataMenu,helpType='Data', helpLbl='Phase/Data')
1105        self.DataEdit = wx.Menu(title='')
1106        self.DataMenu.Append(menu=self.DataEdit, title='Edit')
1107        self.DataEdit.Append(id=wxID_PWDRADD, kind=wx.ITEM_NORMAL,text='Add powder histograms',
1108            help='Select new powder histograms to be used for this phase')
1109        self.DataEdit.Append(id=wxID_HKLFADD, kind=wx.ITEM_NORMAL,text='Add single crystal histograms',
1110            help='Select new single crystal histograms to be used for this phase')
1111        self.DataEdit.Append(id=wxID_DATADELETE, kind=wx.ITEM_NORMAL,text='Delete histograms',
1112            help='Delete histograms from use for this phase')
1113        self.PostfillDataMenu()
1114           
1115# Phase / Atoms tab
1116        self.AtomsMenu = wx.MenuBar()
1117        self.PrefillDataMenu(self.AtomsMenu,helpType='Atoms')
1118        self.AtomEdit = wx.Menu(title='')
1119        self.AtomCompute = wx.Menu(title='')
1120        self.AtomsMenu.Append(menu=self.AtomEdit, title='Edit')
1121        self.AtomsMenu.Append(menu=self.AtomCompute, title='Compute')
1122        self.AtomEdit.Append(id=wxID_ATOMSEDITADD, kind=wx.ITEM_NORMAL,text='Append atom',
1123            help='Appended as an H atom')
1124        self.AtomEdit.Append(id=wxID_ATOMSVIEWADD, kind=wx.ITEM_NORMAL,text='Append view point',
1125            help='Appended as an H atom')
1126        self.AtomEdit.Append(id=wxID_RBAPPEND, kind=wx.ITEM_NORMAL,text='Append rigid body',
1127            help='Append atoms for rigid body')
1128        self.AtomEdit.Append(id=wxID_ATOMSEDITINSERT, kind=wx.ITEM_NORMAL,text='Insert atom',
1129            help='Select atom row to insert before; inserted as an H atom')
1130        self.AtomEdit.Append(id=wxID_ATOMVIEWINSERT, kind=wx.ITEM_NORMAL,text='Insert view point',
1131            help='Select atom row to insert before; inserted as an H atom')
1132        self.AtomEdit.Append(id=wxID_ATOMMOVE, kind=wx.ITEM_NORMAL,text='Move atom to view point',
1133            help='Select single atom to move')
1134        self.AtomEdit.Append(id=wxID_ATOMSEDITDELETE, kind=wx.ITEM_NORMAL,text='Delete atom',
1135            help='Select atoms to delete first')
1136        self.AtomEdit.Append(id=wxID_ATOMSREFINE, kind=wx.ITEM_NORMAL,text='Set atom refinement flags',
1137            help='Select atoms to refine first')
1138        self.AtomEdit.Append(id=wxID_ATOMSMODIFY, kind=wx.ITEM_NORMAL,text='Modify atom parameters',
1139            help='Select atoms to modify first')
1140        self.AtomEdit.Append(id=wxID_ATOMSTRANSFORM, kind=wx.ITEM_NORMAL,text='Transform atoms',
1141            help='Select atoms to transform first')
1142        self.AtomEdit.Append(id=wxID_RELOADDRAWATOMS, kind=wx.ITEM_NORMAL,text='Reload draw atoms',
1143            help='Reload atom drawing list')
1144        self.AtomEdit.Append(id=wxID_ATOMSREIMPORT, kind=wx.ITEM_NORMAL,text='Reimport atoms',
1145            help='Reimport atoms from file; sequence must match')
1146        self.AtomCompute.Append(id=wxID_ATOMSDISAGL, kind=wx.ITEM_NORMAL,text='Distances && Angles',
1147            help='Compute distances & angles for selected atoms')
1148        self.PostfillDataMenu()
1149                 
1150# Phase / Draw Options tab
1151        self.DataDrawOptions = wx.MenuBar()
1152        self.PrefillDataMenu(self.DataDrawOptions,helpType='Draw Options', helpLbl='Phase/Draw Options',empty=True)
1153        self.PostfillDataMenu(empty=True)
1154       
1155# Phase / Draw Atoms tab
1156        self.DrawAtomsMenu = wx.MenuBar()
1157        self.PrefillDataMenu(self.DrawAtomsMenu,helpType='Draw Atoms')
1158        self.DrawAtomEdit = wx.Menu(title='')
1159        self.DrawAtomCompute = wx.Menu(title='')
1160        self.DrawAtomRestraint = wx.Menu(title='')
1161        self.DrawAtomRigidBody = wx.Menu(title='')
1162        self.DrawAtomsMenu.Append(menu=self.DrawAtomEdit, title='Edit')
1163        self.DrawAtomsMenu.Append(menu=self.DrawAtomCompute,title='Compute')
1164        self.DrawAtomsMenu.Append(menu=self.DrawAtomRestraint, title='Restraints')
1165        self.DrawAtomsMenu.Append(menu=self.DrawAtomRigidBody, title='Rigid body')
1166        self.DrawAtomEdit.Append(id=wxID_DRAWATOMSTYLE, kind=wx.ITEM_NORMAL,text='Atom style',
1167            help='Select atoms first')
1168        self.DrawAtomEdit.Append(id=wxID_DRAWATOMLABEL, kind=wx.ITEM_NORMAL,text='Atom label',
1169            help='Select atoms first')
1170        self.DrawAtomEdit.Append(id=wxID_DRAWATOMCOLOR, kind=wx.ITEM_NORMAL,text='Atom color',
1171            help='Select atoms first')
1172        self.DrawAtomEdit.Append(id=wxID_DRAWATOMRESETCOLOR, kind=wx.ITEM_NORMAL,text='Reset atom colors',
1173            help='Resets all atom colors to defaults')
1174        self.DrawAtomEdit.Append(id=wxID_DRAWVIEWPOINT, kind=wx.ITEM_NORMAL,text='View point',
1175            help='View point is 1st atom selected')
1176        self.DrawAtomEdit.Append(id=wxID_DRAWADDEQUIV, kind=wx.ITEM_NORMAL,text='Add atoms',
1177            help='Add symmetry & cell equivalents to drawing set from selected atoms')
1178        self.DrawAtomEdit.Append(id=wxID_DRAWTRANSFORM, kind=wx.ITEM_NORMAL,text='Transform atoms',
1179            help='Transform selected atoms by symmetry & cell translations')
1180        self.DrawAtomEdit.Append(id=wxID_DRAWFILLCOORD, kind=wx.ITEM_NORMAL,text='Fill CN-sphere',
1181            help='Fill coordination sphere for selected atoms')           
1182        self.DrawAtomEdit.Append(id=wxID_DRAWFILLCELL, kind=wx.ITEM_NORMAL,text='Fill unit cell',
1183            help='Fill unit cell with selected atoms')
1184        self.DrawAtomEdit.Append(id=wxID_DRAWDELETE, kind=wx.ITEM_NORMAL,text='Delete atoms',
1185            help='Delete atoms from drawing set')
1186        self.DrawAtomCompute.Append(id=wxID_DRAWDISTVP, kind=wx.ITEM_NORMAL,text='View pt. dist.',
1187            help='Compute distance of selected atoms from view point')   
1188        self.DrawAtomCompute.Append(id=wxID_DRAWDISAGLTOR, kind=wx.ITEM_NORMAL,text='Dist. Ang. Tors.',
1189            help='Compute distance, angle or torsion for 2-4 selected atoms')   
1190        self.DrawAtomCompute.Append(id=wxID_DRAWPLANE, kind=wx.ITEM_NORMAL,text='Best plane',
1191            help='Compute best plane for 4+ selected atoms')   
1192        self.DrawAtomRestraint.Append(id=wxID_DRAWRESTRBOND, kind=wx.ITEM_NORMAL,text='Add bond restraint',
1193            help='Add bond restraint for selected atoms (2)')
1194        self.DrawAtomRestraint.Append(id=wxID_DRAWRESTRANGLE, kind=wx.ITEM_NORMAL,text='Add angle restraint',
1195            help='Add angle restraint for selected atoms (3: one end 1st)')
1196        self.DrawAtomRestraint.Append(id=wxID_DRAWRESTRPLANE, kind=wx.ITEM_NORMAL,text='Add plane restraint',
1197            help='Add plane restraint for selected atoms (4+)')
1198        self.DrawAtomRestraint.Append(id=wxID_DRAWRESTRCHIRAL, kind=wx.ITEM_NORMAL,text='Add chiral restraint',
1199            help='Add chiral restraint for selected atoms (4: center atom 1st)')
1200        self.DrawAtomRigidBody.Append(id=wxID_DRAWDEFINERB, kind=wx.ITEM_NORMAL,text='Define rigid body',
1201            help='Define rigid body with selected atoms')
1202        self.PostfillDataMenu()
1203           
1204# Phase / Texture tab
1205        self.TextureMenu = wx.MenuBar()
1206        self.PrefillDataMenu(self.TextureMenu,helpType='Texture')
1207        self.TextureEdit = wx.Menu(title='')
1208        self.TextureMenu.Append(menu=self.TextureEdit, title='Texture')
1209        self.TextureEdit.Append(id=wxID_REFINETEXTURE, kind=wx.ITEM_NORMAL,text='Refine texture', 
1210            help='Refine the texture coefficients from sequential Pawley results')
1211        self.TextureEdit.Append(id=wxID_CLEARTEXTURE, kind=wx.ITEM_NORMAL,text='Clear texture', 
1212            help='Clear the texture coefficients' )
1213        self.PostfillDataMenu()
1214           
1215# Phase / Pawley tab
1216        self.PawleyMenu = wx.MenuBar()
1217        self.PrefillDataMenu(self.PawleyMenu,helpType='Pawley')
1218        self.PawleyEdit = wx.Menu(title='')
1219        self.PawleyMenu.Append(menu=self.PawleyEdit,title='Operations')
1220        self.PawleyEdit.Append(id=wxID_PAWLEYLOAD, kind=wx.ITEM_NORMAL,text='Pawley create',
1221            help='Initialize Pawley reflection list')
1222        self.PawleyEdit.Append(id=wxID_PAWLEYESTIMATE, kind=wx.ITEM_NORMAL,text='Pawley estimate',
1223            help='Estimate initial Pawley intensities')
1224        self.PawleyEdit.Append(id=wxID_PAWLEYUPDATE, kind=wx.ITEM_NORMAL,text='Pawley update',
1225            help='Update Pawley intensities with abs(Fobs) from reflection list')
1226#        self.PawleyEdit.Append(id=wxID_PAWLEYDELETE, kind=wx.ITEM_NORMAL,text='Pawley delete',
1227#            help='Delete selected Pawley reflection')
1228        self.PostfillDataMenu()
1229           
1230# Phase / Map peaks tab
1231        self.MapPeaksMenu = wx.MenuBar()
1232        self.PrefillDataMenu(self.MapPeaksMenu,helpType='Map peaks')
1233        self.MapPeaksEdit = wx.Menu(title='')
1234        self.MapPeaksMenu.Append(menu=self.MapPeaksEdit, title='Map peaks')
1235        self.MapPeaksEdit.Append(id=wxID_PEAKSMOVE, kind=wx.ITEM_NORMAL,text='Move peaks', 
1236            help='Move selected peaks to atom list')
1237        self.MapPeaksEdit.Append(id=wxID_PEAKSVIEWPT, kind=wx.ITEM_NORMAL,text='View point',
1238            help='View point is 1st peak selected')
1239        self.MapPeaksEdit.Append(id=wxID_PEAKSDISTVP, kind=wx.ITEM_NORMAL,text='View pt. dist.',
1240            help='Compute distance of selected peaks from view point')   
1241        self.MapPeaksEdit.Append(id=wxID_SHOWBONDS, kind=wx.ITEM_NORMAL,text='Hide bonds',
1242            help='Hide or show bonds between peak positions')   
1243        self.MapPeaksEdit.Append(id=wxID_PEAKSDA, kind=wx.ITEM_NORMAL,text='Calc dist/ang', 
1244            help='Calculate distance or angle for selection')
1245        self.MapPeaksEdit.Append(id=wxID_FINDEQVPEAKS, kind=wx.ITEM_NORMAL,text='Equivalent peaks', 
1246            help='Find equivalent peaks')
1247        self.MapPeaksEdit.Append(id=wxID_PEAKSUNIQUE, kind=wx.ITEM_NORMAL,text='Unique peaks', 
1248            help='Select unique set')
1249        self.MapPeaksEdit.Append(id=wxID_PEAKSDELETE, kind=wx.ITEM_NORMAL,text='Delete peaks', 
1250            help='Delete selected peaks')
1251        self.MapPeaksEdit.Append(id=wxID_PEAKSCLEAR, kind=wx.ITEM_NORMAL,text='Clear peaks', 
1252            help='Clear the map peak list')
1253        self.PostfillDataMenu()
1254
1255# Phase / Rigid bodies tab
1256        self.RigidBodiesMenu = wx.MenuBar()
1257        self.PrefillDataMenu(self.MapPeaksMenu,helpType='Rigid bodies')
1258        self.RigidBodiesEdit = wx.Menu(title='')
1259        self.RigidBodiesMenu.Append(menu=self.RigidBodiesEdit, title='Edit')
1260        self.RigidBodiesEdit.Append(id=wxID_ASSIGNATMS2RB, kind=wx.ITEM_NORMAL,text='Assign atoms to rigid body',
1261            help='Select & position rigid body in structure of existing atoms')
1262        self.RigidBodiesEdit.Append(id=wxID_AUTOFINDRESRB, kind=wx.ITEM_NORMAL,text='Auto find residues',
1263            help='Auto find of residue RBs in macromolecule')
1264        self.RigidBodiesEdit.Append(id=wxID_COPYRBPARMS, kind=wx.ITEM_NORMAL,text='Copy rigid body parms',
1265            help='Copy rigid body location & TLS parameters')
1266        self.RigidBodiesEdit.Append(id=wxID_GLOBALRESREFINE, kind=wx.ITEM_NORMAL,text='Global residue refine',
1267            help='Global setting of residue RB refinement flags')
1268        self.RigidBodiesEdit.Append(id=wxID_RBREMOVEALL, kind=wx.ITEM_NORMAL,text='Remove all rigid bodies',
1269            help='Remove all rigid body assignment for atoms')
1270        self.PostfillDataMenu()
1271           
1272# end of GSAS-II menu definitions
1273       
1274    def _init_ctrls(self, parent,name=None,size=None,pos=None):
1275        wx.Frame.__init__(self,parent=parent,
1276            style=wx.DEFAULT_FRAME_STYLE ^ wx.CLOSE_BOX | wx.FRAME_FLOAT_ON_PARENT ,
1277            size=size,pos=pos,title='GSAS-II data display')
1278        self._init_menus()
1279        if name:
1280            self.SetLabel(name)
1281        self.Show()
1282       
1283    def __init__(self,parent,frame,data=None,name=None, size=None,pos=None):
1284        self.G2frame = frame
1285        self._init_ctrls(parent,name,size,pos)
1286        self.data = data
1287        clientSize = wx.ClientDisplayRect()
1288        Size = self.GetSize()
1289        xPos = clientSize[2]-Size[0]
1290        self.SetPosition(wx.Point(xPos,clientSize[1]+250))
1291        self.AtomGrid = []
1292        self.selectedRow = 0
1293       
1294    def setSizePosLeft(self,Width):
1295        clientSize = wx.ClientDisplayRect()
1296        Width[1] = min(Width[1],clientSize[2]-300)
1297        Width[0] = max(Width[0],300)
1298        self.SetSize(Width)
1299#        self.SetPosition(wx.Point(clientSize[2]-Width[0],clientSize[1]+250))
1300       
1301    def Clear(self):
1302        self.ClearBackground()
1303        self.DestroyChildren()
1304                   
1305################################################################################
1306#####  GSNotebook
1307################################################################################           
1308       
1309class GSNoteBook(wx.Notebook):
1310    def __init__(self, parent, name='',size = None):
1311        wx.Notebook.__init__(self, parent, -1, name=name, style= wx.BK_TOP)
1312        if size: self.SetSize(size)
1313                                                     
1314    def Clear(self):       
1315        GSNoteBook.DeleteAllPages(self)
1316       
1317    def FindPage(self,name):
1318        numPage = self.GetPageCount()
1319        for page in range(numPage):
1320            if self.GetPageText(page) == name:
1321                return page
1322       
1323################################################################################
1324#####  GSGrid
1325################################################################################           
1326       
1327class GSGrid(wg.Grid):
1328    def __init__(self, parent, name=''):
1329        wg.Grid.__init__(self,parent,-1,name=name)                   
1330        self.SetSize(parent.GetClientSize())
1331           
1332    def Clear(self):
1333        wg.Grid.ClearGrid(self)
1334       
1335    def SetCellStyle(self,r,c,color="white",readonly=True):
1336        self.SetCellBackgroundColour(r,c,color)
1337        self.SetReadOnly(r,c,isReadOnly=readonly)
1338       
1339    def GetSelection(self):
1340        #this is to satisfy structure drawing stuff in G2plt when focus changes
1341        return None
1342                                               
1343################################################################################
1344#####  Table
1345################################################################################           
1346       
1347class Table(wg.PyGridTableBase):
1348    def __init__(self, data=[], rowLabels=None, colLabels=None, types = None):
1349        wg.PyGridTableBase.__init__(self)
1350        self.colLabels = colLabels
1351        self.rowLabels = rowLabels
1352        self.dataTypes = types
1353        self.data = data
1354       
1355    def AppendRows(self, numRows=1):
1356        self.data.append([])
1357        return True
1358       
1359    def CanGetValueAs(self, row, col, typeName):
1360        if self.dataTypes:
1361            colType = self.dataTypes[col].split(':')[0]
1362            if typeName == colType:
1363                return True
1364            else:
1365                return False
1366        else:
1367            return False
1368
1369    def CanSetValueAs(self, row, col, typeName):
1370        return self.CanGetValueAs(row, col, typeName)
1371
1372    def DeleteRow(self,pos):
1373        data = self.GetData()
1374        self.SetData([])
1375        new = []
1376        for irow,row in enumerate(data):
1377            if irow <> pos:
1378                new.append(row)
1379        self.SetData(new)
1380       
1381    def GetColLabelValue(self, col):
1382        if self.colLabels:
1383            return self.colLabels[col]
1384           
1385    def GetData(self):
1386        data = []
1387        for row in range(self.GetNumberRows()):
1388            data.append(self.GetRowValues(row))
1389        return data
1390       
1391    def GetNumberCols(self):
1392        try:
1393            return len(self.colLabels)
1394        except TypeError:
1395            return None
1396       
1397    def GetNumberRows(self):
1398        return len(self.data)
1399       
1400    def GetRowLabelValue(self, row):
1401        if self.rowLabels:
1402            return self.rowLabels[row]
1403       
1404    def GetColValues(self, col):
1405        data = []
1406        for row in range(self.GetNumberRows()):
1407            data.append(self.GetValue(row, col))
1408        return data
1409       
1410    def GetRowValues(self, row):
1411        data = []
1412        for col in range(self.GetNumberCols()):
1413            data.append(self.GetValue(row, col))
1414        return data
1415       
1416    def GetTypeName(self, row, col):
1417        try:
1418            return self.dataTypes[col]
1419        except TypeError:
1420            return None
1421
1422    def GetValue(self, row, col):
1423        try:
1424            return self.data[row][col]
1425        except IndexError:
1426            return None
1427           
1428    def InsertRows(self, pos, rows):
1429        for row in range(rows):
1430            self.data.insert(pos,[])
1431            pos += 1
1432       
1433    def IsEmptyCell(self,row,col):
1434        try:
1435            return not self.data[row][col]
1436        except IndexError:
1437            return True
1438       
1439    def OnKeyPress(self, event):
1440        dellist = self.GetSelectedRows()
1441        if event.GetKeyCode() == wx.WXK_DELETE and dellist:
1442            grid = self.GetView()
1443            for i in dellist: grid.DeleteRow(i)
1444               
1445    def SetColLabelValue(self, col, label):
1446        numcols = self.GetNumberCols()
1447        if col > numcols-1:
1448            self.colLabels.append(label)
1449        else:
1450            self.colLabels[col]=label
1451       
1452    def SetData(self,data):
1453        for row in range(len(data)):
1454            self.SetRowValues(row,data[row])
1455               
1456    def SetRowLabelValue(self, row, label):
1457        self.rowLabels[row]=label
1458           
1459    def SetRowValues(self,row,data):
1460        self.data[row] = data
1461           
1462    def SetValue(self, row, col, value):
1463        def innerSetValue(row, col, value):
1464            try:
1465                self.data[row][col] = value
1466            except TypeError:
1467                return
1468            except IndexError:
1469                print row,col,value
1470                # add a new row
1471                if row > self.GetNumberRows():
1472                    self.data.append([''] * self.GetNumberCols())
1473                elif col > self.GetNumberCols():
1474                    for row in range(self.GetNumberRows):
1475                        self.data[row].append('')
1476                print self.data
1477                self.data[row][col] = value
1478        innerSetValue(row, col, value)
1479       
1480################################################################################
1481#### Help
1482################################################################################
1483
1484def ShowHelp(helpType,frame):
1485    '''Called to bring up a web page for documentation.'''
1486    global htmlFirstUse
1487    # look up a definition for help info from dict
1488    helplink = helpLocDict.get(helpType)
1489    if helplink is None:
1490        # no defined link to use, create a default based on key
1491        helplink = 'gsasII.html#'+helpType.replace(' ','_')
1492    helplink = os.path.join(path2GSAS2,'help',helplink)
1493    if helpMode == 'internal':
1494        try:
1495            htmlPanel.LoadFile(helplink)
1496            htmlFrame.Raise()
1497        except:
1498            htmlFrame = wx.Frame(frame, -1, size=(610, 510))
1499            htmlFrame.Show(True)
1500            htmlFrame.SetTitle("HTML Window") # N.B. reset later in LoadFile
1501            htmlPanel = MyHtmlPanel(htmlFrame,-1)
1502            htmlPanel.LoadFile(helplink)
1503    else:
1504        pfx = "file://"
1505        if sys.platform.lower().startswith('win'):
1506            pfx = ''
1507        if htmlFirstUse:
1508            webbrowser.open_new(pfx+helplink)
1509            htmlFirstUse = False
1510        else:
1511            webbrowser.open(pfx+helplink, new=0, autoraise=True)
1512
1513################################################################################
1514#####  Notebook
1515################################################################################           
1516       
1517def UpdateNotebook(G2frame,data):
1518   
1519    def OnNoteBook(event):
1520        data = G2frame.dataDisplay.GetValue()
1521        G2frame.PatternTree.SetItemPyData(GetPatternTreeItemId(G2frame,G2frame.root,'Notebook'),data)
1522                   
1523    if G2frame.dataDisplay:
1524        G2frame.dataDisplay.Destroy()
1525    G2frame.dataFrame.SetLabel('Notebook')
1526    G2frame.dataDisplay = wx.TextCtrl(parent=G2frame.dataFrame,size=G2frame.dataFrame.GetClientSize(),
1527        style=wx.TE_MULTILINE|wx.TE_PROCESS_ENTER | wx.TE_DONTWRAP)
1528    G2frame.dataDisplay.Bind(wx.EVT_TEXT_ENTER,OnNoteBook)
1529    G2frame.dataDisplay.Bind(wx.EVT_KILL_FOCUS,OnNoteBook)
1530    for line in data:
1531        G2frame.dataDisplay.AppendText(line+"\n")
1532    G2frame.dataDisplay.AppendText('Notebook entry @ '+time.ctime()+"\n")
1533    G2frame.dataFrame.setSizePosLeft([400,250])
1534           
1535################################################################################
1536#####  Controls
1537################################################################################           
1538       
1539def UpdateControls(G2frame,data):
1540    #patch
1541    if 'deriv type' not in data:
1542        data = {}
1543        data['deriv type'] = 'analytic Hessian'
1544        data['min dM/M'] = 0.0001
1545        data['shift factor'] = 1.
1546        data['max cyc'] = 3       
1547        data['F**2'] = True
1548        data['minF/sig'] = 0
1549    if 'shift factor' not in data:
1550        data['shift factor'] = 1.
1551    if 'max cyc' not in data:
1552        data['max cyc'] = 3
1553    if 'F**2' not in data:
1554        data['F**2'] = True
1555        data['minF/sig'] = 0
1556    #end patch
1557
1558    def SeqSizer():
1559       
1560        def OnSelectData(event):
1561            choices = ['All',]+GetPatternTreeDataNames(G2frame,['PWDR',])
1562            sel = []
1563            if 'Seq Data' in data:
1564                for item in data['Seq Data']:
1565                    sel.append(choices.index(item))
1566            names = []
1567            dlg = wx.MultiChoiceDialog(G2frame,'Select data:','Sequential refinement',choices)
1568            dlg.SetSelections(sel)
1569            if dlg.ShowModal() == wx.ID_OK:
1570                sel = dlg.GetSelections()
1571                for i in sel: names.append(choices[i])
1572                if 'All' in names:
1573                    names = choices[1:]
1574                data['Seq Data'] = names               
1575            dlg.Destroy()
1576            reverseSel.Enable(True)
1577           
1578        def OnReverse(event):
1579            data['Reverse Seq'] = reverseSel.GetValue()
1580                   
1581        seqSizer = wx.BoxSizer(wx.HORIZONTAL)
1582        seqSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Sequential Refinement Powder Data: '),0,wx.ALIGN_CENTER_VERTICAL)
1583        selSeqData = wx.Button(G2frame.dataDisplay,-1,label=' Select data')
1584        selSeqData.Bind(wx.EVT_BUTTON,OnSelectData)
1585        seqSizer.Add(selSeqData,0,wx.ALIGN_CENTER_VERTICAL)
1586        seqSizer.Add((5,0),0)
1587        reverseSel = wx.CheckBox(G2frame.dataDisplay,-1,label=' Reverse order?')
1588        reverseSel.Bind(wx.EVT_CHECKBOX,OnReverse)
1589        if 'Seq Data' not in data:
1590            reverseSel.Enable(False)
1591        if 'Reverse Seq' in data:
1592            reverseSel.SetValue(data['Reverse Seq'])
1593        seqSizer.Add(reverseSel,0,wx.ALIGN_CENTER_VERTICAL)
1594        return seqSizer
1595       
1596    def LSSizer():       
1597       
1598        def OnDerivType(event):
1599            data['deriv type'] = derivSel.GetValue()
1600            derivSel.SetValue(data['deriv type'])
1601            wx.CallAfter(UpdateControls,G2frame,data)
1602           
1603        def OnConvergence(event):
1604            try:
1605                value = max(1.e-9,min(1.0,float(Cnvrg.GetValue())))
1606            except ValueError:
1607                value = 0.0001
1608            data['min dM/M'] = value
1609            Cnvrg.SetValue('%.2g'%(value))
1610           
1611        def OnMaxCycles(event):
1612            data['max cyc'] = int(maxCyc.GetValue())
1613            maxCyc.SetValue(str(data['max cyc']))
1614                       
1615        def OnFactor(event):
1616            try:
1617                value = min(max(float(Factr.GetValue()),0.00001),100.)
1618            except ValueError:
1619                value = 1.0
1620            data['shift factor'] = value
1621            Factr.SetValue('%.5f'%(value))
1622           
1623        def OnFsqRef(event):
1624            data['F**2'] = fsqRef.GetValue()
1625       
1626        def OnMinSig(event):
1627            try:
1628                value = min(max(float(minSig.GetValue()),0.),5.)
1629            except ValueError:
1630                value = 1.0
1631            data['minF/sig'] = value
1632            minSig.SetValue('%.2f'%(value))
1633
1634        LSSizer = wx.FlexGridSizer(cols=4,vgap=5,hgap=5)
1635        LSSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Refinement derivatives: '),0,wx.ALIGN_CENTER_VERTICAL)
1636        Choice=['analytic Jacobian','numeric','analytic Hessian']
1637        derivSel = wx.ComboBox(parent=G2frame.dataDisplay,value=data['deriv type'],choices=Choice,
1638            style=wx.CB_READONLY|wx.CB_DROPDOWN)
1639        derivSel.SetValue(data['deriv type'])
1640        derivSel.Bind(wx.EVT_COMBOBOX, OnDerivType)
1641           
1642        LSSizer.Add(derivSel,0,wx.ALIGN_CENTER_VERTICAL)
1643        LSSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Min delta-M/M: '),0,wx.ALIGN_CENTER_VERTICAL)
1644        Cnvrg = wx.TextCtrl(G2frame.dataDisplay,-1,value='%.2g'%(data['min dM/M']),style=wx.TE_PROCESS_ENTER)
1645        Cnvrg.Bind(wx.EVT_TEXT_ENTER,OnConvergence)
1646        Cnvrg.Bind(wx.EVT_KILL_FOCUS,OnConvergence)
1647        LSSizer.Add(Cnvrg,0,wx.ALIGN_CENTER_VERTICAL)
1648        if 'Hessian' in data['deriv type']:
1649            LSSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Max cycles: '),0,wx.ALIGN_CENTER_VERTICAL)
1650            Choice = ['0','1','2','3','5','10','15','20']
1651            maxCyc = wx.ComboBox(parent=G2frame.dataDisplay,value=str(data['max cyc']),choices=Choice,
1652                style=wx.CB_READONLY|wx.CB_DROPDOWN)
1653            maxCyc.SetValue(str(data['max cyc']))
1654            maxCyc.Bind(wx.EVT_COMBOBOX, OnMaxCycles)
1655            LSSizer.Add(maxCyc,0,wx.ALIGN_CENTER_VERTICAL)
1656        else:
1657            LSSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Initial shift factor: '),0,wx.ALIGN_CENTER_VERTICAL)
1658            Factr = wx.TextCtrl(G2frame.dataDisplay,-1,value='%.5f'%(data['shift factor']),style=wx.TE_PROCESS_ENTER)
1659            Factr.Bind(wx.EVT_TEXT_ENTER,OnFactor)
1660            Factr.Bind(wx.EVT_KILL_FOCUS,OnFactor)
1661            LSSizer.Add(Factr,0,wx.ALIGN_CENTER_VERTICAL)
1662        if G2frame.Sngl:
1663            LSSizer.Add((1,0),)
1664            LSSizer.Add((1,0),)
1665            fsqRef = wx.CheckBox(G2frame.dataDisplay,-1,label='Refine HKLF as F^2? ')
1666            fsqRef.SetValue(data['F**2'])
1667            fsqRef.Bind(wx.EVT_CHECKBOX,OnFsqRef)
1668            LSSizer.Add(fsqRef,0,wx.ALIGN_CENTER_VERTICAL)
1669            LSSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,label='Min obs/sig (0-5): '),0,wx.ALIGN_CENTER_VERTICAL)
1670            minSig = wx.TextCtrl(G2frame.dataDisplay,-1,value='%.2f'%(data['minF/sig']),style=wx.TE_PROCESS_ENTER)
1671            minSig.Bind(wx.EVT_TEXT_ENTER,OnMinSig)
1672            minSig.Bind(wx.EVT_KILL_FOCUS,OnMinSig)
1673            LSSizer.Add(minSig,0,wx.ALIGN_CENTER_VERTICAL)
1674        return LSSizer
1675       
1676    if G2frame.dataDisplay:
1677        G2frame.dataDisplay.Destroy()
1678    if not G2frame.dataFrame.GetStatusBar():
1679        Status = G2frame.dataFrame.CreateStatusBar()
1680        Status.SetStatusText('')
1681    G2frame.dataFrame.SetLabel('Controls')
1682    G2frame.dataDisplay = wx.Panel(G2frame.dataFrame)
1683    SetDataMenuBar(G2frame,G2frame.dataFrame.ControlsMenu)
1684    mainSizer = wx.BoxSizer(wx.VERTICAL)
1685    mainSizer.Add((5,5),0)
1686    mainSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Refinement Controls:'),0,wx.ALIGN_CENTER_VERTICAL)   
1687    mainSizer.Add(LSSizer())
1688    mainSizer.Add((5,5),0)
1689    mainSizer.Add(SeqSizer())
1690    mainSizer.Add((5,5),0)
1691       
1692    mainSizer.Layout()   
1693    G2frame.dataDisplay.SetSizer(mainSizer)
1694    G2frame.dataDisplay.SetSize(mainSizer.Fit(G2frame.dataFrame))
1695    G2frame.dataFrame.setSizePosLeft(mainSizer.Fit(G2frame.dataFrame))
1696     
1697################################################################################
1698#####  Comments
1699################################################################################           
1700       
1701def UpdateComments(G2frame,data):                   
1702
1703    if G2frame.dataDisplay:
1704        G2frame.dataDisplay.Destroy()
1705    G2frame.dataFrame.SetLabel('Comments')
1706    G2frame.dataDisplay = wx.TextCtrl(parent=G2frame.dataFrame,size=G2frame.dataFrame.GetClientSize(),
1707        style=wx.TE_MULTILINE|wx.TE_READONLY|wx.TE_DONTWRAP)
1708    for line in data:
1709        G2frame.dataDisplay.AppendText(line+'\n')
1710    G2frame.dataFrame.setSizePosLeft([400,250])
1711           
1712################################################################################
1713#####  Sequential Results
1714################################################################################           
1715       
1716def UpdateSeqResults(G2frame,data):
1717    """
1718    input:
1719        data - dictionary
1720            'histNames' - list of histogram names in order as processed by Sequential Refinement
1721            'varyList' - list of variables - identical over all refinements in sequence
1722            'histName' - dictionaries for all data sets processed:
1723                'variables'- result[0] from leastsq call
1724                'varyList' - list of variables; same as above
1725                'sig' - esds for variables
1726                'covMatrix' - covariance matrix from individual refinement
1727                'title' - histogram name; same as dict item name
1728                'newAtomDict' - new atom parameters after shifts applied
1729                'newCellDict' - new cell parameters after shifts to A0-A5 applied'
1730    """
1731    if not data:
1732        print 'No sequential refinement results'
1733        return
1734    histNames = data['histNames']
1735       
1736    def GetSampleParms():
1737        sampleParmDict = {'Temperature':[],'Pressure':[],'Humidity':[],'Voltage':[],'Force':[],}
1738        sampleParm = {}
1739        for name in histNames:
1740            Id = GetPatternTreeItemId(G2frame,G2frame.root,name)
1741            sampleData = G2frame.PatternTree.GetItemPyData(GetPatternTreeItemId(G2frame,Id,'Sample Parameters'))
1742            for item in sampleParmDict:
1743                sampleParmDict[item].append(sampleData[item])
1744        for item in sampleParmDict:
1745            frstValue = sampleParmDict[item][0]
1746            if np.any(np.array(sampleParmDict[item])-frstValue):
1747                sampleParm[item] = sampleParmDict[item]           
1748        return sampleParm
1749           
1750    def GetRwps():
1751        Rwps = []
1752        for name in histNames:
1753            Rwps.append(data[name]['Rvals']['Rwp'])
1754        return Rwps
1755           
1756    def GetSigData(parm):
1757        sigData = []
1758        for name in histNames:
1759            sigList = data[name]['sig']
1760            if colLabels[parm] in atomList:
1761                sigData.append(sigList[colLabels.index(atomList[colLabels[parm]])-1])
1762            elif colLabels[parm] in cellList:
1763                sigData.append(sigList[colLabels.index(cellList[colLabels[parm]])-1])
1764            else:
1765                sigData.append(sigList[parm-1])
1766        return sigData
1767   
1768    def Select(event):
1769        cols = G2frame.dataDisplay.GetSelectedCols()
1770        rows = G2frame.dataDisplay.GetSelectedRows()
1771        if cols:
1772            plotData = []
1773            plotSig = []
1774            plotNames = []
1775            for col in cols:
1776                plotData.append(G2frame.SeqTable.GetColValues(col))
1777                if col:     #not Rwp
1778                    plotSig.append(GetSigData(col))
1779                else:
1780                    plotSig.append(0.0)
1781                plotNames.append(G2frame.SeqTable.GetColLabelValue(col))
1782            plotData = np.array(plotData)
1783            G2plt.PlotSeq(G2frame,plotData,plotSig,plotNames,sampleParms)
1784        elif rows:
1785            name = histNames[rows[0]]       #only does 1st one selected
1786            G2plt.PlotCovariance(G2frame,data[name])
1787           
1788    def OnSaveSelSeq(event):       
1789        cols = G2frame.dataDisplay.GetSelectedCols()
1790        if cols:
1791            numRows = G2frame.SeqTable.GetNumberRows()
1792            dataNames = []
1793            saveNames = [G2frame.SeqTable.GetRowLabelValue(r) for r in range(numRows)]
1794            saveData = []
1795            for col in cols:
1796                dataNames.append(G2frame.SeqTable.GetColLabelValue(col))
1797                if col:     #not Rwp
1798                    saveData.append(zip(G2frame.SeqTable.GetColValues(col),GetSigData(col)))
1799                else:
1800                    saveData.append(zip(G2frame.SeqTable.GetColValues(col),0.0))
1801            lenName = len(saveNames[0])
1802            saveData = np.swapaxes(np.array(saveData),0,1)
1803            dlg = wx.FileDialog(G2frame, 'Choose text output file for your selection', '.', '', 
1804                'Text output file (*.txt)|*.txt',wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT|wx.CHANGE_DIR)
1805            try:
1806                if dlg.ShowModal() == wx.ID_OK:
1807                    SeqTextFile = dlg.GetPath()
1808                    SeqTextFile = G2IO.FileDlgFixExt(dlg,SeqTextFile)
1809                    SeqFile = open(SeqTextFile,'w')
1810                    line = %s  '%('name'.center(lenName))
1811                    for item in dataNames:
1812                        line += ' %12s %12s '%(item.center(12),'esd'.center(12))
1813                    line += '\n'
1814                    SeqFile.write(line)
1815                    for i,item in enumerate(saveData):
1816                        line = " '%s' "%(saveNames[i])
1817                        for val,esd in item:
1818                            line += ' %12.6f %12.6f '%(val,esd)
1819                        line += '\n'
1820                        SeqFile.write(line)
1821                    SeqFile.close()
1822            finally:
1823                dlg.Destroy()
1824           
1825               
1826    if G2frame.dataDisplay:
1827        G2frame.dataDisplay.Destroy()
1828    atomList = {}
1829    newAtomDict = data[histNames[0]]['newAtomDict']
1830    for item in newAtomDict:
1831        if item in data['varyList']:
1832            atomList[newAtomDict[item][0]] = item
1833    cellList = {}
1834    newCellDict = data[histNames[0]]['newCellDict']
1835    for item in newCellDict:
1836        if item in data['varyList']:
1837            cellList[newCellDict[item][0]] = item
1838    sampleParms = GetSampleParms()
1839    Rwps = GetRwps()
1840    SetDataMenuBar(G2frame,G2frame.dataFrame.SequentialMenu)
1841    G2frame.dataFrame.SetLabel('Sequental refinement results')
1842    G2frame.dataFrame.CreateStatusBar()
1843    G2frame.dataFrame.Bind(wx.EVT_MENU, OnSaveSelSeq, id=wxID_SAVESEQSEL)
1844    colLabels = ['Rwp',]+data['varyList']+atomList.keys()+cellList.keys()
1845    Types = (len(data['varyList']+atomList.keys()+cellList.keys())+1)*[wg.GRID_VALUE_FLOAT,]
1846    seqList = [[Rwps[i],]+list(data[name]['variables']) for i,name in enumerate(histNames)]
1847    for i,item in enumerate(seqList):
1848        newAtomDict = data[histNames[i]]['newAtomDict']
1849        newCellDict = data[histNames[i]]['newCellDict']
1850        item += [newAtomDict[atomList[parm]][1] for parm in atomList.keys()]
1851        item += [newCellDict[cellList[parm]][1] for parm in cellList.keys()]
1852    G2frame.SeqTable = Table(seqList,colLabels=colLabels,rowLabels=histNames,types=Types)
1853    G2frame.dataDisplay = GSGrid(parent=G2frame.dataFrame)
1854    G2frame.dataDisplay.SetTable(G2frame.SeqTable, True)
1855    G2frame.dataDisplay.EnableEditing(False)
1856    G2frame.dataDisplay.Bind(wg.EVT_GRID_LABEL_LEFT_DCLICK, Select)
1857    G2frame.dataDisplay.SetRowLabelSize(8*len(histNames[0]))       #pretty arbitrary 8
1858    G2frame.dataDisplay.SetMargins(0,0)
1859    G2frame.dataDisplay.AutoSizeColumns(True)
1860    G2frame.dataFrame.setSizePosLeft([700,350])
1861       
1862################################################################################
1863#####  Main PWDR panel
1864################################################################################           
1865       
1866def UpdatePWHKPlot(G2frame,kind,item):
1867
1868    def OnErrorAnalysis(event):
1869        G2plt.PlotDeltSig(G2frame,kind)
1870       
1871    def OnWtFactor(event):
1872        try:
1873            val = float(wtval.GetValue())
1874        except ValueError:
1875            val = data[0]['wtFactor']
1876        data[0]['wtFactor'] = val
1877        wtval.SetValue('%.3f'%(val))
1878           
1879    data = G2frame.PatternTree.GetItemPyData(item)
1880    if 'wtFactor' not in data[0]:
1881        data[0] = {'wtFactor':1.0}
1882    if G2frame.dataDisplay:
1883        G2frame.dataDisplay.Destroy()
1884    SetDataMenuBar(G2frame,G2frame.dataFrame.ErrorMenu)
1885    G2frame.dataFrame.Bind(wx.EVT_MENU,OnErrorAnalysis, id=wxID_PWDANALYSIS)
1886    G2frame.dataDisplay = wx.Panel(G2frame.dataFrame)
1887   
1888    mainSizer = wx.BoxSizer(wx.VERTICAL)
1889    mainSizer.Add((5,5),)
1890    wtSizer = wx.BoxSizer(wx.HORIZONTAL)
1891    wtSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' Weight factor: '),0,wx.ALIGN_CENTER_VERTICAL)
1892    wtval = wx.TextCtrl(G2frame.dataDisplay,-1,'%.3f'%(data[0]['wtFactor']),style=wx.TE_PROCESS_ENTER)
1893    wtval.Bind(wx.EVT_TEXT_ENTER,OnWtFactor)
1894    wtval.Bind(wx.EVT_KILL_FOCUS,OnWtFactor)
1895    wtSizer.Add(wtval,0,wx.ALIGN_CENTER_VERTICAL)
1896    mainSizer.Add(wtSizer)
1897    mainSizer.Layout()   
1898    G2frame.dataDisplay.SetSizer(mainSizer)
1899    G2frame.dataFrame.setSizePosLeft(mainSizer.Fit(G2frame.dataFrame))
1900    G2frame.PatternTree.SetItemPyData(item,data)
1901    if kind == 'PWDR':
1902        G2plt.PlotPatterns(G2frame,newPlot=True)
1903    elif kind == 'HKLF':
1904        G2plt.PlotSngl(G2frame,newPlot=True)
1905                 
1906################################################################################
1907#####  HKLF controls
1908################################################################################           
1909       
1910def UpdateHKLControls(G2frame,data):
1911   
1912    def OnScaleSlider(event):
1913        scale = int(scaleSel.GetValue())/1000.
1914        scaleSel.SetValue(int(scale*1000.))
1915        data['Scale'] = scale*1.
1916        G2plt.PlotSngl(G2frame)
1917       
1918    def OnLayerSlider(event):
1919        layer = layerSel.GetValue()
1920        data['Layer'] = layer
1921        G2plt.PlotSngl(G2frame)
1922       
1923    def OnSelZone(event):
1924        data['Zone'] = zoneSel.GetValue()
1925        izone = zones.index(data['Zone'])
1926        layerSel.SetRange(maxValue=HKLmax[izone],minValue=HKLmin[izone])
1927        G2plt.PlotSngl(G2frame,newPlot=True)
1928       
1929    def OnSelType(event):
1930        data['Type'] = typeSel.GetValue()
1931        G2plt.PlotSngl(G2frame)
1932       
1933    def SetStatusLine():
1934        Status.SetStatusText("")
1935                                     
1936    if G2frame.dataDisplay:
1937        G2frame.dataDisplay.Destroy()
1938    if not G2frame.dataFrame.GetStatusBar():
1939        Status = G2frame.dataFrame.CreateStatusBar()
1940    SetStatusLine()
1941    zones = ['100','010','001']
1942    HKLmax = data['HKLmax']
1943    HKLmin = data['HKLmin']
1944    typeChoices = ['Fosq','Fo','|DFsq|/sig','|DFsq|>sig','|DFsq|>3sig']
1945    G2frame.dataDisplay = wx.Panel(G2frame.dataFrame)
1946    SetDataMenuBar(G2frame)
1947    G2frame.dataFrame.SetTitle('HKL Plot Controls')
1948    mainSizer = wx.BoxSizer(wx.VERTICAL)
1949    mainSizer.Add((5,10),0)
1950   
1951    scaleSizer = wx.BoxSizer(wx.HORIZONTAL)
1952    scaleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Scale'),0,
1953        wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
1954    scaleSel = wx.Slider(parent=G2frame.dataDisplay,maxValue=1000,minValue=1,
1955        style=wx.SL_HORIZONTAL,value=int(data['Scale']*10))
1956    scaleSizer.Add(scaleSel,1,wx.EXPAND|wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
1957    scaleSel.SetLineSize(10)
1958    scaleSel.SetPageSize(10)
1959    scaleSel.Bind(wx.EVT_SLIDER, OnScaleSlider)
1960    mainSizer.Add(scaleSizer,0,wx.EXPAND|wx.RIGHT)
1961    mainSizer.Add((0,10),0)   
1962   
1963    zoneSizer = wx.BoxSizer(wx.HORIZONTAL)
1964    zoneSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Zone  '),0,
1965        wx.ALIGN_CENTER_VERTICAL)
1966    zoneSel = wx.ComboBox(parent=G2frame.dataDisplay,value=data['Zone'],choices=['100','010','001'],
1967        style=wx.CB_READONLY|wx.CB_DROPDOWN)
1968    zoneSel.Bind(wx.EVT_COMBOBOX, OnSelZone)
1969    zoneSizer.Add(zoneSel,0,wx.ALIGN_CENTER_VERTICAL)
1970    zoneSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Plot type  '),0,
1971        wx.ALIGN_CENTER_VERTICAL)       
1972    typeSel = wx.ComboBox(parent=G2frame.dataDisplay,value=data['Type'],choices=typeChoices,
1973        style=wx.CB_READONLY|wx.CB_DROPDOWN)
1974    typeSel.Bind(wx.EVT_COMBOBOX, OnSelType)
1975    zoneSizer.Add(typeSel,0,wx.ALIGN_CENTER_VERTICAL)
1976    zoneSizer.Add((10,0),0)   
1977    mainSizer.Add(zoneSizer,0,wx.EXPAND|wx.RIGHT)
1978    mainSizer.Add((0,10),0)   
1979       
1980    izone = zones.index(data['Zone'])
1981    layerSizer = wx.BoxSizer(wx.HORIZONTAL)
1982    layerSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Layer'),0,
1983        wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
1984    layerSel = wx.Slider(parent=G2frame.dataDisplay,maxValue=HKLmax[izone],minValue=HKLmin[izone],
1985        style=wx.SL_HORIZONTAL|wx.SL_AUTOTICKS|wx.SL_LABELS,value=0)
1986    layerSel.SetLineSize(1)
1987    layerSel.SetPageSize(1)
1988    layerSel.Bind(wx.EVT_SLIDER, OnLayerSlider)   
1989    layerSizer.Add(layerSel,1,wx.EXPAND|wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
1990    layerSizer.Add((10,0),0)   
1991    mainSizer.Add(layerSizer,1,wx.EXPAND|wx.RIGHT)
1992
1993       
1994    mainSizer.Layout()   
1995    G2frame.dataDisplay.SetSizer(mainSizer)
1996    G2frame.dataDisplay.SetSize(mainSizer.Fit(G2frame.dataFrame))
1997    G2frame.dataFrame.setSizePosLeft(mainSizer.Fit(G2frame.dataFrame))
1998
1999################################################################################
2000#####  Pattern tree routines
2001################################################################################           
2002       
2003def GetPatternTreeDataNames(G2frame,dataTypes):
2004    names = []
2005    item, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root)       
2006    while item:
2007        name = G2frame.PatternTree.GetItemText(item)
2008        if name[:4] in dataTypes:
2009            names.append(name)
2010        item, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie)
2011    return names
2012                         
2013def GetPatternTreeItemId(G2frame, parentId, itemText):
2014    item, cookie = G2frame.PatternTree.GetFirstChild(parentId)
2015    while item:
2016        if G2frame.PatternTree.GetItemText(item) == itemText:
2017            return item
2018        item, cookie = G2frame.PatternTree.GetNextChild(parentId, cookie)
2019    return 0               
2020
2021def MovePatternTreeToGrid(G2frame,item):
2022   
2023#    print G2frame.PatternTree.GetItemText(item)
2024   
2025    oldPage = 0
2026    if G2frame.dataFrame:
2027        SetDataMenuBar(G2frame)
2028        if G2frame.dataFrame.GetLabel() == 'Comments':
2029            try:
2030                data = [G2frame.dataDisplay.GetValue()]
2031                G2frame.dataDisplay.Clear() 
2032                Id = GetPatternTreeItemId(G2frame,G2frame.root, 'Comments')
2033                if Id: G2frame.PatternTree.SetItemPyData(Id,data)
2034            except:     #clumsy but avoids dead window problem when opening another project
2035                pass
2036        elif G2frame.dataFrame.GetLabel() == 'Notebook':
2037            try:
2038                data = [G2frame.dataDisplay.GetValue()]
2039                G2frame.dataDisplay.Clear() 
2040                Id = GetPatternTreeItemId(G2frame,G2frame.root, 'Notebook')
2041                if Id: G2frame.PatternTree.SetItemPyData(Id,data)
2042            except:     #clumsy but avoids dead window problem when opening another project
2043                pass
2044        elif 'Phase Data for' in G2frame.dataFrame.GetLabel():
2045            if G2frame.dataDisplay: 
2046                oldPage = G2frame.dataDisplay.GetSelection()
2047        G2frame.dataFrame.Clear()
2048        G2frame.dataFrame.SetLabel('')
2049    else:
2050        #create the frame for the data item window
2051        G2frame.dataFrame = DataFrame(parent=G2frame.mainPanel,frame=G2frame)
2052
2053    G2frame.dataFrame.Raise()           
2054    G2frame.PickId = 0
2055    parentID = G2frame.root
2056    for i in G2frame.ExportPattern: i.Enable(False)
2057    defWid = [250,150]
2058    if item != G2frame.root:
2059        parentID = G2frame.PatternTree.GetItemParent(item)
2060    if G2frame.PatternTree.GetItemParent(item) == G2frame.root:
2061        G2frame.PatternId = item
2062        G2frame.PickId = item
2063        if G2frame.PatternTree.GetItemText(item) == 'Notebook':
2064            SetDataMenuBar(G2frame,G2frame.dataFrame.DataNotebookMenu)
2065            G2frame.PatternId = 0
2066            for i in G2frame.ExportPattern: i.Enable(False)
2067            data = G2frame.PatternTree.GetItemPyData(item)
2068            UpdateNotebook(G2frame,data)
2069        elif G2frame.PatternTree.GetItemText(item) == 'Controls':
2070            G2frame.PatternId = 0
2071            for i in G2frame.ExportPattern: i.Enable(False)
2072            data = G2frame.PatternTree.GetItemPyData(item)
2073            if not data:           #fill in defaults
2074                data = {
2075                    #least squares controls
2076                    'deriv type':'analytic Hessian','min dM/M':0.0001,'shift factor':1.0,'max cyc':3}
2077                G2frame.PatternTree.SetItemPyData(item,data)                             
2078            for i in G2frame.Refine: i.Enable(True)
2079            for i in G2frame.SeqRefine: i.Enable(True)
2080            UpdateControls(G2frame,data)
2081        elif G2frame.PatternTree.GetItemText(item) == 'Sequental results':
2082            data = G2frame.PatternTree.GetItemPyData(item)
2083            UpdateSeqResults(G2frame,data)           
2084        elif G2frame.PatternTree.GetItemText(item) == 'Covariance':
2085            data = G2frame.PatternTree.GetItemPyData(item)
2086            G2frame.dataFrame.setSizePosLeft(defWid)
2087            text = ''
2088            if 'Rvals' in data:
2089                Nvars = len(data['varyList'])
2090                Rvals = data['Rvals']
2091                text = '\nFinal residuals: \nRw = %.3f%% \nchi**2 = %.1f \nGOF = %.2f'%(Rvals['Rwp'],Rvals['chisq'],Rvals['GOF'])
2092                text += '\nNobs = %d \nNvals = %d'%(Rvals['Nobs'],Nvars)
2093                if 'lamMax' in Rvals:
2094                    text += '\nlog10 MaxLambda = %.1f'%(np.log10(Rvals['lamMax']))
2095            wx.TextCtrl(parent=G2frame.dataFrame,size=G2frame.dataFrame.GetClientSize(),
2096                value='See plot window for covariance display'+text,style=wx.TE_MULTILINE)
2097            G2plt.PlotCovariance(G2frame,data)
2098        elif G2frame.PatternTree.GetItemText(item) == 'Constraints':
2099            data = G2frame.PatternTree.GetItemPyData(item)
2100            G2cnstG.UpdateConstraints(G2frame,data)
2101        elif G2frame.PatternTree.GetItemText(item) == 'Rigid bodies':
2102            data = G2frame.PatternTree.GetItemPyData(item)
2103            G2cnstG.UpdateRigidBodies(G2frame,data)
2104        elif G2frame.PatternTree.GetItemText(item) == 'Restraints':
2105            data = G2frame.PatternTree.GetItemPyData(item)
2106            Phases = G2frame.GetPhaseData()
2107            phase = ''
2108            phaseName = ''
2109            if Phases:
2110                phaseName = Phases.keys()[0]
2111            G2frame.dataFrame.setSizePosLeft(defWid)
2112            G2restG.UpdateRestraints(G2frame,data,Phases,phaseName)
2113        elif 'IMG' in G2frame.PatternTree.GetItemText(item):
2114            G2frame.Image = item
2115            G2plt.PlotImage(G2frame,newPlot=True)
2116        elif 'PKS' in G2frame.PatternTree.GetItemText(item):
2117            G2plt.PlotPowderLines(G2frame)
2118        elif 'PWDR' in G2frame.PatternTree.GetItemText(item):
2119            for i in G2frame.ExportPattern: i.Enable(True)
2120            UpdatePWHKPlot(G2frame,'PWDR',item)
2121        elif 'HKLF' in G2frame.PatternTree.GetItemText(item):
2122            G2frame.Sngl = item
2123            UpdatePWHKPlot(G2frame,'HKLF',item)
2124        elif 'PDF' in G2frame.PatternTree.GetItemText(item):
2125            G2frame.PatternId = item
2126            for i in G2frame.ExportPDF: i.Enable(True)
2127            G2plt.PlotISFG(G2frame,type='S(Q)')
2128        elif G2frame.PatternTree.GetItemText(item) == 'Phases':
2129            G2frame.dataFrame.setSizePosLeft(defWid)
2130            wx.TextCtrl(parent=G2frame.dataFrame,size=G2frame.dataFrame.GetClientSize(),
2131                value='Select one phase to see its parameters')           
2132    elif 'I(Q)' in G2frame.PatternTree.GetItemText(item):
2133        G2frame.PickId = item
2134        G2frame.PatternId = G2frame.PatternTree.GetItemParent(item)
2135        G2plt.PlotISFG(G2frame,type='I(Q)',newPlot=True)
2136    elif 'S(Q)' in G2frame.PatternTree.GetItemText(item):
2137        G2frame.PickId = item
2138        G2frame.PatternId = G2frame.PatternTree.GetItemParent(item)
2139        G2plt.PlotISFG(G2frame,type='S(Q)',newPlot=True)
2140    elif 'F(Q)' in G2frame.PatternTree.GetItemText(item):
2141        G2frame.PickId = item
2142        G2frame.PatternId = G2frame.PatternTree.GetItemParent(item)
2143        G2plt.PlotISFG(G2frame,type='F(Q)',newPlot=True)
2144    elif 'G(R)' in G2frame.PatternTree.GetItemText(item):
2145        G2frame.PickId = item
2146        G2frame.PatternId = G2frame.PatternTree.GetItemParent(item)
2147        G2plt.PlotISFG(G2frame,type='G(R)',newPlot=True)           
2148    elif G2frame.PatternTree.GetItemText(parentID) == 'Phases':
2149        G2frame.PickId = item
2150        data = G2frame.PatternTree.GetItemPyData(item)
2151        G2phG.UpdatePhaseData(G2frame,item,data,oldPage)
2152    elif G2frame.PatternTree.GetItemText(item) == 'Comments':
2153        SetDataMenuBar(G2frame,G2frame.dataFrame.DataCommentsMenu)
2154        G2frame.PatternId = G2frame.PatternTree.GetItemParent(item)
2155        G2frame.PickId = item
2156        data = G2frame.PatternTree.GetItemPyData(item)
2157        UpdateComments(G2frame,data)
2158    elif G2frame.PatternTree.GetItemText(item) == 'Image Controls':
2159        G2frame.dataFrame.SetTitle('Image Controls')
2160        G2frame.PickId = item
2161        G2frame.Image = G2frame.PatternTree.GetItemParent(item)
2162        masks = G2frame.PatternTree.GetItemPyData(
2163            GetPatternTreeItemId(G2frame,G2frame.Image, 'Masks'))
2164        data = G2frame.PatternTree.GetItemPyData(item)
2165        G2imG.UpdateImageControls(G2frame,data,masks)
2166        G2plt.PlotImage(G2frame)
2167    elif G2frame.PatternTree.GetItemText(item) == 'Masks':
2168        G2frame.dataFrame.SetTitle('Masks')
2169        G2frame.PickId = item
2170        G2frame.Image = G2frame.PatternTree.GetItemParent(item)
2171        data = G2frame.PatternTree.GetItemPyData(item)
2172        G2imG.UpdateMasks(G2frame,data)
2173        G2plt.PlotImage(G2frame)
2174    elif G2frame.PatternTree.GetItemText(item) == 'Stress/Strain':
2175        G2frame.dataFrame.SetTitle('Stress/Strain')
2176        G2frame.PickId = item
2177        G2frame.Image = G2frame.PatternTree.GetItemParent(item)
2178        data = G2frame.PatternTree.GetItemPyData(item)
2179        G2imG.UpdateStressStrain(G2frame,data)
2180        G2plt.PlotImage(G2frame)
2181    elif G2frame.PatternTree.GetItemText(item) == 'HKL Plot Controls':
2182        G2frame.PickId = item
2183        G2frame.Sngl = G2frame.PatternTree.GetItemParent(item)
2184        data = G2frame.PatternTree.GetItemPyData(item)
2185        UpdateHKLControls(G2frame,data)
2186        G2plt.PlotSngl(G2frame)
2187    elif G2frame.PatternTree.GetItemText(item) == 'PDF Controls':
2188        G2frame.PatternId = G2frame.PatternTree.GetItemParent(item)
2189        for i in G2frame.ExportPDF: i.Enable(True)
2190        G2frame.PickId = item
2191        data = G2frame.PatternTree.GetItemPyData(item)
2192        G2pdG.UpdatePDFGrid(G2frame,data)
2193        G2plt.PlotISFG(G2frame,type='I(Q)')
2194        G2plt.PlotISFG(G2frame,type='S(Q)')
2195        G2plt.PlotISFG(G2frame,type='F(Q)')
2196        G2plt.PlotISFG(G2frame,type='G(R)')
2197    elif G2frame.PatternTree.GetItemText(item) == 'Peak List':
2198        G2frame.PatternId = G2frame.PatternTree.GetItemParent(item)
2199        for i in G2frame.ExportPeakList: i.Enable(True)
2200        G2frame.PickId = item
2201        data = G2frame.PatternTree.GetItemPyData(item)
2202        G2pdG.UpdatePeakGrid(G2frame,data)
2203        G2plt.PlotPatterns(G2frame)
2204    elif G2frame.PatternTree.GetItemText(item) == 'Background':
2205        G2frame.PatternId = G2frame.PatternTree.GetItemParent(item)
2206        G2frame.PickId = item
2207        data = G2frame.PatternTree.GetItemPyData(item)
2208        G2pdG.UpdateBackground(G2frame,data)
2209        G2plt.PlotPatterns(G2frame)
2210    elif G2frame.PatternTree.GetItemText(item) == 'Limits':
2211        G2frame.PatternId = G2frame.PatternTree.GetItemParent(item)
2212        G2frame.PickId = item
2213        data = G2frame.PatternTree.GetItemPyData(item)
2214        G2pdG.UpdateLimitsGrid(G2frame,data)
2215        G2plt.PlotPatterns(G2frame)
2216    elif G2frame.PatternTree.GetItemText(item) == 'Instrument Parameters':
2217        G2frame.PatternId = G2frame.PatternTree.GetItemParent(item)
2218        G2frame.PickId = item
2219        data = G2frame.PatternTree.GetItemPyData(item)[0]
2220        G2pdG.UpdateInstrumentGrid(G2frame,data)
2221        G2plt.PlotPeakWidths(G2frame)
2222    elif G2frame.PatternTree.GetItemText(item) == 'Sample Parameters':
2223        G2frame.PatternId = G2frame.PatternTree.GetItemParent(item)
2224        G2frame.PickId = item
2225        data = G2frame.PatternTree.GetItemPyData(item)
2226
2227        if 'Temperature' not in data:           #temp fix for old gpx files
2228            data = {'Scale':[1.0,True],'Type':'Debye-Scherrer','Absorption':[0.0,False],'DisplaceX':[0.0,False],
2229                'DisplaceY':[0.0,False],'Diffuse':[],'Temperature':300.,'Pressure':1.0,'Humidity':0.0,'Voltage':0.0,
2230                'Force':0.0,'Gonio. radius':200.0}
2231            G2frame.PatternTree.SetItemPyData(item,data)
2232   
2233        G2pdG.UpdateSampleGrid(G2frame,data)
2234        G2plt.PlotPatterns(G2frame)
2235    elif G2frame.PatternTree.GetItemText(item) == 'Index Peak List':
2236        G2frame.PatternId = G2frame.PatternTree.GetItemParent(item)
2237        for i in G2frame.ExportPeakList: i.Enable(True)
2238        G2frame.PickId = item
2239        data = G2frame.PatternTree.GetItemPyData(item)
2240        G2pdG.UpdateIndexPeaksGrid(G2frame,data)
2241        if 'PKS' in G2frame.PatternTree.GetItemText(G2frame.PatternId):
2242            G2plt.PlotPowderLines(G2frame)
2243        else:
2244            G2plt.PlotPatterns(G2frame)
2245    elif G2frame.PatternTree.GetItemText(item) == 'Unit Cells List':
2246        G2frame.PatternId = G2frame.PatternTree.GetItemParent(item)
2247        G2frame.PickId = item
2248        data = G2frame.PatternTree.GetItemPyData(item)
2249        if not data:
2250            data.append([0,0.0,4,25.0,0,'P1',1,1,1,90,90,90]) #zero error flag, zero value, max Nc/No, start volume
2251            data.append([0,0,0,0,0,0,0,0,0,0,0,0,0,0])      #Bravais lattice flags
2252            data.append([])                                 #empty cell list
2253            data.append([])                                 #empty dmin
2254            G2frame.PatternTree.SetItemPyData(item,data)                             
2255        G2pdG.UpdateUnitCellsGrid(G2frame,data)
2256        if 'PKS' in G2frame.PatternTree.GetItemText(G2frame.PatternId):
2257            G2plt.PlotPowderLines(G2frame)
2258        else:
2259            G2plt.PlotPatterns(G2frame)
2260    elif G2frame.PatternTree.GetItemText(item) == 'Reflection Lists':   #powder reflections
2261        G2frame.PatternId = G2frame.PatternTree.GetItemParent(item)
2262        G2frame.PickId = item
2263        data = G2frame.PatternTree.GetItemPyData(item)
2264        G2frame.RefList = ''
2265        if len(data):
2266            G2frame.RefList = data.keys()[0]
2267        G2pdG.UpdateReflectionGrid(G2frame,data)
2268        G2plt.PlotPatterns(G2frame)
2269    elif G2frame.PatternTree.GetItemText(item) == 'Reflection List':    #HKLF reflections
2270        G2frame.PatternId = G2frame.PatternTree.GetItemParent(item)
2271        name = G2frame.PatternTree.GetItemText(G2frame.PatternId)
2272        data = G2frame.PatternTree.GetItemPyData(G2frame.PatternId)
2273        G2pdG.UpdateReflectionGrid(G2frame,data,HKLF=True,Name=name)
2274
2275def SetDataMenuBar(G2frame,menu=None):
2276        '''Set the menu for the data frame. On the Mac put this
2277        menu for the data tree window instead.
2278
2279        Note that data frame items do not have menus, for these (menu=None)
2280        display a blank menu or on the Mac display the standard menu for
2281        the data tree window.
2282        '''
2283        if sys.platform == "darwin":
2284            if menu is None:
2285                G2frame.SetMenuBar(G2frame.GSASIIMenu)
2286            else:
2287                G2frame.SetMenuBar(menu)
2288        else:
2289            if menu is None:
2290                G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.BlankMenu)
2291            else:
2292                G2frame.dataFrame.SetMenuBar(menu)
Note: See TracBrowser for help on using the repository browser.