source: trunk/GSASIIgrid.py @ 607

Last change on this file since 607 was 607, checked in by toby, 11 years ago

revise help to include tutorials on tree only; add kw args to all readers; cache cif for multiple passes; start on powder imports

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