source: trunk/GSASIIgrid.py @ 483

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

changes to eliminate wx objects (Colour & Point) from being saved in the gpx file
finish saving of selected sequential refinement results

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