source: trunk/GSASIIgrid.py @ 583

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

add Rwp to sequential results table & plot
fix bug in backflagcopy

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