source: trunk/GSASIIgrid.py @ 527

Last change on this file since 527 was 527, checked in by vondreele, 11 years ago

more on map peak fitting
add a global for htmlFirstUse
fix periodic table display in unix/linux
fix setting of atom type in linux

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