source: trunk/GSASIIgrid.py @ 697

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

add ranId to PWDR histograms & each PhaseSelector?
implement 'Use' for every histogram & restraint
remove OnPwdrRead? dead code from GSASII.py
implement stress/strain GUI stuff
implement a clear map menu item
remove getBackupName2 dead code from GSASIIstruct.py

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