source: trunk/GSASIIgrid.py @ 453

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

refactor GSASIIgrid
new Hessian based least squares
new GSASIImath.py
work on focus issues

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