source: trunk/GSASIIgrid.py @ 865

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

Add reference to the About GSAS-II box

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Author Revision URL Id
File size: 102.3 KB
Line 
1# -*- coding: utf-8 -*-
2#GSASIIgrid - data display routines
3########### SVN repository information ###################
4# $Date: 2013-03-19 14:38:15 +0000 (Tue, 19 Mar 2013) $
5# $Author: vondreele $
6# $Revision: 865 $
7# $URL: trunk/GSASIIgrid.py $
8# $Id: GSASIIgrid.py 865 2013-03-19 14:38:15Z 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: 865 $")
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.       
594Please cite:
595B.H. Toby & R.B. Von Dreele, J. Appl. Cryst. 46, 544-549 (2013) '''
596        info.Description = '''
597General Structure Analysis System - GSAS-II
598'''
599        wx.AboutBox(info)
600
601    def OnCheckUpdates(self,event):
602        '''Check if the GSAS-II repository has an update for the current source files
603        and perform that update if requested.
604        '''
605        if not GSASIIpath.whichsvn():
606            dlg = wx.MessageDialog(self,'No Subversion','Cannot update GSAS-II because subversion (svn) '+
607                                   'was not found.'
608                                   ,wx.OK)
609            dlg.ShowModal()
610            return
611        wx.BeginBusyCursor()
612        local = GSASIIpath.svnGetRev()
613        if local is None: 
614            wx.EndBusyCursor()
615            dlg = wx.MessageDialog(self.frame,
616                                   'Unable to run subversion on the GSAS-II current directory. Is GSAS-II installed correctly?',
617                                   'Subversion error',
618                                   wx.OK)
619            dlg.ShowModal()
620            return
621        print 'Installed GSAS-II version: '+local
622        repos = GSASIIpath.svnGetRev(local=False)
623        wx.EndBusyCursor()
624        if repos is None: 
625            dlg = wx.MessageDialog(self.frame,
626                                   'Unable to access the GSAS-II server. Is this computer on the internet?',
627                                   'Server unavailable',
628                                   wx.OK)
629            dlg.ShowModal()
630            return
631        print 'GSAS-II version on server: '+repos
632        if local == repos:
633            dlg = wx.MessageDialog(self.frame,
634                                   'GSAS-II is up-to-date. Version '+local+' is already loaded.',
635                                   'GSAS-II Up-to-date',
636                                   wx.OK)
637            dlg.ShowModal()
638            return
639        mods = GSASIIpath.svnFindLocalChanges()
640        if mods:
641            dlg = wx.MessageDialog(self.frame,
642                                   'You have version '+local+
643                                   ' of GSAS-II installed, but the current version is '+repos+
644                                   '. However, you have modified '+str(len(mods))+
645                                   ' file(s) on your local computer have been modified.'
646                                   ' Updating could wipe out your local changes. Press OK to start an update:',
647                                   'Local GSAS-II Mods',
648                                   wx.OK|wx.CANCEL)
649            if dlg.ShowModal() != wx.ID_OK: return
650        else:
651            dlg = wx.MessageDialog(self.frame,
652                                   'You have version '+local+
653                                   ' of GSAS-II installed, but the current version is '+repos+
654                                   '. Press OK to start an update:',
655                                   'GSAS-II Updates',
656                                   wx.OK|wx.CANCEL)
657            if dlg.ShowModal() != wx.ID_OK: return
658        print 'start updates'
659        wx.BeginBusyCursor()
660        moddict = GSASIIpath.svnUpdateDir()
661        wx.EndBusyCursor()
662        if moddict is None: 
663            dlg = wx.MessageDialog(self.frame,
664                                   'Error accessing the GSAS-II server or performing the update. '+
665                                   'Try again later or perform a manual update',
666                                   'Update Error',
667                                   wx.OK)
668            dlg.ShowModal()
669            return
670        modsbytype = {}
671        for key in moddict:
672            typ = moddict[key]
673            if modsbytype.get(typ) is None:
674                modsbytype[typ] = []
675            modsbytype[typ].append(key)
676        msg = 'Update was completed. Changes will take effect when GSAS-II is next updated. The following files were updated, ordered by status:'
677        for key in modsbytype:
678            msg += '\n' + key + ':\n\t'
679            for fil in modsbytype:
680                msg += fil + ', '
681        dlg = wx.MessageDialog(self.frame,msg, 'Update Completed', wx.OK)
682        dlg.ShowModal()
683        return
684
685class AddHelp(wx.Menu):
686    '''This class a single entry for the help menu (used on the Mac only):
687      'Help on <helpType>': where helpType is a reference to an HTML page to
688      be opened
689    NOTE: the title when appending this menu should be '&Help' so the wx handles
690    it correctly. BHT
691    '''
692    def __init__(self,frame,helpType,helpLbl=None,title=''):
693        wx.Menu.__init__(self,title)
694        self.frame = frame
695        if helpLbl is None: helpLbl = helpType
696        # add a help item only when helpType is specified
697        helpobj = self.Append(text='Help on '+helpLbl,
698                              id=wx.ID_ANY, kind=wx.ITEM_NORMAL)
699        frame.Bind(wx.EVT_MENU, self.OnHelpById, helpobj)
700        self.HelpById = helpType
701       
702    def OnHelpById(self,event):
703        '''Called when Help on... is pressed in a menu. Brings up
704        a web page for documentation.
705        '''
706        ShowHelp(self.HelpById,self.frame)
707
708class MyHtmlPanel(wx.Panel):
709    '''Defines a panel to display Help information'''
710    def __init__(self, frame, id):
711        self.frame = frame
712        wx.Panel.__init__(self, frame, id)
713        sizer = wx.BoxSizer(wx.VERTICAL)
714        back = wx.Button(self, -1, "Back")
715        back.Bind(wx.EVT_BUTTON, self.OnBack)
716        self.htmlwin = G2HtmlWindow(self, id, size=(750,450))
717        sizer.Add(self.htmlwin, 1,wx.EXPAND)
718        sizer.Add(back, 0, wx.ALIGN_LEFT, 0)
719        self.SetSizer(sizer)
720        sizer.Fit(frame)       
721        self.Bind(wx.EVT_SIZE,self.OnSize)
722    def OnSize(self,event):         #does the job but weirdly!!
723        anchor = self.htmlwin.GetOpenedAnchor()
724        if anchor:           
725            self.htmlwin.ScrollToAnchor(anchor)
726            wx.CallAfter(self.htmlwin.ScrollToAnchor,anchor)
727            event.Skip()
728    def OnBack(self, event):
729        self.htmlwin.HistoryBack()
730    def LoadFile(self,file):
731        pos = file.rfind('#')
732        if pos != -1:
733            helpfile = file[:pos]
734            helpanchor = file[pos+1:]
735        else:
736            helpfile = file
737            helpanchor = None
738        self.htmlwin.LoadPage(helpfile)
739        if helpanchor is not None:
740            self.htmlwin.ScrollToAnchor(helpanchor)
741            xs,ys = self.htmlwin.GetViewStart()
742            self.htmlwin.Scroll(xs,ys-1)
743
744class G2HtmlWindow(wx.html.HtmlWindow):
745    '''Displays help information in a primitive HTML browser type window
746    '''
747    def __init__(self, parent, *args, **kwargs):
748        self.parent = parent
749        wx.html.HtmlWindow.__init__(self, parent, *args, **kwargs)
750    def LoadPage(self, *args, **kwargs):
751        wx.html.HtmlWindow.LoadPage(self, *args, **kwargs)
752        self.TitlePage()
753    def OnLinkClicked(self, *args, **kwargs):
754        wx.html.HtmlWindow.OnLinkClicked(self, *args, **kwargs)
755        xs,ys = self.GetViewStart()
756        self.Scroll(xs,ys-1)
757        self.TitlePage()
758    def HistoryBack(self, *args, **kwargs):
759        wx.html.HtmlWindow.HistoryBack(self, *args, **kwargs)
760        self.TitlePage()
761    def TitlePage(self):
762        self.parent.frame.SetTitle(self.GetOpenedPage() + ' -- ' + 
763            self.GetOpenedPageTitle())
764
765class DataFrame(wx.Frame):
766    '''Create the dataframe window and its menus
767    '''
768    def PrefillDataMenu(self,menu,helpType,helpLbl=None,empty=False):
769        '''Create the "standard" part of data frame menus. Note that on Linux and
770        Windows, this is the standard help Menu. On Mac, this menu duplicates the
771        tree menu, but adds an extra help command for the data item and a separator.
772        '''
773        self.datamenu = menu
774        self.helpType = helpType
775        self.helpLbl = helpLbl
776        if sys.platform == "darwin": # mac                         
777            self.G2frame.FillMainMenu(menu) # add the data tree menu items
778            if not empty:
779                menu.Append(wx.Menu(title=''),title='|') # add a separator
780        #    menu.Append(AddHelp(self.G2frame,helpType=helpType, helpLbl=helpLbl),
781        #                title='&Help')
782        #else: # other
783        #    menu.Append(menu=MyHelp(self,helpType=helpType, helpLbl=helpLbl),
784        #                title='&Help')
785       
786    def PostfillDataMenu(self,empty=False):
787        '''Create the "standard" part of data frame menus. Note that on Linux and
788        Windows, this is the standard help Menu. On Mac, this menu duplicates the
789        tree menu, but adds an extra help command for the data item and a separator.
790        '''
791        menu = self.datamenu
792        helpType = self.helpType
793        helpLbl = self.helpLbl
794        if sys.platform == "darwin": # mac
795            if not empty:
796                menu.Append(wx.Menu(title=''),title='|') # add another separator
797            menu.Append(AddHelp(self.G2frame,helpType=helpType, helpLbl=helpLbl),
798                        title='&Help')
799        else: # other
800            menu.Append(menu=MyHelp(self,helpType=helpType, helpLbl=helpLbl),
801                        title='&Help')
802
803    def _init_menus(self):
804       
805# define all GSAS-II data frame menus       
806
807# for use where no menu or data frame help is provided
808        self.BlankMenu = wx.MenuBar()
809       
810# Controls
811        self.ControlsMenu = wx.MenuBar()
812        self.PrefillDataMenu(self.ControlsMenu,helpType='Controls',empty=True)
813        self.PostfillDataMenu(empty=True)
814       
815# Notebook
816        self.DataNotebookMenu = wx.MenuBar() 
817        self.PrefillDataMenu(self.DataNotebookMenu,helpType='Notebook',empty=True)
818        self.PostfillDataMenu(empty=True)
819       
820# Comments
821        self.DataCommentsMenu = wx.MenuBar()
822        self.PrefillDataMenu(self.DataCommentsMenu,helpType='Comments',empty=True)
823        self.PostfillDataMenu(empty=True)
824       
825# Constraints
826        self.ConstraintMenu = wx.MenuBar()
827        self.PrefillDataMenu(self.ConstraintMenu,helpType='Constraints')
828        self.ConstraintEdit = wx.Menu(title='')
829        self.ConstraintMenu.Append(menu=self.ConstraintEdit, title='Edit')
830        self.ConstraintEdit.Append(id=wxID_HOLDADD, kind=wx.ITEM_NORMAL,text='Add hold',
831            help='Add hold on a parameter value')
832        self.ConstraintEdit.Append(id=wxID_EQUIVADD, kind=wx.ITEM_NORMAL,text='Add equivalence',
833            help='Add equivalence between parameter values')
834        self.ConstraintEdit.Append(id=wxID_CONSTRAINTADD, kind=wx.ITEM_NORMAL,text='Add constraint',
835            help='Add constraint on parameter values')
836        self.ConstraintEdit.Append(id=wxID_FUNCTADD, kind=wx.ITEM_NORMAL,text='Add New Var',
837            help='Add variable composed of existing parameter')
838        self.PostfillDataMenu()
839       
840# Rigid bodies
841        self.VectorRBEdit = wx.Menu(title='')
842        self.VectorRBEdit.Append(id=wxID_RIGIDBODYADD, kind=wx.ITEM_NORMAL,text='Add rigid body',
843            help='Add vector rigid body')
844        self.ResidueRBMenu = wx.Menu(title='')
845        self.ResidueRBMenu.Append(id=wxID_RIGIDBODYIMPORT, kind=wx.ITEM_NORMAL,text='Import XYZ',
846            help='Import rigid body XYZ from file')
847        self.ResidueRBMenu.Append(id=wxID_RESIDUETORSSEQ, kind=wx.ITEM_NORMAL,text='Define sequence',
848            help='Define torsion sequence')
849        self.ResidueRBMenu.Append(id=wxID_RIGIDBODYADD, kind=wx.ITEM_NORMAL,text='Import residues',
850            help='Import residue rigid bodies from macro file')
851           
852        self.RigidBodyMenu = wx.MenuBar()
853        self.PrefillDataMenu(self.RigidBodyMenu,helpType='Rigid bodies')
854        self.RigidBodyMenu.Append(menu=self.VectorRBEdit, title='Edit')       
855        self.PostfillDataMenu()
856           
857# Restraints
858        self.RestraintEdit = wx.Menu(title='')
859        self.RestraintEdit.Append(id=wxID_RESTSELPHASE, kind=wx.ITEM_NORMAL,text='Select phase',
860            help='Select phase')
861        self.RestraintEdit.Append(id=wxID_RESTRAINTADD, kind=wx.ITEM_NORMAL,text='Add restraints',
862            help='Add restraints')
863        self.RestraintEdit.Enable(wxID_RESTRAINTADD,True)    #gets disenabled if macromolecule phase
864        self.RestraintEdit.Append(id=wxID_AARESTRAINTADD, kind=wx.ITEM_NORMAL,text='Add residue restraints',
865            help='Add residue based restraints for macromolecules from macro file')
866        self.RestraintEdit.Enable(wxID_AARESTRAINTADD,False)    #gets enabled if macromolecule phase
867        self.RestraintEdit.Append(id=wxID_AARESTRAINTPLOT, kind=wx.ITEM_NORMAL,text='Plot residue restraints',
868            help='Plot selected residue based restraints for macromolecules from macro file')
869        self.RestraintEdit.Enable(wxID_AARESTRAINTPLOT,False)    #gets enabled if macromolecule phase
870        self.RestraintEdit.Append(id=wxID_RESRCHANGEVAL, kind=wx.ITEM_NORMAL,text='Change value',
871            help='Change observed value')
872        self.RestraintEdit.Append(id=wxID_RESTCHANGEESD, kind=wx.ITEM_NORMAL,text='Change esd',
873            help='Change esd in observed value')
874        self.RestraintEdit.Append(id=wxID_RESTDELETE, kind=wx.ITEM_NORMAL,text='Delete restraints',
875            help='Delete selected restraints')
876
877        self.RestraintMenu = wx.MenuBar()
878        self.PrefillDataMenu(self.RestraintMenu,helpType='Restraints')
879        self.RestraintMenu.Append(menu=self.RestraintEdit, title='Edit')
880        self.PostfillDataMenu()
881           
882# Sequential results
883        self.SequentialMenu = wx.MenuBar()
884        self.PrefillDataMenu(self.SequentialMenu,helpType='Sequential',helpLbl='Sequential Refinement')
885        self.SequentialFile = wx.Menu(title='')
886        self.SequentialMenu.Append(menu=self.SequentialFile, title='File')
887        self.SequentialFile.Append(id=wxID_SAVESEQSEL, kind=wx.ITEM_NORMAL,text='Save...',
888            help='Save selected sequential refinement results')
889        self.PostfillDataMenu()
890           
891# PDR
892        self.ErrorMenu = wx.MenuBar()
893        self.PrefillDataMenu(self.ErrorMenu,helpType='PWD Analysis',helpLbl='Powder Fit Error Analysis')
894        self.ErrorAnal = wx.Menu(title='')
895        self.ErrorMenu.Append(menu=self.ErrorAnal,title='Analysis')
896        self.ErrorAnal.Append(id=wxID_PWDANALYSIS,kind=wx.ITEM_NORMAL,text='Analyze',
897            help='Error analysis on powder pattern')
898        self.PostfillDataMenu()
899           
900# PDR / Limits
901        self.LimitMenu = wx.MenuBar()
902        self.PrefillDataMenu(self.LimitMenu,helpType='Limits')
903        self.LimitEdit = wx.Menu(title='')
904        self.LimitMenu.Append(menu=self.LimitEdit, title='File')
905        self.LimitEdit.Append(id=wxID_LIMITCOPY, kind=wx.ITEM_NORMAL,text='Copy',
906            help='Copy limits to other histograms')
907        self.PostfillDataMenu()
908           
909# PDR / Background
910        self.BackMenu = wx.MenuBar()
911        self.PrefillDataMenu(self.BackMenu,helpType='Background')
912        self.BackEdit = wx.Menu(title='')
913        self.BackMenu.Append(menu=self.BackEdit, title='File')
914        self.BackEdit.Append(id=wxID_BACKCOPY, kind=wx.ITEM_NORMAL,text='Copy',
915            help='Copy background parameters to other histograms')
916        self.BackEdit.Append(id=wxID_BACKFLAGCOPY, kind=wx.ITEM_NORMAL,text='Copy flags',
917            help='Copy background refinement flags to other histograms')
918        self.PostfillDataMenu()
919           
920# PDR / Instrument Parameters
921        self.InstMenu = wx.MenuBar()
922        self.PrefillDataMenu(self.InstMenu,helpType='Instrument Parameters')
923        self.InstEdit = wx.Menu(title='')
924        self.InstMenu.Append(menu=self.InstEdit, title='Operations')
925        self.InstEdit.Append(help='Reset instrument profile parameters to default', 
926            id=wxID_INSTLOAD, kind=wx.ITEM_NORMAL,text='Load profile...')
927        self.InstEdit.Append(help='Load instrument profile parameters from file', 
928            id=wxID_INSTSAVE, kind=wx.ITEM_NORMAL,text='Save profile...')
929        self.InstEdit.Append(help='Save instrument profile parameters to file', 
930            id=wxID_INSTPRMRESET, kind=wx.ITEM_NORMAL,text='Reset profile')
931        self.InstEdit.Append(help='Copy instrument profile parameters to other histograms', 
932            id=wxID_INSTCOPY, kind=wx.ITEM_NORMAL,text='Copy')
933        self.InstEdit.Append(id=wxID_INSTFLAGCOPY, kind=wx.ITEM_NORMAL,text='Copy flags',
934            help='Copy instrument parameter refinement flags to other histograms')
935#        self.InstEdit.Append(help='Change radiation type (Ka12 - synch)',
936#            id=wxID_CHANGEWAVETYPE, kind=wx.ITEM_NORMAL,text='Change radiation')
937        self.PostfillDataMenu()
938       
939# PDR / Sample Parameters
940        self.SampleMenu = wx.MenuBar()
941        self.PrefillDataMenu(self.SampleMenu,helpType='Sample Parameters')
942        self.SampleEdit = wx.Menu(title='')
943        self.SampleMenu.Append(menu=self.SampleEdit, title='File')
944        self.SampleEdit.Append(id=wxID_SAMPLELOAD, kind=wx.ITEM_NORMAL,text='Load',
945            help='Load sample parameters from file')
946        self.SampleEdit.Append(id=wxID_SAMPLESAVE, kind=wx.ITEM_NORMAL,text='Save',
947            help='Save sample parameters to file')
948        self.SampleEdit.Append(id=wxID_SAMPLECOPY, kind=wx.ITEM_NORMAL,text='Copy',
949            help='Copy refinable sample parameters to other histograms')
950        self.SampleEdit.Append(id=wxID_SAMPLEFLAGCOPY, kind=wx.ITEM_NORMAL,text='Copy flags',
951            help='Copy sample parameter refinement flags to other histograms')
952        self.PostfillDataMenu()
953
954# PDR / Peak List
955        self.PeakMenu = wx.MenuBar()
956        self.PrefillDataMenu(self.PeakMenu,helpType='Peak List')
957        self.PeakEdit = wx.Menu(title='')
958        self.PeakMenu.Append(menu=self.PeakEdit, title='Peak Fitting')
959        self.AutoSearch = self.PeakEdit.Append(help='Automatic peak search', 
960            id=wxID_AUTOSEARCH, kind=wx.ITEM_NORMAL,text='Auto search')
961        self.UnDo = self.PeakEdit.Append(help='Undo last least squares refinement', 
962            id=wxID_UNDO, kind=wx.ITEM_NORMAL,text='UnDo')
963        self.PeakFit = self.PeakEdit.Append(id=wxID_LSQPEAKFIT, kind=wx.ITEM_NORMAL,text='LSQ PeakFit', 
964            help='Peak fitting via least-squares' )
965        self.PFOneCycle = self.PeakEdit.Append(id=wxID_LSQONECYCLE, kind=wx.ITEM_NORMAL,text='LSQ one cycle', 
966            help='One cycle of Peak fitting via least-squares' )
967        self.PeakEdit.Append(id=wxID_RESETSIGGAM, kind=wx.ITEM_NORMAL, 
968            text='Reset sig and gam',help='Reset sigma and gamma to global fit' )
969        self.PeakEdit.Append(id=wxID_CLEARPEAKS, kind=wx.ITEM_NORMAL,text='Clear peaks', 
970            help='Clear the peak list' )
971        self.PostfillDataMenu()
972        self.UnDo.Enable(False)
973        self.PeakFit.Enable(False)
974        self.PFOneCycle.Enable(False)
975       
976# PDR / Index Peak List
977        self.IndPeaksMenu = wx.MenuBar()
978        self.PrefillDataMenu(self.IndPeaksMenu,helpType='Index Peak List')
979        self.IndPeaksEdit = wx.Menu(title='')
980        self.IndPeaksMenu.Append(menu=self.IndPeaksEdit,title='Operations')
981        self.IndPeaksEdit.Append(help='Load/Reload index peaks from peak list',id=wxID_INDXRELOAD, 
982            kind=wx.ITEM_NORMAL,text='Load/Reload')
983        self.PostfillDataMenu()
984       
985# PDR / Unit Cells List
986        self.IndexMenu = wx.MenuBar()
987        self.PrefillDataMenu(self.IndexMenu,helpType='Unit Cells List')
988        self.IndexEdit = wx.Menu(title='')
989        self.IndexMenu.Append(menu=self.IndexEdit, title='Cell Index/Refine')
990        self.IndexPeaks = self.IndexEdit.Append(help='', id=wxID_INDEXPEAKS, kind=wx.ITEM_NORMAL,
991            text='Index Cell')
992        self.CopyCell = self.IndexEdit.Append( id=wxID_COPYCELL, kind=wx.ITEM_NORMAL,text='Copy Cell', 
993            help='Copy selected unit cell from indexing to cell refinement fields')
994        self.RefineCell = self.IndexEdit.Append( id=wxID_REFINECELL, kind=wx.ITEM_NORMAL, 
995            text='Refine Cell',help='Refine unit cell parameters from indexed peaks')
996        self.MakeNewPhase = self.IndexEdit.Append( id=wxID_MAKENEWPHASE, kind=wx.ITEM_NORMAL,
997            text='Make new phase',help='Make new phase from selected unit cell')
998        self.PostfillDataMenu()
999        self.IndexPeaks.Enable(False)
1000        self.CopyCell.Enable(False)
1001        self.RefineCell.Enable(False)
1002        self.MakeNewPhase.Enable(False)
1003       
1004# PDR / Reflection Lists
1005        self.ReflMenu = wx.MenuBar()
1006        self.PrefillDataMenu(self.ReflMenu,helpType='Reflection List')
1007        self.ReflEdit = wx.Menu(title='')
1008        self.ReflMenu.Append(menu=self.ReflEdit, title='Reflection List')
1009        self.SelectPhase = self.ReflEdit.Append(help='Select phase for reflection list',id=wxID_SELECTPHASE, 
1010            kind=wx.ITEM_NORMAL,text='Select phase')
1011        self.PostfillDataMenu()
1012       
1013# IMG / Image Controls
1014        self.ImageMenu = wx.MenuBar()
1015        self.PrefillDataMenu(self.ImageMenu,helpType='Image Controls')
1016        self.ImageEdit = wx.Menu(title='')
1017        self.ImageMenu.Append(menu=self.ImageEdit, title='Operations')
1018        self.ImageEdit.Append(help='Calibrate detector by fitting to calibrant lines', 
1019            id=wxID_IMCALIBRATE, kind=wx.ITEM_NORMAL,text='Calibrate')
1020        self.ImageEdit.Append(help='Recalibrate detector by fitting to calibrant lines', 
1021            id=wxID_IMRECALIBRATE, kind=wx.ITEM_NORMAL,text='Recalibrate')
1022        self.ImageEdit.Append(help='Clear calibration data points and rings',id=wxID_IMCLEARCALIB, 
1023            kind=wx.ITEM_NORMAL,text='Clear calibration')
1024        self.ImageEdit.Append(help='Integrate selected image',id=wxID_IMINTEGRATE, 
1025            kind=wx.ITEM_NORMAL,text='Integrate')
1026        self.ImageEdit.Append(help='Integrate all images selected from list',id=wxID_INTEGRATEALL,
1027            kind=wx.ITEM_NORMAL,text='Integrate all')
1028        self.ImageEdit.Append(help='Copy image controls to other images', 
1029            id=wxID_IMCOPYCONTROLS, kind=wx.ITEM_NORMAL,text='Copy Controls')
1030        self.ImageEdit.Append(help='Save image controls to file', 
1031            id=wxID_IMSAVECONTROLS, kind=wx.ITEM_NORMAL,text='Save Controls')
1032        self.ImageEdit.Append(help='Load image controls from file', 
1033            id=wxID_IMLOADCONTROLS, kind=wx.ITEM_NORMAL,text='Load Controls')
1034        self.PostfillDataMenu()
1035           
1036# IMG / Masks
1037        self.MaskMenu = wx.MenuBar()
1038        self.PrefillDataMenu(self.MaskMenu,helpType='Image Masks')
1039        self.MaskEdit = wx.Menu(title='')
1040        self.MaskMenu.Append(menu=self.MaskEdit, title='Operations')
1041        self.MaskEdit.Append(help='Copy mask to other images', 
1042            id=wxID_MASKCOPY, kind=wx.ITEM_NORMAL,text='Copy mask')
1043        self.MaskEdit.Append(help='Save mask to file', 
1044            id=wxID_MASKSAVE, kind=wx.ITEM_NORMAL,text='Save mask')
1045        self.MaskEdit.Append(help='Load mask from file', 
1046            id=wxID_MASKLOAD, kind=wx.ITEM_NORMAL,text='Load mask')
1047        self.PostfillDataMenu()
1048           
1049# IMG / Stress/Strain
1050
1051        self.StrStaMenu = wx.MenuBar()
1052        self.PrefillDataMenu(self.StrStaMenu,helpType='Stress/Strain')
1053        self.StrStaEdit = wx.Menu(title='')
1054        self.StrStaMenu.Append(menu=self.StrStaEdit, title='Operations')
1055        self.StrStaEdit.Append(help='Append d-zero for one ring', 
1056            id=wxID_APPENDDZERO, kind=wx.ITEM_NORMAL,text='Append d-zero')
1057        self.StrStaEdit.Append(help='Fit stress/strain data', 
1058            id=wxID_STRSTAFIT, kind=wx.ITEM_NORMAL,text='Fit stress/strain')
1059        self.StrStaEdit.Append(help='Copy stress/strain data to other images', 
1060            id=wxID_STRSTACOPY, kind=wx.ITEM_NORMAL,text='Copy stress/strain')
1061        self.StrStaEdit.Append(help='Save stress/strain data to file', 
1062            id=wxID_STRSTASAVE, kind=wx.ITEM_NORMAL,text='Save stress/strain')
1063        self.StrStaEdit.Append(help='Load stress/strain data from file', 
1064            id=wxID_STRSTALOAD, kind=wx.ITEM_NORMAL,text='Load stress/strain')
1065        self.PostfillDataMenu()
1066           
1067# PDF / PDF Controls
1068        self.PDFMenu = wx.MenuBar()
1069        self.PrefillDataMenu(self.PDFMenu,helpType='PDF Controls')
1070        self.PDFEdit = wx.Menu(title='')
1071        self.PDFMenu.Append(menu=self.PDFEdit, title='PDF Controls')
1072        self.PDFEdit.Append(help='Add element to sample composition',id=wxID_PDFADDELEMENT, kind=wx.ITEM_NORMAL,
1073            text='Add element')
1074        self.PDFEdit.Append(help='Delete element from sample composition',id=wxID_PDFDELELEMENT, kind=wx.ITEM_NORMAL,
1075            text='Delete element')
1076        self.PDFEdit.Append(help='Copy PDF controls', id=wxID_PDFCOPYCONTROLS, kind=wx.ITEM_NORMAL,
1077            text='Copy controls')
1078#        self.PDFEdit.Append(help='Load PDF controls from file',id=wxID_PDFLOADCONTROLS, kind=wx.ITEM_NORMAL,
1079#            text='Load Controls')
1080#        self.PDFEdit.Append(help='Save PDF controls to file', id=wxID_PDFSAVECONTROLS, kind=wx.ITEM_NORMAL,
1081#            text='Save controls')
1082        self.PDFEdit.Append(help='Compute PDF', id=wxID_PDFCOMPUTE, kind=wx.ITEM_NORMAL,
1083            text='Compute PDF')
1084        self.PDFEdit.Append(help='Compute all PDFs', id=wxID_PDFCOMPUTEALL, kind=wx.ITEM_NORMAL,
1085            text='Compute all PDFs')
1086        self.PostfillDataMenu()
1087           
1088# Phase / General tab
1089
1090        self.DataGeneral = wx.MenuBar()
1091        self.PrefillDataMenu(self.DataGeneral,helpType='General', helpLbl='Phase/General')
1092        self.GeneralCalc = wx.Menu(title='')
1093        self.DataGeneral.Append(menu=self.GeneralCalc,title='Compute')
1094        self.GeneralCalc.Append(help='Compute Fourier map',id=wxID_FOURCALC, kind=wx.ITEM_NORMAL,
1095            text='Fourier map')
1096        self.GeneralCalc.Append(help='Search Fourier map',id=wxID_FOURSEARCH, kind=wx.ITEM_NORMAL,
1097            text='Search map')
1098        self.GeneralCalc.Append(help='Run charge flipping',id=wxID_CHARGEFLIP, kind=wx.ITEM_NORMAL,
1099            text='Charge flipping')
1100        self.GeneralCalc.Append(help='Clear map',id=wxID_FOURCLEAR, kind=wx.ITEM_NORMAL,
1101            text='Clear map')
1102        self.PostfillDataMenu()
1103       
1104# Phase / Data tab
1105        self.DataMenu = wx.MenuBar()
1106        self.PrefillDataMenu(self.DataMenu,helpType='Data', helpLbl='Phase/Data')
1107        self.DataEdit = wx.Menu(title='')
1108        self.DataMenu.Append(menu=self.DataEdit, title='Edit')
1109        self.DataEdit.Append(id=wxID_PWDRADD, kind=wx.ITEM_NORMAL,text='Add powder histograms',
1110            help='Select new powder histograms to be used for this phase')
1111        self.DataEdit.Append(id=wxID_HKLFADD, kind=wx.ITEM_NORMAL,text='Add single crystal histograms',
1112            help='Select new single crystal histograms to be used for this phase')
1113        self.DataEdit.Append(id=wxID_DATADELETE, kind=wx.ITEM_NORMAL,text='Delete histograms',
1114            help='Delete histograms from use for this phase')
1115        self.PostfillDataMenu()
1116           
1117# Phase / Atoms tab
1118        self.AtomsMenu = wx.MenuBar()
1119        self.PrefillDataMenu(self.AtomsMenu,helpType='Atoms')
1120        self.AtomEdit = wx.Menu(title='')
1121        self.AtomCompute = wx.Menu(title='')
1122        self.AtomsMenu.Append(menu=self.AtomEdit, title='Edit')
1123        self.AtomsMenu.Append(menu=self.AtomCompute, title='Compute')
1124        self.AtomEdit.Append(id=wxID_ATOMSEDITADD, kind=wx.ITEM_NORMAL,text='Append atom',
1125            help='Appended as an H atom')
1126        self.AtomEdit.Append(id=wxID_ATOMSVIEWADD, kind=wx.ITEM_NORMAL,text='Append view point',
1127            help='Appended as an H atom')
1128        self.AtomEdit.Append(id=wxID_RBAPPEND, kind=wx.ITEM_NORMAL,text='Append rigid body',
1129            help='Append atoms for rigid body')
1130        self.AtomEdit.Append(id=wxID_ATOMSEDITINSERT, kind=wx.ITEM_NORMAL,text='Insert atom',
1131            help='Select atom row to insert before; inserted as an H atom')
1132        self.AtomEdit.Append(id=wxID_ATOMVIEWINSERT, kind=wx.ITEM_NORMAL,text='Insert view point',
1133            help='Select atom row to insert before; inserted as an H atom')
1134        self.AtomEdit.Append(id=wxID_ATOMMOVE, kind=wx.ITEM_NORMAL,text='Move atom to view point',
1135            help='Select single atom to move')
1136        self.AtomEdit.Append(id=wxID_ATOMSEDITDELETE, kind=wx.ITEM_NORMAL,text='Delete atom',
1137            help='Select atoms to delete first')
1138        self.AtomEdit.Append(id=wxID_ATOMSREFINE, kind=wx.ITEM_NORMAL,text='Set atom refinement flags',
1139            help='Select atoms to refine first')
1140        self.AtomEdit.Append(id=wxID_ATOMSMODIFY, kind=wx.ITEM_NORMAL,text='Modify atom parameters',
1141            help='Select atoms to modify first')
1142        self.AtomEdit.Append(id=wxID_ATOMSTRANSFORM, kind=wx.ITEM_NORMAL,text='Transform atoms',
1143            help='Select atoms to transform first')
1144        self.AtomEdit.Append(id=wxID_RELOADDRAWATOMS, kind=wx.ITEM_NORMAL,text='Reload draw atoms',
1145            help='Reload atom drawing list')
1146        self.AtomEdit.Append(id=wxID_ATOMSREIMPORT, kind=wx.ITEM_NORMAL,text='Reimport atoms',
1147            help='Reimport atoms from file; sequence must match')
1148        self.AtomCompute.Append(id=wxID_ATOMSDISAGL, kind=wx.ITEM_NORMAL,text='Distances && Angles',
1149            help='Compute distances & angles for selected atoms')
1150        self.PostfillDataMenu()
1151                 
1152# Phase / Draw Options tab
1153        self.DataDrawOptions = wx.MenuBar()
1154        self.PrefillDataMenu(self.DataDrawOptions,helpType='Draw Options', helpLbl='Phase/Draw Options',empty=True)
1155        self.PostfillDataMenu(empty=True)
1156       
1157# Phase / Draw Atoms tab
1158        self.DrawAtomsMenu = wx.MenuBar()
1159        self.PrefillDataMenu(self.DrawAtomsMenu,helpType='Draw Atoms')
1160        self.DrawAtomEdit = wx.Menu(title='')
1161        self.DrawAtomCompute = wx.Menu(title='')
1162        self.DrawAtomRestraint = wx.Menu(title='')
1163        self.DrawAtomRigidBody = wx.Menu(title='')
1164        self.DrawAtomsMenu.Append(menu=self.DrawAtomEdit, title='Edit')
1165        self.DrawAtomsMenu.Append(menu=self.DrawAtomCompute,title='Compute')
1166        self.DrawAtomsMenu.Append(menu=self.DrawAtomRestraint, title='Restraints')
1167        self.DrawAtomsMenu.Append(menu=self.DrawAtomRigidBody, title='Rigid body')
1168        self.DrawAtomEdit.Append(id=wxID_DRAWATOMSTYLE, kind=wx.ITEM_NORMAL,text='Atom style',
1169            help='Select atoms first')
1170        self.DrawAtomEdit.Append(id=wxID_DRAWATOMLABEL, kind=wx.ITEM_NORMAL,text='Atom label',
1171            help='Select atoms first')
1172        self.DrawAtomEdit.Append(id=wxID_DRAWATOMCOLOR, kind=wx.ITEM_NORMAL,text='Atom color',
1173            help='Select atoms first')
1174        self.DrawAtomEdit.Append(id=wxID_DRAWATOMRESETCOLOR, kind=wx.ITEM_NORMAL,text='Reset atom colors',
1175            help='Resets all atom colors to defaults')
1176        self.DrawAtomEdit.Append(id=wxID_DRAWVIEWPOINT, kind=wx.ITEM_NORMAL,text='View point',
1177            help='View point is 1st atom selected')
1178        self.DrawAtomEdit.Append(id=wxID_DRAWADDEQUIV, kind=wx.ITEM_NORMAL,text='Add atoms',
1179            help='Add symmetry & cell equivalents to drawing set from selected atoms')
1180        self.DrawAtomEdit.Append(id=wxID_DRAWTRANSFORM, kind=wx.ITEM_NORMAL,text='Transform atoms',
1181            help='Transform selected atoms by symmetry & cell translations')
1182        self.DrawAtomEdit.Append(id=wxID_DRAWFILLCOORD, kind=wx.ITEM_NORMAL,text='Fill CN-sphere',
1183            help='Fill coordination sphere for selected atoms')           
1184        self.DrawAtomEdit.Append(id=wxID_DRAWFILLCELL, kind=wx.ITEM_NORMAL,text='Fill unit cell',
1185            help='Fill unit cell with selected atoms')
1186        self.DrawAtomEdit.Append(id=wxID_DRAWDELETE, kind=wx.ITEM_NORMAL,text='Delete atoms',
1187            help='Delete atoms from drawing set')
1188        self.DrawAtomCompute.Append(id=wxID_DRAWDISTVP, kind=wx.ITEM_NORMAL,text='View pt. dist.',
1189            help='Compute distance of selected atoms from view point')   
1190        self.DrawAtomCompute.Append(id=wxID_DRAWDISAGLTOR, kind=wx.ITEM_NORMAL,text='Dist. Ang. Tors.',
1191            help='Compute distance, angle or torsion for 2-4 selected atoms')   
1192        self.DrawAtomCompute.Append(id=wxID_DRAWPLANE, kind=wx.ITEM_NORMAL,text='Best plane',
1193            help='Compute best plane for 4+ selected atoms')   
1194        self.DrawAtomRestraint.Append(id=wxID_DRAWRESTRBOND, kind=wx.ITEM_NORMAL,text='Add bond restraint',
1195            help='Add bond restraint for selected atoms (2)')
1196        self.DrawAtomRestraint.Append(id=wxID_DRAWRESTRANGLE, kind=wx.ITEM_NORMAL,text='Add angle restraint',
1197            help='Add angle restraint for selected atoms (3: one end 1st)')
1198        self.DrawAtomRestraint.Append(id=wxID_DRAWRESTRPLANE, kind=wx.ITEM_NORMAL,text='Add plane restraint',
1199            help='Add plane restraint for selected atoms (4+)')
1200        self.DrawAtomRestraint.Append(id=wxID_DRAWRESTRCHIRAL, kind=wx.ITEM_NORMAL,text='Add chiral restraint',
1201            help='Add chiral restraint for selected atoms (4: center atom 1st)')
1202        self.DrawAtomRigidBody.Append(id=wxID_DRAWDEFINERB, kind=wx.ITEM_NORMAL,text='Define rigid body',
1203            help='Define rigid body with selected atoms')
1204        self.PostfillDataMenu()
1205           
1206# Phase / Texture tab
1207        self.TextureMenu = wx.MenuBar()
1208        self.PrefillDataMenu(self.TextureMenu,helpType='Texture')
1209        self.TextureEdit = wx.Menu(title='')
1210        self.TextureMenu.Append(menu=self.TextureEdit, title='Texture')
1211        self.TextureEdit.Append(id=wxID_REFINETEXTURE, kind=wx.ITEM_NORMAL,text='Refine texture', 
1212            help='Refine the texture coefficients from sequential Pawley results')
1213        self.TextureEdit.Append(id=wxID_CLEARTEXTURE, kind=wx.ITEM_NORMAL,text='Clear texture', 
1214            help='Clear the texture coefficients' )
1215        self.PostfillDataMenu()
1216           
1217# Phase / Pawley tab
1218        self.PawleyMenu = wx.MenuBar()
1219        self.PrefillDataMenu(self.PawleyMenu,helpType='Pawley')
1220        self.PawleyEdit = wx.Menu(title='')
1221        self.PawleyMenu.Append(menu=self.PawleyEdit,title='Operations')
1222        self.PawleyEdit.Append(id=wxID_PAWLEYLOAD, kind=wx.ITEM_NORMAL,text='Pawley create',
1223            help='Initialize Pawley reflection list')
1224        self.PawleyEdit.Append(id=wxID_PAWLEYESTIMATE, kind=wx.ITEM_NORMAL,text='Pawley estimate',
1225            help='Estimate initial Pawley intensities')
1226        self.PawleyEdit.Append(id=wxID_PAWLEYUPDATE, kind=wx.ITEM_NORMAL,text='Pawley update',
1227            help='Update Pawley intensities with abs(Fobs) from reflection list')
1228#        self.PawleyEdit.Append(id=wxID_PAWLEYDELETE, kind=wx.ITEM_NORMAL,text='Pawley delete',
1229#            help='Delete selected Pawley reflection')
1230        self.PostfillDataMenu()
1231           
1232# Phase / Map peaks tab
1233        self.MapPeaksMenu = wx.MenuBar()
1234        self.PrefillDataMenu(self.MapPeaksMenu,helpType='Map peaks')
1235        self.MapPeaksEdit = wx.Menu(title='')
1236        self.MapPeaksMenu.Append(menu=self.MapPeaksEdit, title='Map peaks')
1237        self.MapPeaksEdit.Append(id=wxID_PEAKSMOVE, kind=wx.ITEM_NORMAL,text='Move peaks', 
1238            help='Move selected peaks to atom list')
1239        self.MapPeaksEdit.Append(id=wxID_PEAKSVIEWPT, kind=wx.ITEM_NORMAL,text='View point',
1240            help='View point is 1st peak selected')
1241        self.MapPeaksEdit.Append(id=wxID_PEAKSDISTVP, kind=wx.ITEM_NORMAL,text='View pt. dist.',
1242            help='Compute distance of selected peaks from view point')   
1243        self.MapPeaksEdit.Append(id=wxID_SHOWBONDS, kind=wx.ITEM_NORMAL,text='Hide bonds',
1244            help='Hide or show bonds between peak positions')   
1245        self.MapPeaksEdit.Append(id=wxID_PEAKSDA, kind=wx.ITEM_NORMAL,text='Calc dist/ang', 
1246            help='Calculate distance or angle for selection')
1247        self.MapPeaksEdit.Append(id=wxID_FINDEQVPEAKS, kind=wx.ITEM_NORMAL,text='Equivalent peaks', 
1248            help='Find equivalent peaks')
1249        self.MapPeaksEdit.Append(id=wxID_PEAKSUNIQUE, kind=wx.ITEM_NORMAL,text='Unique peaks', 
1250            help='Select unique set')
1251        self.MapPeaksEdit.Append(id=wxID_PEAKSDELETE, kind=wx.ITEM_NORMAL,text='Delete peaks', 
1252            help='Delete selected peaks')
1253        self.MapPeaksEdit.Append(id=wxID_PEAKSCLEAR, kind=wx.ITEM_NORMAL,text='Clear peaks', 
1254            help='Clear the map peak list')
1255        self.PostfillDataMenu()
1256
1257# Phase / Rigid bodies tab
1258        self.RigidBodiesMenu = wx.MenuBar()
1259        self.PrefillDataMenu(self.MapPeaksMenu,helpType='Rigid bodies')
1260        self.RigidBodiesEdit = wx.Menu(title='')
1261        self.RigidBodiesMenu.Append(menu=self.RigidBodiesEdit, title='Edit')
1262        self.RigidBodiesEdit.Append(id=wxID_ASSIGNATMS2RB, kind=wx.ITEM_NORMAL,text='Assign atoms to rigid body',
1263            help='Select & position rigid body in structure of existing atoms')
1264        self.RigidBodiesEdit.Append(id=wxID_AUTOFINDRESRB, kind=wx.ITEM_NORMAL,text='Auto find residues',
1265            help='Auto find of residue RBs in macromolecule')
1266        self.RigidBodiesEdit.Append(id=wxID_COPYRBPARMS, kind=wx.ITEM_NORMAL,text='Copy rigid body parms',
1267            help='Copy rigid body location & TLS parameters')
1268        self.RigidBodiesEdit.Append(id=wxID_GLOBALRESREFINE, kind=wx.ITEM_NORMAL,text='Global residue refine',
1269            help='Global setting of residue RB refinement flags')
1270        self.RigidBodiesEdit.Append(id=wxID_RBREMOVEALL, kind=wx.ITEM_NORMAL,text='Remove all rigid bodies',
1271            help='Remove all rigid body assignment for atoms')
1272        self.PostfillDataMenu()
1273           
1274# end of GSAS-II menu definitions
1275       
1276    def _init_ctrls(self, parent,name=None,size=None,pos=None):
1277        wx.Frame.__init__(self,parent=parent,
1278            style=wx.DEFAULT_FRAME_STYLE ^ wx.CLOSE_BOX | wx.FRAME_FLOAT_ON_PARENT ,
1279            size=size,pos=pos,title='GSAS-II data display')
1280        self._init_menus()
1281        if name:
1282            self.SetLabel(name)
1283        self.Show()
1284       
1285    def __init__(self,parent,frame,data=None,name=None, size=None,pos=None):
1286        self.G2frame = frame
1287        self._init_ctrls(parent,name,size,pos)
1288        self.data = data
1289        clientSize = wx.ClientDisplayRect()
1290        Size = self.GetSize()
1291        xPos = clientSize[2]-Size[0]
1292        self.SetPosition(wx.Point(xPos,clientSize[1]+250))
1293        self.AtomGrid = []
1294        self.selectedRow = 0
1295       
1296    def setSizePosLeft(self,Width):
1297        clientSize = wx.ClientDisplayRect()
1298        Width[1] = min(Width[1],clientSize[2]-300)
1299        Width[0] = max(Width[0],300)
1300        self.SetSize(Width)
1301#        self.SetPosition(wx.Point(clientSize[2]-Width[0],clientSize[1]+250))
1302       
1303    def Clear(self):
1304        self.ClearBackground()
1305        self.DestroyChildren()
1306                   
1307################################################################################
1308#####  GSNotebook
1309################################################################################           
1310       
1311class GSNoteBook(wx.Notebook):
1312    def __init__(self, parent, name='',size = None):
1313        wx.Notebook.__init__(self, parent, -1, name=name, style= wx.BK_TOP)
1314        if size: self.SetSize(size)
1315                                                     
1316    def Clear(self):       
1317        GSNoteBook.DeleteAllPages(self)
1318       
1319    def FindPage(self,name):
1320        numPage = self.GetPageCount()
1321        for page in range(numPage):
1322            if self.GetPageText(page) == name:
1323                return page
1324       
1325################################################################################
1326#####  GSGrid
1327################################################################################           
1328       
1329class GSGrid(wg.Grid):
1330    def __init__(self, parent, name=''):
1331        wg.Grid.__init__(self,parent,-1,name=name)                   
1332        self.SetSize(parent.GetClientSize())
1333           
1334    def Clear(self):
1335        wg.Grid.ClearGrid(self)
1336       
1337    def SetCellStyle(self,r,c,color="white",readonly=True):
1338        self.SetCellBackgroundColour(r,c,color)
1339        self.SetReadOnly(r,c,isReadOnly=readonly)
1340       
1341    def GetSelection(self):
1342        #this is to satisfy structure drawing stuff in G2plt when focus changes
1343        return None
1344                                               
1345################################################################################
1346#####  Table
1347################################################################################           
1348       
1349class Table(wg.PyGridTableBase):
1350    def __init__(self, data=[], rowLabels=None, colLabels=None, types = None):
1351        wg.PyGridTableBase.__init__(self)
1352        self.colLabels = colLabels
1353        self.rowLabels = rowLabels
1354        self.dataTypes = types
1355        self.data = data
1356       
1357    def AppendRows(self, numRows=1):
1358        self.data.append([])
1359        return True
1360       
1361    def CanGetValueAs(self, row, col, typeName):
1362        if self.dataTypes:
1363            colType = self.dataTypes[col].split(':')[0]
1364            if typeName == colType:
1365                return True
1366            else:
1367                return False
1368        else:
1369            return False
1370
1371    def CanSetValueAs(self, row, col, typeName):
1372        return self.CanGetValueAs(row, col, typeName)
1373
1374    def DeleteRow(self,pos):
1375        data = self.GetData()
1376        self.SetData([])
1377        new = []
1378        for irow,row in enumerate(data):
1379            if irow <> pos:
1380                new.append(row)
1381        self.SetData(new)
1382       
1383    def GetColLabelValue(self, col):
1384        if self.colLabels:
1385            return self.colLabels[col]
1386           
1387    def GetData(self):
1388        data = []
1389        for row in range(self.GetNumberRows()):
1390            data.append(self.GetRowValues(row))
1391        return data
1392       
1393    def GetNumberCols(self):
1394        try:
1395            return len(self.colLabels)
1396        except TypeError:
1397            return None
1398       
1399    def GetNumberRows(self):
1400        return len(self.data)
1401       
1402    def GetRowLabelValue(self, row):
1403        if self.rowLabels:
1404            return self.rowLabels[row]
1405       
1406    def GetColValues(self, col):
1407        data = []
1408        for row in range(self.GetNumberRows()):
1409            data.append(self.GetValue(row, col))
1410        return data
1411       
1412    def GetRowValues(self, row):
1413        data = []
1414        for col in range(self.GetNumberCols()):
1415            data.append(self.GetValue(row, col))
1416        return data
1417       
1418    def GetTypeName(self, row, col):
1419        try:
1420            return self.dataTypes[col]
1421        except TypeError:
1422            return None
1423
1424    def GetValue(self, row, col):
1425        try:
1426            return self.data[row][col]
1427        except IndexError:
1428            return None
1429           
1430    def InsertRows(self, pos, rows):
1431        for row in range(rows):
1432            self.data.insert(pos,[])
1433            pos += 1
1434       
1435    def IsEmptyCell(self,row,col):
1436        try:
1437            return not self.data[row][col]
1438        except IndexError:
1439            return True
1440       
1441    def OnKeyPress(self, event):
1442        dellist = self.GetSelectedRows()
1443        if event.GetKeyCode() == wx.WXK_DELETE and dellist:
1444            grid = self.GetView()
1445            for i in dellist: grid.DeleteRow(i)
1446               
1447    def SetColLabelValue(self, col, label):
1448        numcols = self.GetNumberCols()
1449        if col > numcols-1:
1450            self.colLabels.append(label)
1451        else:
1452            self.colLabels[col]=label
1453       
1454    def SetData(self,data):
1455        for row in range(len(data)):
1456            self.SetRowValues(row,data[row])
1457               
1458    def SetRowLabelValue(self, row, label):
1459        self.rowLabels[row]=label
1460           
1461    def SetRowValues(self,row,data):
1462        self.data[row] = data
1463           
1464    def SetValue(self, row, col, value):
1465        def innerSetValue(row, col, value):
1466            try:
1467                self.data[row][col] = value
1468            except TypeError:
1469                return
1470            except IndexError:
1471                print row,col,value
1472                # add a new row
1473                if row > self.GetNumberRows():
1474                    self.data.append([''] * self.GetNumberCols())
1475                elif col > self.GetNumberCols():
1476                    for row in range(self.GetNumberRows):
1477                        self.data[row].append('')
1478                print self.data
1479                self.data[row][col] = value
1480        innerSetValue(row, col, value)
1481       
1482################################################################################
1483#### Help
1484################################################################################
1485
1486def ShowHelp(helpType,frame):
1487    '''Called to bring up a web page for documentation.'''
1488    global htmlFirstUse
1489    # look up a definition for help info from dict
1490    helplink = helpLocDict.get(helpType)
1491    if helplink is None:
1492        # no defined link to use, create a default based on key
1493        helplink = 'gsasII.html#'+helpType.replace(' ','_')
1494    helplink = os.path.join(path2GSAS2,'help',helplink)
1495    if helpMode == 'internal':
1496        try:
1497            htmlPanel.LoadFile(helplink)
1498            htmlFrame.Raise()
1499        except:
1500            htmlFrame = wx.Frame(frame, -1, size=(610, 510))
1501            htmlFrame.Show(True)
1502            htmlFrame.SetTitle("HTML Window") # N.B. reset later in LoadFile
1503            htmlPanel = MyHtmlPanel(htmlFrame,-1)
1504            htmlPanel.LoadFile(helplink)
1505    else:
1506        pfx = "file://"
1507        if sys.platform.lower().startswith('win'):
1508            pfx = ''
1509        if htmlFirstUse:
1510            webbrowser.open_new(pfx+helplink)
1511            htmlFirstUse = False
1512        else:
1513            webbrowser.open(pfx+helplink, new=0, autoraise=True)
1514
1515################################################################################
1516#####  Notebook
1517################################################################################           
1518       
1519def UpdateNotebook(G2frame,data):
1520   
1521    def OnNoteBook(event):
1522        data = G2frame.dataDisplay.GetValue()
1523        G2frame.PatternTree.SetItemPyData(GetPatternTreeItemId(G2frame,G2frame.root,'Notebook'),data)
1524                   
1525    if G2frame.dataDisplay:
1526        G2frame.dataDisplay.Destroy()
1527    G2frame.dataFrame.SetLabel('Notebook')
1528    G2frame.dataDisplay = wx.TextCtrl(parent=G2frame.dataFrame,size=G2frame.dataFrame.GetClientSize(),
1529        style=wx.TE_MULTILINE|wx.TE_PROCESS_ENTER | wx.TE_DONTWRAP)
1530    G2frame.dataDisplay.Bind(wx.EVT_TEXT_ENTER,OnNoteBook)
1531    G2frame.dataDisplay.Bind(wx.EVT_KILL_FOCUS,OnNoteBook)
1532    for line in data:
1533        G2frame.dataDisplay.AppendText(line+"\n")
1534    G2frame.dataDisplay.AppendText('Notebook entry @ '+time.ctime()+"\n")
1535    G2frame.dataFrame.setSizePosLeft([400,250])
1536           
1537################################################################################
1538#####  Controls
1539################################################################################           
1540       
1541def UpdateControls(G2frame,data):
1542    #patch
1543    if 'deriv type' not in data:
1544        data = {}
1545        data['deriv type'] = 'analytic Hessian'
1546        data['min dM/M'] = 0.0001
1547        data['shift factor'] = 1.
1548        data['max cyc'] = 3       
1549        data['F**2'] = True
1550        data['minF/sig'] = 0
1551    if 'shift factor' not in data:
1552        data['shift factor'] = 1.
1553    if 'max cyc' not in data:
1554        data['max cyc'] = 3
1555    if 'F**2' not in data:
1556        data['F**2'] = True
1557        data['minF/sig'] = 0
1558    #end patch
1559
1560    def SeqSizer():
1561       
1562        def OnSelectData(event):
1563            choices = ['All',]+GetPatternTreeDataNames(G2frame,['PWDR',])
1564            sel = []
1565            if 'Seq Data' in data:
1566                for item in data['Seq Data']:
1567                    sel.append(choices.index(item))
1568            names = []
1569            dlg = wx.MultiChoiceDialog(G2frame,'Select data:','Sequential refinement',choices)
1570            dlg.SetSelections(sel)
1571            if dlg.ShowModal() == wx.ID_OK:
1572                sel = dlg.GetSelections()
1573                for i in sel: names.append(choices[i])
1574                if 'All' in names:
1575                    names = choices[1:]
1576                data['Seq Data'] = names               
1577            dlg.Destroy()
1578            reverseSel.Enable(True)
1579           
1580        def OnReverse(event):
1581            data['Reverse Seq'] = reverseSel.GetValue()
1582                   
1583        seqSizer = wx.BoxSizer(wx.HORIZONTAL)
1584        seqSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Sequential Refinement Powder Data: '),0,wx.ALIGN_CENTER_VERTICAL)
1585        selSeqData = wx.Button(G2frame.dataDisplay,-1,label=' Select data')
1586        selSeqData.Bind(wx.EVT_BUTTON,OnSelectData)
1587        seqSizer.Add(selSeqData,0,wx.ALIGN_CENTER_VERTICAL)
1588        seqSizer.Add((5,0),0)
1589        reverseSel = wx.CheckBox(G2frame.dataDisplay,-1,label=' Reverse order?')
1590        reverseSel.Bind(wx.EVT_CHECKBOX,OnReverse)
1591        if 'Seq Data' not in data:
1592            reverseSel.Enable(False)
1593        if 'Reverse Seq' in data:
1594            reverseSel.SetValue(data['Reverse Seq'])
1595        seqSizer.Add(reverseSel,0,wx.ALIGN_CENTER_VERTICAL)
1596        return seqSizer
1597       
1598    def LSSizer():       
1599       
1600        def OnDerivType(event):
1601            data['deriv type'] = derivSel.GetValue()
1602            derivSel.SetValue(data['deriv type'])
1603            wx.CallAfter(UpdateControls,G2frame,data)
1604           
1605        def OnConvergence(event):
1606            try:
1607                value = max(1.e-9,min(1.0,float(Cnvrg.GetValue())))
1608            except ValueError:
1609                value = 0.0001
1610            data['min dM/M'] = value
1611            Cnvrg.SetValue('%.2g'%(value))
1612           
1613        def OnMaxCycles(event):
1614            data['max cyc'] = int(maxCyc.GetValue())
1615            maxCyc.SetValue(str(data['max cyc']))
1616                       
1617        def OnFactor(event):
1618            try:
1619                value = min(max(float(Factr.GetValue()),0.00001),100.)
1620            except ValueError:
1621                value = 1.0
1622            data['shift factor'] = value
1623            Factr.SetValue('%.5f'%(value))
1624           
1625        def OnFsqRef(event):
1626            data['F**2'] = fsqRef.GetValue()
1627       
1628        def OnMinSig(event):
1629            try:
1630                value = min(max(float(minSig.GetValue()),0.),5.)
1631            except ValueError:
1632                value = 1.0
1633            data['minF/sig'] = value
1634            minSig.SetValue('%.2f'%(value))
1635
1636        LSSizer = wx.FlexGridSizer(cols=4,vgap=5,hgap=5)
1637        LSSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Refinement derivatives: '),0,wx.ALIGN_CENTER_VERTICAL)
1638        Choice=['analytic Jacobian','numeric','analytic Hessian']
1639        derivSel = wx.ComboBox(parent=G2frame.dataDisplay,value=data['deriv type'],choices=Choice,
1640            style=wx.CB_READONLY|wx.CB_DROPDOWN)
1641        derivSel.SetValue(data['deriv type'])
1642        derivSel.Bind(wx.EVT_COMBOBOX, OnDerivType)
1643           
1644        LSSizer.Add(derivSel,0,wx.ALIGN_CENTER_VERTICAL)
1645        LSSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Min delta-M/M: '),0,wx.ALIGN_CENTER_VERTICAL)
1646        Cnvrg = wx.TextCtrl(G2frame.dataDisplay,-1,value='%.2g'%(data['min dM/M']),style=wx.TE_PROCESS_ENTER)
1647        Cnvrg.Bind(wx.EVT_TEXT_ENTER,OnConvergence)
1648        Cnvrg.Bind(wx.EVT_KILL_FOCUS,OnConvergence)
1649        LSSizer.Add(Cnvrg,0,wx.ALIGN_CENTER_VERTICAL)
1650        if 'Hessian' in data['deriv type']:
1651            LSSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Max cycles: '),0,wx.ALIGN_CENTER_VERTICAL)
1652            Choice = ['0','1','2','3','5','10','15','20']
1653            maxCyc = wx.ComboBox(parent=G2frame.dataDisplay,value=str(data['max cyc']),choices=Choice,
1654                style=wx.CB_READONLY|wx.CB_DROPDOWN)
1655            maxCyc.SetValue(str(data['max cyc']))
1656            maxCyc.Bind(wx.EVT_COMBOBOX, OnMaxCycles)
1657            LSSizer.Add(maxCyc,0,wx.ALIGN_CENTER_VERTICAL)
1658        else:
1659            LSSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Initial shift factor: '),0,wx.ALIGN_CENTER_VERTICAL)
1660            Factr = wx.TextCtrl(G2frame.dataDisplay,-1,value='%.5f'%(data['shift factor']),style=wx.TE_PROCESS_ENTER)
1661            Factr.Bind(wx.EVT_TEXT_ENTER,OnFactor)
1662            Factr.Bind(wx.EVT_KILL_FOCUS,OnFactor)
1663            LSSizer.Add(Factr,0,wx.ALIGN_CENTER_VERTICAL)
1664        if G2frame.Sngl:
1665            LSSizer.Add((1,0),)
1666            LSSizer.Add((1,0),)
1667            fsqRef = wx.CheckBox(G2frame.dataDisplay,-1,label='Refine HKLF as F^2? ')
1668            fsqRef.SetValue(data['F**2'])
1669            fsqRef.Bind(wx.EVT_CHECKBOX,OnFsqRef)
1670            LSSizer.Add(fsqRef,0,wx.ALIGN_CENTER_VERTICAL)
1671            LSSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,label='Min obs/sig (0-5): '),0,wx.ALIGN_CENTER_VERTICAL)
1672            minSig = wx.TextCtrl(G2frame.dataDisplay,-1,value='%.2f'%(data['minF/sig']),style=wx.TE_PROCESS_ENTER)
1673            minSig.Bind(wx.EVT_TEXT_ENTER,OnMinSig)
1674            minSig.Bind(wx.EVT_KILL_FOCUS,OnMinSig)
1675            LSSizer.Add(minSig,0,wx.ALIGN_CENTER_VERTICAL)
1676        return LSSizer
1677       
1678    if G2frame.dataDisplay:
1679        G2frame.dataDisplay.Destroy()
1680    if not G2frame.dataFrame.GetStatusBar():
1681        Status = G2frame.dataFrame.CreateStatusBar()
1682        Status.SetStatusText('')
1683    G2frame.dataFrame.SetLabel('Controls')
1684    G2frame.dataDisplay = wx.Panel(G2frame.dataFrame)
1685    SetDataMenuBar(G2frame,G2frame.dataFrame.ControlsMenu)
1686    mainSizer = wx.BoxSizer(wx.VERTICAL)
1687    mainSizer.Add((5,5),0)
1688    mainSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Refinement Controls:'),0,wx.ALIGN_CENTER_VERTICAL)   
1689    mainSizer.Add(LSSizer())
1690    mainSizer.Add((5,5),0)
1691    mainSizer.Add(SeqSizer())
1692    mainSizer.Add((5,5),0)
1693       
1694    mainSizer.Layout()   
1695    G2frame.dataDisplay.SetSizer(mainSizer)
1696    G2frame.dataDisplay.SetSize(mainSizer.Fit(G2frame.dataFrame))
1697    G2frame.dataFrame.setSizePosLeft(mainSizer.Fit(G2frame.dataFrame))
1698     
1699################################################################################
1700#####  Comments
1701################################################################################           
1702       
1703def UpdateComments(G2frame,data):                   
1704
1705    if G2frame.dataDisplay:
1706        G2frame.dataDisplay.Destroy()
1707    G2frame.dataFrame.SetLabel('Comments')
1708    G2frame.dataDisplay = wx.TextCtrl(parent=G2frame.dataFrame,size=G2frame.dataFrame.GetClientSize(),
1709        style=wx.TE_MULTILINE|wx.TE_READONLY|wx.TE_DONTWRAP)
1710    for line in data:
1711        G2frame.dataDisplay.AppendText(line+'\n')
1712    G2frame.dataFrame.setSizePosLeft([400,250])
1713           
1714################################################################################
1715#####  Sequential Results
1716################################################################################           
1717       
1718def UpdateSeqResults(G2frame,data):
1719    """
1720    input:
1721        data - dictionary
1722            'histNames' - list of histogram names in order as processed by Sequential Refinement
1723            'varyList' - list of variables - identical over all refinements in sequence
1724            'histName' - dictionaries for all data sets processed:
1725                'variables'- result[0] from leastsq call
1726                'varyList' - list of variables; same as above
1727                'sig' - esds for variables
1728                'covMatrix' - covariance matrix from individual refinement
1729                'title' - histogram name; same as dict item name
1730                'newAtomDict' - new atom parameters after shifts applied
1731                'newCellDict' - new cell parameters after shifts to A0-A5 applied'
1732    """
1733    if not data:
1734        print 'No sequential refinement results'
1735        return
1736    histNames = data['histNames']
1737       
1738    def GetSampleParms():
1739        sampleParmDict = {'Temperature':[],'Pressure':[],'Humidity':[],'Voltage':[],'Force':[],}
1740        sampleParm = {}
1741        for name in histNames:
1742            Id = GetPatternTreeItemId(G2frame,G2frame.root,name)
1743            sampleData = G2frame.PatternTree.GetItemPyData(GetPatternTreeItemId(G2frame,Id,'Sample Parameters'))
1744            for item in sampleParmDict:
1745                sampleParmDict[item].append(sampleData[item])
1746        for item in sampleParmDict:
1747            frstValue = sampleParmDict[item][0]
1748            if np.any(np.array(sampleParmDict[item])-frstValue):
1749                sampleParm[item] = sampleParmDict[item]           
1750        return sampleParm
1751           
1752    def GetRwps():
1753        Rwps = []
1754        for name in histNames:
1755            Rwps.append(data[name]['Rvals']['Rwp'])
1756        return Rwps
1757           
1758    def GetSigData(parm):
1759        sigData = []
1760        for name in histNames:
1761            sigList = data[name]['sig']
1762            if colLabels[parm] in atomList:
1763                sigData.append(sigList[colLabels.index(atomList[colLabels[parm]])-1])
1764            elif colLabels[parm] in cellList:
1765                sigData.append(sigList[colLabels.index(cellList[colLabels[parm]])-1])
1766            else:
1767                sigData.append(sigList[parm-1])
1768        return sigData
1769   
1770    def Select(event):
1771        cols = G2frame.dataDisplay.GetSelectedCols()
1772        rows = G2frame.dataDisplay.GetSelectedRows()
1773        if cols:
1774            plotData = []
1775            plotSig = []
1776            plotNames = []
1777            for col in cols:
1778                plotData.append(G2frame.SeqTable.GetColValues(col))
1779                if col:     #not Rwp
1780                    plotSig.append(GetSigData(col))
1781                else:
1782                    plotSig.append(0.0)
1783                plotNames.append(G2frame.SeqTable.GetColLabelValue(col))
1784            plotData = np.array(plotData)
1785            G2plt.PlotSeq(G2frame,plotData,plotSig,plotNames,sampleParms)
1786        elif rows:
1787            name = histNames[rows[0]]       #only does 1st one selected
1788            G2plt.PlotCovariance(G2frame,data[name])
1789           
1790    def OnSaveSelSeq(event):       
1791        cols = G2frame.dataDisplay.GetSelectedCols()
1792        if cols:
1793            numRows = G2frame.SeqTable.GetNumberRows()
1794            dataNames = []
1795            saveNames = [G2frame.SeqTable.GetRowLabelValue(r) for r in range(numRows)]
1796            saveData = []
1797            for col in cols:
1798                dataNames.append(G2frame.SeqTable.GetColLabelValue(col))
1799                if col:     #not Rwp
1800                    saveData.append(zip(G2frame.SeqTable.GetColValues(col),GetSigData(col)))
1801                else:
1802                    saveData.append(zip(G2frame.SeqTable.GetColValues(col),0.0))
1803            lenName = len(saveNames[0])
1804            saveData = np.swapaxes(np.array(saveData),0,1)
1805            dlg = wx.FileDialog(G2frame, 'Choose text output file for your selection', '.', '', 
1806                'Text output file (*.txt)|*.txt',wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT|wx.CHANGE_DIR)
1807            try:
1808                if dlg.ShowModal() == wx.ID_OK:
1809                    SeqTextFile = dlg.GetPath()
1810                    SeqTextFile = G2IO.FileDlgFixExt(dlg,SeqTextFile)
1811                    SeqFile = open(SeqTextFile,'w')
1812                    line = %s  '%('name'.center(lenName))
1813                    for item in dataNames:
1814                        line += ' %12s %12s '%(item.center(12),'esd'.center(12))
1815                    line += '\n'
1816                    SeqFile.write(line)
1817                    for i,item in enumerate(saveData):
1818                        line = " '%s' "%(saveNames[i])
1819                        for val,esd in item:
1820                            line += ' %12.6f %12.6f '%(val,esd)
1821                        line += '\n'
1822                        SeqFile.write(line)
1823                    SeqFile.close()
1824            finally:
1825                dlg.Destroy()
1826           
1827               
1828    if G2frame.dataDisplay:
1829        G2frame.dataDisplay.Destroy()
1830    atomList = {}
1831    newAtomDict = data[histNames[0]]['newAtomDict']
1832    for item in newAtomDict:
1833        if item in data['varyList']:
1834            atomList[newAtomDict[item][0]] = item
1835    cellList = {}
1836    newCellDict = data[histNames[0]]['newCellDict']
1837    for item in newCellDict:
1838        if item in data['varyList']:
1839            cellList[newCellDict[item][0]] = item
1840    sampleParms = GetSampleParms()
1841    Rwps = GetRwps()
1842    SetDataMenuBar(G2frame,G2frame.dataFrame.SequentialMenu)
1843    G2frame.dataFrame.SetLabel('Sequental refinement results')
1844    G2frame.dataFrame.CreateStatusBar()
1845    G2frame.dataFrame.Bind(wx.EVT_MENU, OnSaveSelSeq, id=wxID_SAVESEQSEL)
1846    colLabels = ['Rwp',]+data['varyList']+atomList.keys()+cellList.keys()
1847    Types = (len(data['varyList']+atomList.keys()+cellList.keys())+1)*[wg.GRID_VALUE_FLOAT,]
1848    seqList = [[Rwps[i],]+list(data[name]['variables']) for i,name in enumerate(histNames)]
1849    for i,item in enumerate(seqList):
1850        newAtomDict = data[histNames[i]]['newAtomDict']
1851        newCellDict = data[histNames[i]]['newCellDict']
1852        item += [newAtomDict[atomList[parm]][1] for parm in atomList.keys()]
1853        item += [newCellDict[cellList[parm]][1] for parm in cellList.keys()]
1854    G2frame.SeqTable = Table(seqList,colLabels=colLabels,rowLabels=histNames,types=Types)
1855    G2frame.dataDisplay = GSGrid(parent=G2frame.dataFrame)
1856    G2frame.dataDisplay.SetTable(G2frame.SeqTable, True)
1857    G2frame.dataDisplay.EnableEditing(False)
1858    G2frame.dataDisplay.Bind(wg.EVT_GRID_LABEL_LEFT_DCLICK, Select)
1859    G2frame.dataDisplay.SetRowLabelSize(8*len(histNames[0]))       #pretty arbitrary 8
1860    G2frame.dataDisplay.SetMargins(0,0)
1861    G2frame.dataDisplay.AutoSizeColumns(True)
1862    G2frame.dataFrame.setSizePosLeft([700,350])
1863       
1864################################################################################
1865#####  Main PWDR panel
1866################################################################################           
1867       
1868def UpdatePWHKPlot(G2frame,kind,item):
1869
1870    def OnErrorAnalysis(event):
1871        G2plt.PlotDeltSig(G2frame,kind)
1872       
1873    def OnWtFactor(event):
1874        try:
1875            val = float(wtval.GetValue())
1876        except ValueError:
1877            val = data[0]['wtFactor']
1878        data[0]['wtFactor'] = val
1879        wtval.SetValue('%.3f'%(val))
1880           
1881    data = G2frame.PatternTree.GetItemPyData(item)
1882    if 'wtFactor' not in data[0]:
1883        data[0] = {'wtFactor':1.0}
1884    if G2frame.dataDisplay:
1885        G2frame.dataDisplay.Destroy()
1886    SetDataMenuBar(G2frame,G2frame.dataFrame.ErrorMenu)
1887    G2frame.dataFrame.Bind(wx.EVT_MENU,OnErrorAnalysis, id=wxID_PWDANALYSIS)
1888    G2frame.dataDisplay = wx.Panel(G2frame.dataFrame)
1889   
1890    mainSizer = wx.BoxSizer(wx.VERTICAL)
1891    mainSizer.Add((5,5),)
1892    wtSizer = wx.BoxSizer(wx.HORIZONTAL)
1893    wtSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' Weight factor: '),0,wx.ALIGN_CENTER_VERTICAL)
1894    wtval = wx.TextCtrl(G2frame.dataDisplay,-1,'%.3f'%(data[0]['wtFactor']),style=wx.TE_PROCESS_ENTER)
1895    wtval.Bind(wx.EVT_TEXT_ENTER,OnWtFactor)
1896    wtval.Bind(wx.EVT_KILL_FOCUS,OnWtFactor)
1897    wtSizer.Add(wtval,0,wx.ALIGN_CENTER_VERTICAL)
1898    mainSizer.Add(wtSizer)
1899    mainSizer.Layout()   
1900    G2frame.dataDisplay.SetSizer(mainSizer)
1901    G2frame.dataFrame.setSizePosLeft(mainSizer.Fit(G2frame.dataFrame))
1902    G2frame.PatternTree.SetItemPyData(item,data)
1903    if kind == 'PWDR':
1904        G2plt.PlotPatterns(G2frame,newPlot=True)
1905    elif kind == 'HKLF':
1906        G2plt.PlotSngl(G2frame,newPlot=True)
1907                 
1908################################################################################
1909#####  HKLF controls
1910################################################################################           
1911       
1912def UpdateHKLControls(G2frame,data):
1913   
1914    def OnScaleSlider(event):
1915        scale = int(scaleSel.GetValue())/1000.
1916        scaleSel.SetValue(int(scale*1000.))
1917        data['Scale'] = scale*1.
1918        G2plt.PlotSngl(G2frame)
1919       
1920    def OnLayerSlider(event):
1921        layer = layerSel.GetValue()
1922        data['Layer'] = layer
1923        G2plt.PlotSngl(G2frame)
1924       
1925    def OnSelZone(event):
1926        data['Zone'] = zoneSel.GetValue()
1927        izone = zones.index(data['Zone'])
1928        layerSel.SetRange(maxValue=HKLmax[izone],minValue=HKLmin[izone])
1929        G2plt.PlotSngl(G2frame,newPlot=True)
1930       
1931    def OnSelType(event):
1932        data['Type'] = typeSel.GetValue()
1933        G2plt.PlotSngl(G2frame)
1934       
1935    def SetStatusLine():
1936        Status.SetStatusText("")
1937                                     
1938    if G2frame.dataDisplay:
1939        G2frame.dataDisplay.Destroy()
1940    if not G2frame.dataFrame.GetStatusBar():
1941        Status = G2frame.dataFrame.CreateStatusBar()
1942    SetStatusLine()
1943    zones = ['100','010','001']
1944    HKLmax = data['HKLmax']
1945    HKLmin = data['HKLmin']
1946    typeChoices = ['Fosq','Fo','|DFsq|/sig','|DFsq|>sig','|DFsq|>3sig']
1947    G2frame.dataDisplay = wx.Panel(G2frame.dataFrame)
1948    SetDataMenuBar(G2frame)
1949    G2frame.dataFrame.SetTitle('HKL Plot Controls')
1950    mainSizer = wx.BoxSizer(wx.VERTICAL)
1951    mainSizer.Add((5,10),0)
1952   
1953    scaleSizer = wx.BoxSizer(wx.HORIZONTAL)
1954    scaleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Scale'),0,
1955        wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
1956    scaleSel = wx.Slider(parent=G2frame.dataDisplay,maxValue=1000,minValue=1,
1957        style=wx.SL_HORIZONTAL,value=int(data['Scale']*10))
1958    scaleSizer.Add(scaleSel,1,wx.EXPAND|wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
1959    scaleSel.SetLineSize(10)
1960    scaleSel.SetPageSize(10)
1961    scaleSel.Bind(wx.EVT_SLIDER, OnScaleSlider)
1962    mainSizer.Add(scaleSizer,0,wx.EXPAND|wx.RIGHT)
1963    mainSizer.Add((0,10),0)   
1964   
1965    zoneSizer = wx.BoxSizer(wx.HORIZONTAL)
1966    zoneSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Zone  '),0,
1967        wx.ALIGN_CENTER_VERTICAL)
1968    zoneSel = wx.ComboBox(parent=G2frame.dataDisplay,value=data['Zone'],choices=['100','010','001'],
1969        style=wx.CB_READONLY|wx.CB_DROPDOWN)
1970    zoneSel.Bind(wx.EVT_COMBOBOX, OnSelZone)
1971    zoneSizer.Add(zoneSel,0,wx.ALIGN_CENTER_VERTICAL)
1972    zoneSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Plot type  '),0,
1973        wx.ALIGN_CENTER_VERTICAL)       
1974    typeSel = wx.ComboBox(parent=G2frame.dataDisplay,value=data['Type'],choices=typeChoices,
1975        style=wx.CB_READONLY|wx.CB_DROPDOWN)
1976    typeSel.Bind(wx.EVT_COMBOBOX, OnSelType)
1977    zoneSizer.Add(typeSel,0,wx.ALIGN_CENTER_VERTICAL)
1978    zoneSizer.Add((10,0),0)   
1979    mainSizer.Add(zoneSizer,0,wx.EXPAND|wx.RIGHT)
1980    mainSizer.Add((0,10),0)   
1981       
1982    izone = zones.index(data['Zone'])
1983    layerSizer = wx.BoxSizer(wx.HORIZONTAL)
1984    layerSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Layer'),0,
1985        wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
1986    layerSel = wx.Slider(parent=G2frame.dataDisplay,maxValue=HKLmax[izone],minValue=HKLmin[izone],
1987        style=wx.SL_HORIZONTAL|wx.SL_AUTOTICKS|wx.SL_LABELS,value=0)
1988    layerSel.SetLineSize(1)
1989    layerSel.SetPageSize(1)
1990    layerSel.Bind(wx.EVT_SLIDER, OnLayerSlider)   
1991    layerSizer.Add(layerSel,1,wx.EXPAND|wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
1992    layerSizer.Add((10,0),0)   
1993    mainSizer.Add(layerSizer,1,wx.EXPAND|wx.RIGHT)
1994
1995       
1996    mainSizer.Layout()   
1997    G2frame.dataDisplay.SetSizer(mainSizer)
1998    G2frame.dataDisplay.SetSize(mainSizer.Fit(G2frame.dataFrame))
1999    G2frame.dataFrame.setSizePosLeft(mainSizer.Fit(G2frame.dataFrame))
2000
2001################################################################################
2002#####  Pattern tree routines
2003################################################################################           
2004       
2005def GetPatternTreeDataNames(G2frame,dataTypes):
2006    names = []
2007    item, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root)       
2008    while item:
2009        name = G2frame.PatternTree.GetItemText(item)
2010        if name[:4] in dataTypes:
2011            names.append(name)
2012        item, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie)
2013    return names
2014                         
2015def GetPatternTreeItemId(G2frame, parentId, itemText):
2016    item, cookie = G2frame.PatternTree.GetFirstChild(parentId)
2017    while item:
2018        if G2frame.PatternTree.GetItemText(item) == itemText:
2019            return item
2020        item, cookie = G2frame.PatternTree.GetNextChild(parentId, cookie)
2021    return 0               
2022
2023def MovePatternTreeToGrid(G2frame,item):
2024   
2025#    print G2frame.PatternTree.GetItemText(item)
2026   
2027    oldPage = 0
2028    if G2frame.dataFrame:
2029        SetDataMenuBar(G2frame)
2030        if G2frame.dataFrame.GetLabel() == 'Comments':
2031            try:
2032                data = [G2frame.dataDisplay.GetValue()]
2033                G2frame.dataDisplay.Clear() 
2034                Id = GetPatternTreeItemId(G2frame,G2frame.root, 'Comments')
2035                if Id: G2frame.PatternTree.SetItemPyData(Id,data)
2036            except:     #clumsy but avoids dead window problem when opening another project
2037                pass
2038        elif G2frame.dataFrame.GetLabel() == 'Notebook':
2039            try:
2040                data = [G2frame.dataDisplay.GetValue()]
2041                G2frame.dataDisplay.Clear() 
2042                Id = GetPatternTreeItemId(G2frame,G2frame.root, 'Notebook')
2043                if Id: G2frame.PatternTree.SetItemPyData(Id,data)
2044            except:     #clumsy but avoids dead window problem when opening another project
2045                pass
2046        elif 'Phase Data for' in G2frame.dataFrame.GetLabel():
2047            if G2frame.dataDisplay: 
2048                oldPage = G2frame.dataDisplay.GetSelection()
2049        G2frame.dataFrame.Clear()
2050        G2frame.dataFrame.SetLabel('')
2051    else:
2052        #create the frame for the data item window
2053        G2frame.dataFrame = DataFrame(parent=G2frame.mainPanel,frame=G2frame)
2054
2055    G2frame.dataFrame.Raise()           
2056    G2frame.PickId = 0
2057    parentID = G2frame.root
2058    for i in G2frame.ExportPattern: i.Enable(False)
2059    defWid = [250,150]
2060    if item != G2frame.root:
2061        parentID = G2frame.PatternTree.GetItemParent(item)
2062    if G2frame.PatternTree.GetItemParent(item) == G2frame.root:
2063        G2frame.PatternId = item
2064        G2frame.PickId = item
2065        if G2frame.PatternTree.GetItemText(item) == 'Notebook':
2066            SetDataMenuBar(G2frame,G2frame.dataFrame.DataNotebookMenu)
2067            G2frame.PatternId = 0
2068            for i in G2frame.ExportPattern: i.Enable(False)
2069            data = G2frame.PatternTree.GetItemPyData(item)
2070            UpdateNotebook(G2frame,data)
2071        elif G2frame.PatternTree.GetItemText(item) == 'Controls':
2072            G2frame.PatternId = 0
2073            for i in G2frame.ExportPattern: i.Enable(False)
2074            data = G2frame.PatternTree.GetItemPyData(item)
2075            if not data:           #fill in defaults
2076                data = {
2077                    #least squares controls
2078                    'deriv type':'analytic Hessian','min dM/M':0.0001,'shift factor':1.0,'max cyc':3}
2079                G2frame.PatternTree.SetItemPyData(item,data)                             
2080            for i in G2frame.Refine: i.Enable(True)
2081            for i in G2frame.SeqRefine: i.Enable(True)
2082            UpdateControls(G2frame,data)
2083        elif G2frame.PatternTree.GetItemText(item) == 'Sequental results':
2084            data = G2frame.PatternTree.GetItemPyData(item)
2085            UpdateSeqResults(G2frame,data)           
2086        elif G2frame.PatternTree.GetItemText(item) == 'Covariance':
2087            data = G2frame.PatternTree.GetItemPyData(item)
2088            G2frame.dataFrame.setSizePosLeft(defWid)
2089            text = ''
2090            if 'Rvals' in data:
2091                Nvars = len(data['varyList'])
2092                Rvals = data['Rvals']
2093                text = '\nFinal residuals: \nRw = %.3f%% \nchi**2 = %.1f \nGOF = %.2f'%(Rvals['Rwp'],Rvals['chisq'],Rvals['GOF'])
2094                text += '\nNobs = %d \nNvals = %d'%(Rvals['Nobs'],Nvars)
2095                if 'lamMax' in Rvals:
2096                    text += '\nlog10 MaxLambda = %.1f'%(np.log10(Rvals['lamMax']))
2097            wx.TextCtrl(parent=G2frame.dataFrame,size=G2frame.dataFrame.GetClientSize(),
2098                value='See plot window for covariance display'+text,style=wx.TE_MULTILINE)
2099            G2plt.PlotCovariance(G2frame,data)
2100        elif G2frame.PatternTree.GetItemText(item) == 'Constraints':
2101            data = G2frame.PatternTree.GetItemPyData(item)
2102            G2cnstG.UpdateConstraints(G2frame,data)
2103        elif G2frame.PatternTree.GetItemText(item) == 'Rigid bodies':
2104            data = G2frame.PatternTree.GetItemPyData(item)
2105            G2cnstG.UpdateRigidBodies(G2frame,data)
2106        elif G2frame.PatternTree.GetItemText(item) == 'Restraints':
2107            data = G2frame.PatternTree.GetItemPyData(item)
2108            Phases = G2frame.GetPhaseData()
2109            phase = ''
2110            phaseName = ''
2111            if Phases:
2112                phaseName = Phases.keys()[0]
2113            G2frame.dataFrame.setSizePosLeft(defWid)
2114            G2restG.UpdateRestraints(G2frame,data,Phases,phaseName)
2115        elif 'IMG' in G2frame.PatternTree.GetItemText(item):
2116            G2frame.Image = item
2117            G2plt.PlotImage(G2frame,newPlot=True)
2118        elif 'PKS' in G2frame.PatternTree.GetItemText(item):
2119            G2plt.PlotPowderLines(G2frame)
2120        elif 'PWDR' in G2frame.PatternTree.GetItemText(item):
2121            for i in G2frame.ExportPattern: i.Enable(True)
2122            UpdatePWHKPlot(G2frame,'PWDR',item)
2123        elif 'HKLF' in G2frame.PatternTree.GetItemText(item):
2124            G2frame.Sngl = item
2125            UpdatePWHKPlot(G2frame,'HKLF',item)
2126        elif 'PDF' in G2frame.PatternTree.GetItemText(item):
2127            G2frame.PatternId = item
2128            for i in G2frame.ExportPDF: i.Enable(True)
2129            G2plt.PlotISFG(G2frame,type='S(Q)')
2130        elif G2frame.PatternTree.GetItemText(item) == 'Phases':
2131            G2frame.dataFrame.setSizePosLeft(defWid)
2132            wx.TextCtrl(parent=G2frame.dataFrame,size=G2frame.dataFrame.GetClientSize(),
2133                value='Select one phase to see its parameters')           
2134    elif 'I(Q)' in G2frame.PatternTree.GetItemText(item):
2135        G2frame.PickId = item
2136        G2frame.PatternId = G2frame.PatternTree.GetItemParent(item)
2137        G2plt.PlotISFG(G2frame,type='I(Q)',newPlot=True)
2138    elif 'S(Q)' in G2frame.PatternTree.GetItemText(item):
2139        G2frame.PickId = item
2140        G2frame.PatternId = G2frame.PatternTree.GetItemParent(item)
2141        G2plt.PlotISFG(G2frame,type='S(Q)',newPlot=True)
2142    elif 'F(Q)' in G2frame.PatternTree.GetItemText(item):
2143        G2frame.PickId = item
2144        G2frame.PatternId = G2frame.PatternTree.GetItemParent(item)
2145        G2plt.PlotISFG(G2frame,type='F(Q)',newPlot=True)
2146    elif 'G(R)' in G2frame.PatternTree.GetItemText(item):
2147        G2frame.PickId = item
2148        G2frame.PatternId = G2frame.PatternTree.GetItemParent(item)
2149        G2plt.PlotISFG(G2frame,type='G(R)',newPlot=True)           
2150    elif G2frame.PatternTree.GetItemText(parentID) == 'Phases':
2151        G2frame.PickId = item
2152        data = G2frame.PatternTree.GetItemPyData(item)
2153        G2phG.UpdatePhaseData(G2frame,item,data,oldPage)
2154    elif G2frame.PatternTree.GetItemText(item) == 'Comments':
2155        SetDataMenuBar(G2frame,G2frame.dataFrame.DataCommentsMenu)
2156        G2frame.PatternId = G2frame.PatternTree.GetItemParent(item)
2157        G2frame.PickId = item
2158        data = G2frame.PatternTree.GetItemPyData(item)
2159        UpdateComments(G2frame,data)
2160    elif G2frame.PatternTree.GetItemText(item) == 'Image Controls':
2161        G2frame.dataFrame.SetTitle('Image Controls')
2162        G2frame.PickId = item
2163        G2frame.Image = G2frame.PatternTree.GetItemParent(item)
2164        masks = G2frame.PatternTree.GetItemPyData(
2165            GetPatternTreeItemId(G2frame,G2frame.Image, 'Masks'))
2166        data = G2frame.PatternTree.GetItemPyData(item)
2167        G2imG.UpdateImageControls(G2frame,data,masks)
2168        G2plt.PlotImage(G2frame)
2169    elif G2frame.PatternTree.GetItemText(item) == 'Masks':
2170        G2frame.dataFrame.SetTitle('Masks')
2171        G2frame.PickId = item
2172        G2frame.Image = G2frame.PatternTree.GetItemParent(item)
2173        data = G2frame.PatternTree.GetItemPyData(item)
2174        G2imG.UpdateMasks(G2frame,data)
2175        G2plt.PlotImage(G2frame)
2176    elif G2frame.PatternTree.GetItemText(item) == 'Stress/Strain':
2177        G2frame.dataFrame.SetTitle('Stress/Strain')
2178        G2frame.PickId = item
2179        G2frame.Image = G2frame.PatternTree.GetItemParent(item)
2180        data = G2frame.PatternTree.GetItemPyData(item)
2181        G2imG.UpdateStressStrain(G2frame,data)
2182        G2plt.PlotImage(G2frame)
2183    elif G2frame.PatternTree.GetItemText(item) == 'HKL Plot Controls':
2184        G2frame.PickId = item
2185        G2frame.Sngl = G2frame.PatternTree.GetItemParent(item)
2186        data = G2frame.PatternTree.GetItemPyData(item)
2187        UpdateHKLControls(G2frame,data)
2188        G2plt.PlotSngl(G2frame)
2189    elif G2frame.PatternTree.GetItemText(item) == 'PDF Controls':
2190        G2frame.PatternId = G2frame.PatternTree.GetItemParent(item)
2191        for i in G2frame.ExportPDF: i.Enable(True)
2192        G2frame.PickId = item
2193        data = G2frame.PatternTree.GetItemPyData(item)
2194        G2pdG.UpdatePDFGrid(G2frame,data)
2195        G2plt.PlotISFG(G2frame,type='I(Q)')
2196        G2plt.PlotISFG(G2frame,type='S(Q)')
2197        G2plt.PlotISFG(G2frame,type='F(Q)')
2198        G2plt.PlotISFG(G2frame,type='G(R)')
2199    elif G2frame.PatternTree.GetItemText(item) == 'Peak List':
2200        G2frame.PatternId = G2frame.PatternTree.GetItemParent(item)
2201        for i in G2frame.ExportPeakList: i.Enable(True)
2202        G2frame.PickId = item
2203        data = G2frame.PatternTree.GetItemPyData(item)
2204        G2pdG.UpdatePeakGrid(G2frame,data)
2205        G2plt.PlotPatterns(G2frame)
2206    elif G2frame.PatternTree.GetItemText(item) == 'Background':
2207        G2frame.PatternId = G2frame.PatternTree.GetItemParent(item)
2208        G2frame.PickId = item
2209        data = G2frame.PatternTree.GetItemPyData(item)
2210        G2pdG.UpdateBackground(G2frame,data)
2211        G2plt.PlotPatterns(G2frame)
2212    elif G2frame.PatternTree.GetItemText(item) == 'Limits':
2213        G2frame.PatternId = G2frame.PatternTree.GetItemParent(item)
2214        G2frame.PickId = item
2215        data = G2frame.PatternTree.GetItemPyData(item)
2216        G2pdG.UpdateLimitsGrid(G2frame,data)
2217        G2plt.PlotPatterns(G2frame)
2218    elif G2frame.PatternTree.GetItemText(item) == 'Instrument Parameters':
2219        G2frame.PatternId = G2frame.PatternTree.GetItemParent(item)
2220        G2frame.PickId = item
2221        data = G2frame.PatternTree.GetItemPyData(item)[0]
2222        G2pdG.UpdateInstrumentGrid(G2frame,data)
2223        G2plt.PlotPeakWidths(G2frame)
2224    elif G2frame.PatternTree.GetItemText(item) == 'Sample Parameters':
2225        G2frame.PatternId = G2frame.PatternTree.GetItemParent(item)
2226        G2frame.PickId = item
2227        data = G2frame.PatternTree.GetItemPyData(item)
2228
2229        if 'Temperature' not in data:           #temp fix for old gpx files
2230            data = {'Scale':[1.0,True],'Type':'Debye-Scherrer','Absorption':[0.0,False],'DisplaceX':[0.0,False],
2231                'DisplaceY':[0.0,False],'Diffuse':[],'Temperature':300.,'Pressure':1.0,'Humidity':0.0,'Voltage':0.0,
2232                'Force':0.0,'Gonio. radius':200.0}
2233            G2frame.PatternTree.SetItemPyData(item,data)
2234   
2235        G2pdG.UpdateSampleGrid(G2frame,data)
2236        G2plt.PlotPatterns(G2frame)
2237    elif G2frame.PatternTree.GetItemText(item) == 'Index Peak List':
2238        G2frame.PatternId = G2frame.PatternTree.GetItemParent(item)
2239        for i in G2frame.ExportPeakList: i.Enable(True)
2240        G2frame.PickId = item
2241        data = G2frame.PatternTree.GetItemPyData(item)
2242        G2pdG.UpdateIndexPeaksGrid(G2frame,data)
2243        if 'PKS' in G2frame.PatternTree.GetItemText(G2frame.PatternId):
2244            G2plt.PlotPowderLines(G2frame)
2245        else:
2246            G2plt.PlotPatterns(G2frame)
2247    elif G2frame.PatternTree.GetItemText(item) == 'Unit Cells List':
2248        G2frame.PatternId = G2frame.PatternTree.GetItemParent(item)
2249        G2frame.PickId = item
2250        data = G2frame.PatternTree.GetItemPyData(item)
2251        if not data:
2252            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
2253            data.append([0,0,0,0,0,0,0,0,0,0,0,0,0,0])      #Bravais lattice flags
2254            data.append([])                                 #empty cell list
2255            data.append([])                                 #empty dmin
2256            G2frame.PatternTree.SetItemPyData(item,data)                             
2257        G2pdG.UpdateUnitCellsGrid(G2frame,data)
2258        if 'PKS' in G2frame.PatternTree.GetItemText(G2frame.PatternId):
2259            G2plt.PlotPowderLines(G2frame)
2260        else:
2261            G2plt.PlotPatterns(G2frame)
2262    elif G2frame.PatternTree.GetItemText(item) == 'Reflection Lists':   #powder reflections
2263        G2frame.PatternId = G2frame.PatternTree.GetItemParent(item)
2264        G2frame.PickId = item
2265        data = G2frame.PatternTree.GetItemPyData(item)
2266        G2frame.RefList = ''
2267        if len(data):
2268            G2frame.RefList = data.keys()[0]
2269        G2pdG.UpdateReflectionGrid(G2frame,data)
2270        G2plt.PlotPatterns(G2frame)
2271    elif G2frame.PatternTree.GetItemText(item) == 'Reflection List':    #HKLF reflections
2272        G2frame.PatternId = G2frame.PatternTree.GetItemParent(item)
2273        name = G2frame.PatternTree.GetItemText(G2frame.PatternId)
2274        data = G2frame.PatternTree.GetItemPyData(G2frame.PatternId)
2275        G2pdG.UpdateReflectionGrid(G2frame,data,HKLF=True,Name=name)
2276
2277def SetDataMenuBar(G2frame,menu=None):
2278        '''Set the menu for the data frame. On the Mac put this
2279        menu for the data tree window instead.
2280
2281        Note that data frame items do not have menus, for these (menu=None)
2282        display a blank menu or on the Mac display the standard menu for
2283        the data tree window.
2284        '''
2285        if sys.platform == "darwin":
2286            if menu is None:
2287                G2frame.SetMenuBar(G2frame.GSASIIMenu)
2288            else:
2289                G2frame.SetMenuBar(menu)
2290        else:
2291            if menu is None:
2292                G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.BlankMenu)
2293            else:
2294                G2frame.dataFrame.SetMenuBar(menu)
Note: See TracBrowser for help on using the repository browser.