source: trunk/GSASIIgrid.py @ 600

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