source: trunk/GSASIIgrid.py @ 570

Last change on this file since 570 was 570, checked in by toby, 10 years ago

Add checks on constraints: if problems display error window when displayed, added/edited & on Refine; handle GPX w/o doPawley flag

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