source: trunk/GSASIIgrid.py @ 612

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

complete combined x/n exercise & fix bugs uncovered in process
made version 0.2.0
moved tutorials in help menu to be 2nd
fixed problem with drawing after f-map generated
fixed some plot errors
reverse sign on macrostrain

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