source: trunk/GSASIIgrid.py @ 460

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

add more text to help/gsasII.html
finish best plane calcs
allow multiple atom selection from plot
begin torsion calc

  • Property svn:keywords set to Date Author Revision URL Id
File size: 75.3 KB
Line 
1#GSASII - data display routines
2########### SVN repository information ###################
3# $Date: 2012-01-31 21:40:48 +0000 (Tue, 31 Jan 2012) $
4# $Author: vondreele $
5# $Revision: 460 $
6# $URL: trunk/GSASIIgrid.py $
7# $Id: GSASIIgrid.py 460 2012-01-31 21:40:48Z 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, wxID_DRAWDISAGL, wxID_DRAWTORSION, wxID_DRAWPLANE,
49] = [wx.NewId() for _init_coll_DrawAtom_Items in range(13)]
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.DrawAtomCompute = wx.Menu(title='')
486        self.DrawAtomsMenu.Append(menu=self.DrawAtomEdit, title='Edit')
487        self.DrawAtomsMenu.Append(menu=self.DrawAtomCompute,title='Compute')
488        self.DrawAtomsMenu.Append(menu=MyHelp(self,helpType='Draw Atoms'),title='&Help')
489        self.DrawAtomEdit.Append(id=wxID_DRAWATOMSTYLE, kind=wx.ITEM_NORMAL,text='Atom style',
490            help='Select atoms first')
491        self.DrawAtomEdit.Append(id=wxID_DRAWATOMLABEL, kind=wx.ITEM_NORMAL,text='Atom label',
492            help='Select atoms first')
493        self.DrawAtomEdit.Append(id=wxID_DRAWATOMCOLOR, kind=wx.ITEM_NORMAL,text='Atom color',
494            help='Select atoms first')
495        self.DrawAtomEdit.Append(id=wxID_DRAWATOMRESETCOLOR, kind=wx.ITEM_NORMAL,text='Reset atom colors',
496            help='Resets all atom colors to defaults')
497        self.DrawAtomEdit.Append(id=wxID_DRAWVIEWPOINT, kind=wx.ITEM_NORMAL,text='View point',
498            help='View point is 1st atom selected')
499        self.DrawAtomEdit.Append(id=wxID_DRAWADDEQUIV, kind=wx.ITEM_NORMAL,text='Add atoms',
500            help='Add symmetry & cell equivalents to drawing set from selected atoms')
501        self.DrawAtomEdit.Append(id=wxID_DRAWTRANSFORM, kind=wx.ITEM_NORMAL,text='Transform atoms',
502            help='Transform selected atoms by symmetry & cell translations')
503        self.DrawAtomEdit.Append(id=wxID_DRAWFILLCOORD, kind=wx.ITEM_NORMAL,text='Fill CN-sphere',
504            help='Fill coordination sphere for selected atoms')           
505        self.DrawAtomEdit.Append(id=wxID_DRAWFILLCELL, kind=wx.ITEM_NORMAL,text='Fill unit cell',
506            help='Fill unit cell with selected atoms')
507        self.DrawAtomEdit.Append(id=wxID_DRAWDELETE, kind=wx.ITEM_NORMAL,text='Delete atoms',
508            help='Delete atoms from drawing set')
509        self.DrawAtomCompute.Append(id=wxID_DRAWDISAGL, kind=wx.ITEM_NORMAL,text='Distances & Angles',
510            help='Compute distances & angles for selected atoms')   
511        self.DrawAtomCompute.Append(id=wxID_DRAWTORSION, kind=wx.ITEM_NORMAL,text='Torsion angle',
512            help='Compute torsion angle for 4 selected atoms')   
513        self.DrawAtomCompute.Append(id=wxID_DRAWPLANE, kind=wx.ITEM_NORMAL,text='Best plane',
514            help='Compute best plane for 3+ selected atoms')   
515           
516# end of GSAS-II menu definitions
517       
518    def _init_ctrls(self, parent,name=None,size=None,pos=None):
519        wx.Frame.__init__(self,parent=parent,style=wx.DEFAULT_FRAME_STYLE ^ wx.CLOSE_BOX,
520            size=size,pos=pos,title='GSAS-II data display')
521        self._init_menus()
522        if name:
523            self.SetLabel(name)
524        self.Show()
525       
526    def __init__(self,parent,data=None,name=None, size=None,pos=None):
527        self._init_ctrls(parent,name,size,pos)
528        self.data = data
529        clientSize = wx.ClientDisplayRect()
530        Size = self.GetSize()
531        xPos = clientSize[2]-Size[0]
532        self.SetPosition(wx.Point(xPos,clientSize[1]+250))
533        self.dirname = ''
534        self.AtomGrid = []
535        self.selectedRow = 0
536       
537    def setSizePosLeft(self,Width):
538        clientSize = wx.ClientDisplayRect()
539        Width[1] = min(Width[1],clientSize[2]-300)
540        Width[0] = max(Width[0],300)
541        self.SetSize(Width)
542        self.SetPosition(wx.Point(clientSize[2]-Width[0],clientSize[1]+250))
543       
544    def Clear(self):
545        self.ClearBackground()
546        self.DestroyChildren()
547                   
548class GSNoteBook(wx.Notebook):
549    def __init__(self, parent, name='',size = None):
550        wx.Notebook.__init__(self, parent, -1, name=name, style= wx.BK_TOP)
551        if size: self.SetSize(size)
552                                                     
553    def Clear(self):       
554        GSNoteBook.DeleteAllPages(self)
555       
556    def FindPage(self,name):
557        numPage = self.GetPageCount()
558        for page in range(numPage):
559            if self.GetPageText(page) == name:
560                return page
561       
562class GSGrid(wg.Grid):
563    def __init__(self, parent, name=''):
564        wg.Grid.__init__(self,parent,-1,name=name)                   
565        self.SetSize(parent.GetClientSize())
566           
567    def Clear(self):
568        wg.Grid.ClearGrid(self)
569       
570    def SetCellStyle(self,r,c,color="white",readonly=True):
571        self.SetCellBackgroundColour(r,c,color)
572        self.SetReadOnly(r,c,isReadOnly=readonly)
573       
574    def GetSelection(self):
575        #this is to satisfy structure drawing stuff in G2plt when focus changes
576        return None
577                       
578class Table(wg.PyGridTableBase):
579    def __init__(self, data=[], rowLabels=None, colLabels=None, types = None):
580        wg.PyGridTableBase.__init__(self)
581        self.colLabels = colLabels
582        self.rowLabels = rowLabels
583        self.dataTypes = types
584        self.data = data
585       
586    def AppendRows(self, numRows=1):
587        self.data.append([])
588        return True
589       
590    def CanGetValueAs(self, row, col, typeName):
591        if self.dataTypes:
592            colType = self.dataTypes[col].split(':')[0]
593            if typeName == colType:
594                return True
595            else:
596                return False
597        else:
598            return False
599
600    def CanSetValueAs(self, row, col, typeName):
601        return self.CanGetValueAs(row, col, typeName)
602
603    def DeleteRow(self,pos):
604        data = self.GetData()
605        self.SetData([])
606        new = []
607        for irow,row in enumerate(data):
608            if irow <> pos:
609                new.append(row)
610        self.SetData(new)
611       
612    def GetColLabelValue(self, col):
613        if self.colLabels:
614            return self.colLabels[col]
615           
616    def GetData(self):
617        data = []
618        for row in range(self.GetNumberRows()):
619            data.append(self.GetRowValues(row))
620        return data
621       
622    def GetNumberCols(self):
623        try:
624            return len(self.colLabels)
625        except TypeError:
626            return None
627       
628    def GetNumberRows(self):
629        return len(self.data)
630       
631    def GetRowLabelValue(self, row):
632        if self.rowLabels:
633            return self.rowLabels[row]
634       
635    def GetColValues(self, col):
636        data = []
637        for row in range(self.GetNumberRows()):
638            data.append(self.GetValue(row, col))
639        return data
640       
641    def GetRowValues(self, row):
642        data = []
643        for col in range(self.GetNumberCols()):
644            data.append(self.GetValue(row, col))
645        return data
646       
647    def GetTypeName(self, row, col):
648        try:
649            return self.dataTypes[col]
650        except TypeError:
651            return None
652
653    def GetValue(self, row, col):
654        try:
655            return self.data[row][col]
656        except IndexError:
657            return None
658           
659    def InsertRows(self, pos, rows):
660        for row in range(rows):
661            self.data.insert(pos,[])
662            pos += 1
663       
664    def IsEmptyCell(self,row,col):
665        try:
666            return not self.data[row][col]
667        except IndexError:
668            return True
669       
670    def OnKeyPress(self, event):
671        dellist = self.GetSelectedRows()
672        if event.GetKeyCode() == wx.WXK_DELETE and dellist:
673            grid = self.GetView()
674            for i in dellist: grid.DeleteRow(i)
675               
676    def SetColLabelValue(self, col, label):
677        numcols = self.GetNumberCols()
678        if col > numcols-1:
679            self.colLabels.append(label)
680        else:
681            self.colLabels[col]=label
682       
683    def SetData(self,data):
684        for row in range(len(data)):
685            self.SetRowValues(row,data[row])
686               
687    def SetRowLabelValue(self, row, label):
688        self.rowLabels[row]=label
689           
690    def SetRowValues(self,row,data):
691        self.data[row] = data
692           
693    def SetValue(self, row, col, value):
694        def innerSetValue(row, col, value):
695            try:
696                self.data[row][col] = value
697            except TypeError:
698                return
699            except IndexError:
700                print row,col,value
701                # add a new row
702                if row > self.GetNumberRows():
703                    self.data.append([''] * self.GetNumberCols())
704                elif col > self.GetNumberCols():
705                    for row in range(self.GetNumberRows):
706                        self.data[row].append('')
707                print self.data
708                self.data[row][col] = value
709        innerSetValue(row, col, value)
710               
711def UpdateNotebook(self,data):       
712    if data:
713        self.dataFrame.SetLabel('Notebook')
714        self.dataDisplay = wx.TextCtrl(parent=self.dataFrame,size=self.dataFrame.GetClientSize(),
715            style=wx.TE_MULTILINE|wx.TE_PROCESS_ENTER | wx.TE_DONTWRAP)
716        for line in data:
717            self.dataDisplay.AppendText(line+"\n")
718            self.dataDisplay.AppendText('Notebook entry @ '+time.ctime()+"\n")
719           
720def UpdateControls(self,data):
721    #patch
722    if 'deriv type' not in data:
723        data = {}
724        data['deriv type'] = 'analytic Jacobian'
725        data['min dM/M'] = 0.0001
726        data['shift factor'] = 1.
727    if 'shift factor' not in data:
728        data['shift factor'] = 1.
729    if 'max cyc' not in data:
730        data['max cyc'] = 3       
731    #end patch
732    '''
733    #Fourier controls
734    'mapType':'Fobs','d-max':100.,'d-min':0.2,'histograms':[],
735    'stepSize':[0.5,0.5,0.5],'minX':[0.,0.,0.],'maxX':[1.0,1.0,1.0],
736    '''
737    def SeqSizer():
738       
739        def OnSelectData(event):
740            choices = ['All',]+GetPatternTreeDataNames(self,['PWDR',])
741            sel = []
742            if 'Seq Data' in data:
743                for item in data['Seq Data']:
744                    sel.append(choices.index(item))
745            names = []
746            dlg = wx.MultiChoiceDialog(self,'Select data:','Sequential refinement',choices)
747            dlg.SetSelections(sel)
748            if dlg.ShowModal() == wx.ID_OK:
749                sel = dlg.GetSelections()
750                for i in sel: names.append(choices[i])
751                if 'All' in names:
752                    names = choices[1:]
753                data['Seq Data'] = names               
754            dlg.Destroy()
755            reverseSel.Enable(True)
756           
757        def OnReverse(event):
758            data['Reverse Seq'] = reverseSel.GetValue()
759                   
760        seqSizer = wx.BoxSizer(wx.HORIZONTAL)
761        seqSizer.Add(wx.StaticText(self.dataDisplay,label=' Sequential Refinement Powder Data: '),0,wx.ALIGN_CENTER_VERTICAL)
762        selSeqData = wx.Button(self.dataDisplay,-1,label=' Select data')
763        selSeqData.Bind(wx.EVT_BUTTON,OnSelectData)
764        seqSizer.Add(selSeqData,0,wx.ALIGN_CENTER_VERTICAL)
765        seqSizer.Add((5,0),0)
766        reverseSel = wx.CheckBox(self.dataDisplay,-1,label=' Reverse order?')
767        reverseSel.Bind(wx.EVT_CHECKBOX,OnReverse)
768        if 'Seq Data' not in data:
769            reverseSel.Enable(False)
770        if 'Reverse Seq' in data:
771            reverseSel.SetValue(data['Reverse Seq'])
772        seqSizer.Add(reverseSel,0,wx.ALIGN_CENTER_VERTICAL)
773        return seqSizer
774       
775    def LSSizer():       
776       
777        def OnDerivType(event):
778            data['deriv type'] = derivSel.GetValue()
779            derivSel.SetValue(data['deriv type'])
780            wx.CallAfter(UpdateControls,self,data)
781           
782        def OnConvergence(event):
783            try:
784                value = max(1.e-9,min(1.0,float(Cnvrg.GetValue())))
785            except ValueError:
786                value = 0.0001
787            data['min dM/M'] = value
788            Cnvrg.SetValue('%.2g'%(value))
789           
790        def OnMaxCycles(event):
791            data['max cyc'] = int(maxCyc.GetValue())
792            maxCyc.SetValue(str(data['max cyc']))
793                       
794        def OnFactor(event):
795            try:
796                value = min(max(float(Factr.GetValue()),0.00001),100.)
797            except ValueError:
798                value = 1.0
799            data['shift factor'] = value
800            Factr.SetValue('%.5f'%(value))
801       
802        LSSizer = wx.FlexGridSizer(cols=6,vgap=5,hgap=5)
803        LSSizer.Add(wx.StaticText(self.dataDisplay,label=' Refinement derivatives: '),0,wx.ALIGN_CENTER_VERTICAL)
804        Choice=['analytic Jacobian','numeric','analytic Hessian']
805        derivSel = wx.ComboBox(parent=self.dataDisplay,value=data['deriv type'],choices=Choice,
806            style=wx.CB_READONLY|wx.CB_DROPDOWN)
807        derivSel.SetValue(data['deriv type'])
808        derivSel.Bind(wx.EVT_COMBOBOX, OnDerivType)
809           
810        LSSizer.Add(derivSel,0,wx.ALIGN_CENTER_VERTICAL)
811        LSSizer.Add(wx.StaticText(self.dataDisplay,label=' Min delta-M/M: '),0,wx.ALIGN_CENTER_VERTICAL)
812        Cnvrg = wx.TextCtrl(self.dataDisplay,-1,value='%.2g'%(data['min dM/M']),style=wx.TE_PROCESS_ENTER)
813        Cnvrg.Bind(wx.EVT_TEXT_ENTER,OnConvergence)
814        Cnvrg.Bind(wx.EVT_KILL_FOCUS,OnConvergence)
815        LSSizer.Add(Cnvrg,0,wx.ALIGN_CENTER_VERTICAL)
816        if 'Hessian' in data['deriv type']:
817            LSSizer.Add(wx.StaticText(self.dataDisplay,label=' Max cycles: '),0,wx.ALIGN_CENTER_VERTICAL)
818            Choice = ['0','1','2','3','5','10','15','20']
819            maxCyc = wx.ComboBox(parent=self.dataDisplay,value=str(data['max cyc']),choices=Choice,
820                style=wx.CB_READONLY|wx.CB_DROPDOWN)
821            maxCyc.SetValue(str(data['max cyc']))
822            maxCyc.Bind(wx.EVT_COMBOBOX, OnMaxCycles)
823            LSSizer.Add(maxCyc,0,wx.ALIGN_CENTER_VERTICAL)
824        else:
825            LSSizer.Add(wx.StaticText(self.dataDisplay,label=' Initial shift factor: '),0,wx.ALIGN_CENTER_VERTICAL)
826            Factr = wx.TextCtrl(self.dataDisplay,-1,value='%.5f'%(data['shift factor']),style=wx.TE_PROCESS_ENTER)
827            Factr.Bind(wx.EVT_TEXT_ENTER,OnFactor)
828            Factr.Bind(wx.EVT_KILL_FOCUS,OnFactor)
829            LSSizer.Add(Factr,0,wx.ALIGN_CENTER_VERTICAL)
830        return LSSizer
831       
832    if self.dataDisplay:
833        self.dataDisplay.Destroy()
834    if not self.dataFrame.GetStatusBar():
835        Status = self.dataFrame.CreateStatusBar()
836        Status.SetStatusText('')
837    self.dataFrame.SetLabel('Controls')
838    self.dataDisplay = wx.Panel(self.dataFrame)
839    self.dataFrame.SetMenuBar(self.dataFrame.ControlsMenu)
840    mainSizer = wx.BoxSizer(wx.VERTICAL)
841    mainSizer.Add((5,5),0)
842    mainSizer.Add(wx.StaticText(self.dataDisplay,label=' Refinement Controls:'),0,wx.ALIGN_CENTER_VERTICAL)   
843    mainSizer.Add(LSSizer())
844    mainSizer.Add((5,5),0)
845    mainSizer.Add(SeqSizer())
846    mainSizer.Add((5,5),0)
847       
848    mainSizer.Add(wx.StaticText(self.dataDisplay,label=' Density Map Controls:'),0,wx.ALIGN_CENTER_VERTICAL)
849
850    mainSizer.Layout()   
851    self.dataDisplay.SetSizer(mainSizer)
852    self.dataDisplay.SetSize(mainSizer.Fit(self.dataFrame))
853    self.dataFrame.setSizePosLeft(mainSizer.Fit(self.dataFrame))
854     
855def UpdateComments(self,data):                   
856    self.dataFrame.SetLabel('Comments')
857    self.dataDisplay = wx.TextCtrl(parent=self.dataFrame,size=self.dataFrame.GetClientSize(),
858        style=wx.TE_MULTILINE|wx.TE_PROCESS_ENTER | wx.TE_DONTWRAP)
859    for line in data:
860        if line[-1] == '\n':
861            self.dataDisplay.AppendText(line)
862        else:
863            self.dataDisplay.AppendText(line+'\n')
864           
865def UpdateSeqResults(self,data):
866    """
867    input:
868        data - dictionary
869            'histNames' - list of histogram names in order as processed by Sequential Refinement
870            'varyList' - list of variables - identical over all refinements insequence
871            histName - dictionaries for all data sets processed:
872                'variables'- result[0] from leastsq call
873                'varyList' - list of variables; same as above
874                'sig' - esds for variables
875                'covMatrix' - covariance matrix from individual refinement
876                'title' - histogram name; same as dict item name
877                'newAtomDict' - new atom parameters after shifts applied
878                'newCellDict' - new cell parameters after shifts to A0-A5 applied'
879    """
880    if not data:
881        print 'No sequential refinement results'
882        return
883    histNames = data['histNames']
884       
885    def GetSampleParms():
886        sampleParmDict = {'Temperature':[],'Pressure':[],'Humidity':[],'Voltage':[],'Force':[],}
887        sampleParm = {}
888        for name in histNames:
889            Id = GetPatternTreeItemId(self,self.root,name)
890            sampleData = self.PatternTree.GetItemPyData(GetPatternTreeItemId(self,Id,'Sample Parameters'))
891            for item in sampleParmDict:
892                sampleParmDict[item].append(sampleData[item])
893        for item in sampleParmDict:
894            frstValue = sampleParmDict[item][0]
895            if np.any(np.array(sampleParmDict[item])-frstValue):
896                sampleParm[item] = sampleParmDict[item]           
897        return sampleParm
898           
899    def GetSigData(parm):
900        sigData = []
901        for name in histNames:
902            sigList = data[name]['sig']
903            if colLabels[parm] in atomList:
904                sigData.append(sigList[colLabels.index(atomList[colLabels[parm]])])
905            elif colLabels[parm] in cellList:
906                sigData.append(sigList[colLabels.index(cellList[colLabels[parm]])])
907            else:
908                sigData.append(sigList[parm])
909        return sigData
910   
911    def Select(event):
912        cols = self.dataDisplay.GetSelectedCols()
913        rows = self.dataDisplay.GetSelectedRows()
914        if cols:
915            plotData = []
916            plotSig = []
917            plotNames = []
918            for col in cols:
919                plotData.append(self.SeqTable.GetColValues(col))
920                plotSig.append(GetSigData(col))
921                plotNames.append(self.SeqTable.GetColLabelValue(col))
922            plotData = np.array(plotData)
923            G2plt.PlotSeq(self,plotData,plotSig,plotNames,sampleParms)
924        elif rows:
925            name = histNames[rows[0]]
926            G2plt.PlotCovariance(self,Data=data[name])
927               
928    if self.dataDisplay:
929        self.dataDisplay.Destroy()
930    cellList = {}
931    newCellDict = data[histNames[0]]['newCellDict']
932    for item in newCellDict:
933        if item in data['varyList']:
934            cellList[newCellDict[item][0]] = item
935    atomList = {}
936    newAtomDict = data[histNames[0]]['newAtomDict']
937    for item in newAtomDict:
938        if item in data['varyList']:
939            atomList[newAtomDict[item][0]] = item
940    sampleParms = GetSampleParms()
941    self.dataFrame.SetMenuBar(self.dataFrame.BlankMenu)
942    self.dataFrame.SetLabel('Sequental refinement results')
943    self.dataFrame.CreateStatusBar()
944    colLabels = data['varyList']+atomList.keys()+cellList.keys()
945    Types = len(data['varyList']+atomList.keys()+cellList.keys())*[wg.GRID_VALUE_FLOAT,]
946    seqList = [list(data[name]['variables']) for name in histNames]
947   
948    for i,item in enumerate(seqList):
949        newAtomDict = data[histNames[i]]['newAtomDict']
950        newCellDict = data[histNames[i]]['newCellDict']
951        item += [newAtomDict[atomList[parm]][1] for parm in atomList.keys()]
952        item += [newCellDict[cellList[parm]][1] for parm in cellList.keys()]
953    self.SeqTable = Table(seqList,colLabels=colLabels,rowLabels=histNames,types=Types)
954    self.dataDisplay = GSGrid(parent=self.dataFrame)
955    self.dataDisplay.SetTable(self.SeqTable, True)
956    self.dataDisplay.EnableEditing(False)
957    self.dataDisplay.Bind(wg.EVT_GRID_LABEL_LEFT_DCLICK, Select)
958    self.dataDisplay.SetRowLabelSize(8*len(histNames[0]))       #pretty arbitrary 8
959    self.dataDisplay.SetMargins(0,0)
960    self.dataDisplay.AutoSizeColumns(True)
961    self.dataFrame.setSizePosLeft([700,350])
962   
963def UpdateConstraints(self,data):             
964#    data.update({'Hist':[],'HAP':[],'Phase':[]})       #empty dict - fill it
965    if not data:
966        data.update({'Hist':[],'HAP':[],'Phase':[]})       #empty dict - fill it
967    Histograms,Phases = self.GetUsedHistogramsAndPhasesfromTree()
968    AtomDict = dict([Phases[phase]['pId'],Phases[phase]['Atoms']] for phase in Phases)
969    Natoms,phaseVary,phaseDict,pawleyLookup,FFtable,BLtable = G2str.GetPhaseData(Phases,Print=False)
970    phaseList = []
971    for item in phaseDict:
972        if item.split(':')[2] not in ['Ax','Ay','Az','Amul','AI/A','Atype','SHorder']:
973            phaseList.append(item)
974    phaseList.sort()
975    phaseAtNames = {}
976    for item in phaseList:
977        Split = item.split(':')
978        if Split[2][:2] in ['AU','Af','dA']:
979            phaseAtNames[item] = AtomDict[int(Split[0])][int(Split[3])][0]
980        else:
981            phaseAtNames[item] = ''
982           
983    hapVary,hapDict,controlDict = G2str.GetHistogramPhaseData(Phases,Histograms,Print=False)
984    hapList = hapDict.keys()
985    hapList.sort()
986    histVary,histDict,controlDict = G2str.GetHistogramData(Histograms,Print=False)
987    histList = []
988    for item in histDict:
989        if item.split(':')[2] not in ['Omega','Type','Chi','Phi','Azimuth','Gonio. radius','Lam1','Lam2','Back']:
990            histList.append(item)
991    histList.sort()
992    Indx = {}
993    scope = {}                          #filled out later
994    self.Page = [0,'phs']
995   
996    def GetPHlegends(Phases,Histograms):
997        plegend = '\n In p::name'
998        hlegend = '\n In :h:name'
999        phlegend = '\n In p:h:name'
1000        for phase in Phases:
1001            plegend += '\n p:: = '+str(Phases[phase]['pId'])+':: for '+phase
1002            count = 0
1003            for histogram in Phases[phase]['Histograms']:
1004                if count < 3:
1005                    phlegend += '\n p:h: = '+str(Phases[phase]['pId'])+':'+str(Histograms[histogram]['hId'])+': for '+phase+' in '+histogram
1006                else:
1007                    phlegend += '\n ... etc.'
1008                    break
1009                count += 1
1010        count = 0
1011        for histogram in Histograms:
1012            if count < 3:
1013                hlegend += '\n :h: = :'+str(Histograms[histogram]['hId'])+': for '+histogram
1014            else:
1015                hlegend += '\n ... etc.'
1016                break
1017            count += 1
1018        return plegend,hlegend,phlegend
1019       
1020    def FindEquivVarb(name,nameList):
1021        outList = []
1022        namelist = [name.split(':')[2],]
1023        if 'dA' in name:
1024            namelist = ['dAx','dAy','dAz']
1025        elif 'AU' in name:
1026            namelist = ['AUiso','AU11','AU22','AU33','AU12','AU13','AU23']
1027        for item in nameList:
1028            key = item.split(':')[2]
1029            if key in namelist and item != name:
1030                outList.append(item)
1031        return outList
1032       
1033    def SelectVarbs(page,FrstVarb,varList,legend,constType):
1034        #future -  add 'all:all:name', '0:all:name', etc. to the varList
1035        if page[1] == 'phs':
1036            atchoice = [item+' for '+phaseAtNames[item] for item in varList]
1037            dlg = wx.MultiChoiceDialog(self,'Select more variables:'+legend,FrstVarb+' and:',atchoice)
1038        else:
1039            dlg = wx.MultiChoiceDialog(self,'Select more variables:'+legend,FrstVarb+' and:',varList)
1040        varbs = [FrstVarb,]
1041        if dlg.ShowModal() == wx.ID_OK:
1042            sel = dlg.GetSelections()
1043            for x in sel:
1044                varbs.append(varList[x])
1045        dlg.Destroy()
1046        if len(varbs) > 1:
1047            if 'equivalence' in constType:
1048                constr = []
1049                for item in varbs[1:]:
1050                    constr += [[[1.0,FrstVarb],[-1.0,item],None,None],]
1051                return constr           #multiple constraints
1052            elif 'function' in constType:
1053                constr = map(list,zip([1.0 for i in range(len(varbs))],varbs))
1054                return [constr+[0.0,False]]         #just one constraint
1055            else:       #'constraint'
1056                constr = map(list,zip([1.0 for i in range(len(varbs))],varbs))
1057                return [constr+[1.0,None]]          #just one constraint - default sum to one
1058        return []
1059             
1060    def OnAddHold(event):
1061        for phase in Phases:
1062            Phase = Phases[phase]
1063            Atoms = Phase['Atoms']
1064        constr = []
1065        page = self.Page
1066        choice = scope[page[1]]
1067        if page[1] == 'phs':
1068            atchoice = [item+' for '+phaseAtNames[item] for item in choice[2]]
1069            dlg = wx.SingleChoiceDialog(self,'Select 1st variable:'+choice[1],choice[0],atchoice)
1070        else:   
1071            dlg = wx.SingleChoiceDialog(self,'Select 1st variable:'+choice[1],choice[0],choice[2])
1072        if dlg.ShowModal() == wx.ID_OK:
1073            sel = dlg.GetSelection()
1074            FrstVarb = choice[2][sel]
1075            data[choice[3]] += [[[0.0,FrstVarb],None,None],]
1076        dlg.Destroy()
1077        choice[4]()
1078       
1079    def OnAddEquivalence(event):
1080        constr = []
1081        page = self.Page
1082        choice = scope[page[1]]
1083        if page[1] == 'phs':
1084            atchoice = [item+' for '+phaseAtNames[item] for item in choice[2]]
1085            dlg = wx.SingleChoiceDialog(self,'Select 1st variable:'+choice[1],choice[0],atchoice)
1086        else:   
1087            dlg = wx.SingleChoiceDialog(self,'Select 1st variable:'+choice[1],choice[0],choice[2])
1088        if dlg.ShowModal() == wx.ID_OK:
1089            sel = dlg.GetSelection()
1090            FrstVarb = choice[2][sel]
1091            moreVarb = FindEquivVarb(FrstVarb,choice[2])
1092            constr = SelectVarbs(page,FrstVarb,moreVarb,choice[1],'equivalence')
1093            if len(constr) > 0:
1094                data[choice[3]] += constr
1095        dlg.Destroy()
1096        choice[4]()
1097   
1098    def OnAddFunction(event):
1099        constr = []
1100        page = self.Page
1101        choice = scope[page[1]]
1102        if page[1] == 'phs':
1103            atchoice = [item+' for '+phaseAtNames[item] for item in choice[2]]
1104            dlg = wx.SingleChoiceDialog(self,'Select 1st variable:'+choice[1],choice[0],atchoice)
1105        else:   
1106            dlg = wx.SingleChoiceDialog(self,'Select 1st variable:'+choice[1],choice[0],choice[2])
1107        if dlg.ShowModal() == wx.ID_OK:
1108            sel = dlg.GetSelection()
1109            FrstVarb = choice[2][sel]
1110            moreVarb = FindEquivVarb(FrstVarb,choice[2])
1111            constr = SelectVarbs(page,FrstVarb,moreVarb,choice[1],'function')
1112            if len(constr) > 0:
1113                data[choice[3]] += constr
1114        dlg.Destroy()
1115        choice[4]()
1116                       
1117    def OnAddConstraint(event):
1118        constr = []
1119        page = self.Page
1120        choice = scope[page[1]]
1121        if page[1] == 'phs':
1122            atchoice = [item+' for '+phaseAtNames[item] for item in choice[2]]
1123            dlg = wx.SingleChoiceDialog(self,'Select 1st variable:'+choice[1],choice[0],atchoice)
1124        else:   
1125            dlg = wx.SingleChoiceDialog(self,'Select 1st variable:'+choice[1],choice[0],choice[2])
1126        if dlg.ShowModal() == wx.ID_OK:
1127            sel = dlg.GetSelection()
1128            FrstVarb = choice[2][sel]
1129            moreVarb = FindEquivVarb(FrstVarb,choice[2])
1130            constr = SelectVarbs(page,FrstVarb,moreVarb,choice[1],'constraint')
1131            if len(constr) > 0:
1132                data[choice[3]] += constr
1133        dlg.Destroy()
1134        choice[4]()
1135                       
1136    def ConstSizer(name,pageDisplay):
1137        constSizer = wx.FlexGridSizer(1,4,0,0)
1138        for Id,item in enumerate(data[name]):
1139            constDel = wx.Button(pageDisplay,-1,'Delete',style=wx.BU_EXACTFIT)
1140            constDel.Bind(wx.EVT_BUTTON,OnConstDel)
1141            Indx[constDel.GetId()] = [Id,name]
1142            if len(item) < 4:
1143                constSizer.Add((5,5),0)
1144                constSizer.Add(constDel)
1145                eqString = ' FIXED   '+item[0][1]+'   '
1146            else:
1147                constEdit = wx.Button(pageDisplay,-1,'Edit',style=wx.BU_EXACTFIT)
1148                constEdit.Bind(wx.EVT_BUTTON,OnConstEdit)
1149                Indx[constEdit.GetId()] = [Id,name]
1150                constSizer.Add(constEdit)           
1151                constSizer.Add(constDel)
1152                if isinstance(item[-1],bool):
1153                    eqString = ' FUNCT   '
1154                elif isinstance(item[-2],float):
1155                    eqString = ' CONSTR  '
1156                else:
1157                    eqString = ' EQUIV   '
1158                for term in item[:-2]:
1159                    eqString += '%+.3f*%s '%(term[0],term[1])
1160                if isinstance(item[-2],float):
1161                    eqString += ' = %.3f'%(item[-2])+'  '
1162                else:
1163                    eqString += ' = 0   '
1164            constSizer.Add(wx.StaticText(pageDisplay,-1,eqString),0,wx.ALIGN_CENTER_VERTICAL)
1165            if isinstance(item[-1],bool):
1166                constRef = wx.CheckBox(pageDisplay,-1,label=' Refine?')                   
1167                constRef.SetValue(item[-1])
1168                constRef.Bind(wx.EVT_CHECKBOX,OnConstRef)
1169                Indx[constRef.GetId()] = item
1170                constSizer.Add(constRef,0,wx.ALIGN_CENTER_VERTICAL)
1171            else:
1172                constSizer.Add((5,5),0)
1173        return constSizer
1174               
1175    def OnConstRef(event):
1176        Obj = event.GetEventObject()
1177        Indx[Obj.GetId()][-1] = Obj.GetValue()
1178       
1179    def OnConstDel(event):
1180        Obj = event.GetEventObject()
1181        Id,name = Indx[Obj.GetId()]
1182        del(data[name][Id])
1183        OnPageChanged(None)       
1184       
1185    def OnConstEdit(event):
1186        Obj = event.GetEventObject()
1187        Id,name = Indx[Obj.GetId()]
1188        const = data[name][Id][-2]       
1189        if isinstance(data[name][Id][-1],bool):
1190            items = data[name][Id][:-2]+[[],]
1191            constType = 'Function'
1192            extra = '; sum = new variable'
1193        elif isinstance(data[name][Id][-2],float):
1194            items = data[name][Id][:-2]+[[const,'= fixed value'],[]]
1195            constType = 'Constraint'
1196            extra = ' sum = constant'
1197        else:
1198            items = data[name][Id][:-2]+[[],]
1199            constType = 'Equivalence'
1200            extra = '; sum = 0'
1201        dlg = self.SumDialog(self,constType,'Enter value for each term in constraint'+extra,'',items)
1202        try:
1203            if dlg.ShowModal() == wx.ID_OK:
1204                result = dlg.GetData()
1205                if isinstance(data[name][Id][-2],float):
1206                    data[name][Id][:-2] = result[:-2]
1207                    data[name][Id][-2] = result[-2][0]
1208                else:
1209                    data[name][Id][:-2] = result[:-1]
1210        finally:
1211            dlg.Destroy()           
1212        OnPageChanged(None)                     
1213   
1214    def UpdateHAPConstr():
1215        HAPConstr.DestroyChildren()
1216        HAPDisplay = wx.Panel(HAPConstr)
1217        HAPSizer = wx.BoxSizer(wx.VERTICAL)
1218        HAPSizer.Add((5,5),0)
1219        HAPSizer.Add(ConstSizer('HAP',HAPDisplay))
1220        HAPDisplay.SetSizer(HAPSizer,True)
1221        Size = HAPSizer.GetMinSize()
1222        Size[0] += 40
1223        Size[1] = max(Size[1],250) + 20
1224        HAPDisplay.SetSize(Size)
1225        HAPConstr.SetScrollbars(10,10,Size[0]/10-4,Size[1]/10-1)
1226        Size[1] = min(Size[1],250)
1227        self.dataFrame.setSizePosLeft(Size)
1228       
1229    def UpdateHistConstr():
1230        HistConstr.DestroyChildren()
1231        HistDisplay = wx.Panel(HistConstr)
1232        HistSizer = wx.BoxSizer(wx.VERTICAL)
1233        HistSizer.Add((5,5),0)       
1234        HistSizer.Add(ConstSizer('Hist',HistDisplay))
1235        HistDisplay.SetSizer(HistSizer,True)
1236        Size = HistSizer.GetMinSize()
1237        Size[0] += 40
1238        Size[1] = max(Size[1],250) + 20
1239        HistDisplay.SetSize(Size)
1240        HistConstr.SetScrollbars(10,10,Size[0]/10-4,Size[1]/10-1)
1241        Size[1] = min(Size[1],250)
1242        self.dataFrame.setSizePosLeft(Size)
1243       
1244    def UpdatePhaseConstr():
1245        PhaseConstr.DestroyChildren()
1246        PhaseDisplay = wx.Panel(PhaseConstr)
1247        PhaseSizer = wx.BoxSizer(wx.VERTICAL)
1248        PhaseSizer.Add((5,5),0)       
1249        PhaseSizer.Add(ConstSizer('Phase',PhaseDisplay))
1250        PhaseDisplay.SetSizer(PhaseSizer,True)
1251        Size = PhaseSizer.GetMinSize()
1252        Size[0] += 40
1253        Size[1] = max(Size[1],250) + 20
1254        PhaseDisplay.SetSize(Size)
1255        PhaseConstr.SetScrollbars(10,10,Size[0]/10-4,Size[1]/10-1)
1256        Size[1] = min(Size[1],250)
1257        self.dataFrame.setSizePosLeft(Size)
1258   
1259    def OnPageChanged(event):
1260        if event:       #page change event!
1261            page = event.GetSelection()
1262        else:
1263            page = self.dataDisplay.GetSelection()
1264        oldPage = self.dataDisplay.ChangeSelection(page)
1265        text = self.dataDisplay.GetPageText(page)
1266        if text == 'Histogram/Phase constraints':
1267            self.Page = [page,'hap']
1268            UpdateHAPConstr()
1269        elif text == 'Histogram constraints':
1270            self.Page = [page,'hst']
1271            UpdateHistConstr()
1272        elif text == 'Phase constraints':
1273            self.Page = [page,'phs']
1274            UpdatePhaseConstr()
1275
1276    def SetStatusLine(text):
1277        Status.SetStatusText(text)                                     
1278       
1279    plegend,hlegend,phlegend = GetPHlegends(Phases,Histograms)
1280    scope = {'hst':['Histogram variables:',hlegend,histList,'Hist',UpdateHistConstr],
1281        'hap':['HAP variables:',phlegend,hapList,'HAP',UpdateHAPConstr],
1282        'phs':['Phase variables:',plegend,phaseList,'Phase',UpdatePhaseConstr]}
1283    if self.dataDisplay:
1284        self.dataDisplay.Destroy()
1285    self.dataFrame.SetMenuBar(self.dataFrame.ConstraintMenu)
1286    self.dataFrame.SetLabel('Constraints')
1287    if not self.dataFrame.GetStatusBar():
1288        Status = self.dataFrame.CreateStatusBar()
1289    SetStatusLine('')
1290   
1291    self.dataFrame.SetMenuBar(self.dataFrame.ConstraintMenu)
1292    self.dataFrame.Bind(wx.EVT_MENU, OnAddConstraint, id=wxID_CONSTRAINTADD)
1293    self.dataFrame.Bind(wx.EVT_MENU, OnAddFunction, id=wxID_FUNCTADD)
1294    self.dataFrame.Bind(wx.EVT_MENU, OnAddEquivalence, id=wxID_EQUIVADD)
1295    self.dataFrame.Bind(wx.EVT_MENU, OnAddHold, id=wxID_HOLDADD)
1296    self.dataDisplay = GSNoteBook(parent=self.dataFrame,size=self.dataFrame.GetClientSize())
1297   
1298    PhaseConstr = wx.ScrolledWindow(self.dataDisplay)
1299    self.dataDisplay.AddPage(PhaseConstr,'Phase constraints')
1300    HAPConstr = wx.ScrolledWindow(self.dataDisplay)
1301    self.dataDisplay.AddPage(HAPConstr,'Histogram/Phase constraints')
1302    HistConstr = wx.ScrolledWindow(self.dataDisplay)
1303    self.dataDisplay.AddPage(HistConstr,'Histogram constraints')
1304    UpdatePhaseConstr()
1305
1306    self.dataDisplay.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, OnPageChanged)
1307   
1308   
1309def UpdateRestraints(self,data):
1310
1311    def OnAddRestraint(event):
1312        page = self.dataDisplay.GetSelection()
1313        print self.dataDisplay.GetPageText(page)
1314
1315    def UpdateAtomRestr():
1316        AtomRestr.DestroyChildren()
1317        dataDisplay = wx.Panel(AtomRestr)
1318        mainSizer = wx.BoxSizer(wx.VERTICAL)
1319        mainSizer.Add((5,5),0)
1320        mainSizer.Add(wx.StaticText(dataDisplay,-1,'Atom restraint data:'),0,wx.ALIGN_CENTER_VERTICAL)
1321        mainSizer.Add((5,5),0)
1322
1323
1324        dataDisplay.SetSizer(mainSizer)
1325        Size = mainSizer.Fit(self.dataFrame)
1326        Size[1] += 26                           #compensate for status bar
1327        dataDisplay.SetSize(Size)
1328        self.dataFrame.setSizePosLeft(Size)
1329       
1330    def UpdatePhaseRestr():
1331        PhaseRestr.DestroyChildren()
1332        dataDisplay = wx.Panel(PhaseRestr)
1333        mainSizer = wx.BoxSizer(wx.VERTICAL)
1334        mainSizer.Add((5,5),0)
1335        mainSizer.Add(wx.StaticText(dataDisplay,-1,'Phase restraint data:'),0,wx.ALIGN_CENTER_VERTICAL)
1336        mainSizer.Add((5,5),0)
1337
1338
1339        dataDisplay.SetSizer(mainSizer)
1340        Size = mainSizer.Fit(self.dataFrame)
1341        Size[1] += 26                           #compensate for status bar
1342        dataDisplay.SetSize(Size)
1343        self.dataFrame.setSizePosLeft(Size)
1344   
1345    def OnPageChanged(event):
1346        page = event.GetSelection()
1347        text = self.dataDisplay.GetPageText(page)
1348        if text == 'Atom restraints':
1349            self.dataFrame.SetMenuBar(self.dataFrame.RestraintMenu)
1350            UpdateAtomRestr()
1351        elif text == 'Phase restraints':
1352            UpdatePhaseRestr()
1353            self.dataFrame.SetMenuBar(self.dataFrame.RestraintMenu)
1354        event.Skip()
1355
1356    if self.dataDisplay:
1357        self.dataDisplay.Destroy()
1358    self.dataFrame.SetMenuBar(self.dataFrame.RestraintMenu)
1359    self.dataFrame.SetLabel('restraints')
1360    self.dataFrame.CreateStatusBar()
1361    self.dataFrame.Bind(wx.EVT_MENU, OnAddRestraint, id=wxID_RESTRAINTADD)
1362    self.dataDisplay = GSNoteBook(parent=self.dataFrame,size=self.dataFrame.GetClientSize())
1363   
1364    PhaseRestr = wx.ScrolledWindow(self.dataDisplay)
1365    self.dataDisplay.AddPage(PhaseRestr,'Phase restraints')
1366    AtomRestr = wx.ScrolledWindow(self.dataDisplay)
1367    self.dataDisplay.AddPage(AtomRestr,'Atom restraints')
1368    UpdatePhaseRestr()
1369#    AtomRestrData = data['AtomRestr']
1370
1371    self.dataDisplay.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, OnPageChanged)       
1372             
1373def UpdateHKLControls(self,data):
1374   
1375    def OnScaleSlider(event):
1376        scale = int(scaleSel.GetValue())/1000.
1377        scaleSel.SetValue(int(scale*1000.))
1378        data['Scale'] = scale*10.
1379        G2plt.PlotSngl(self)
1380       
1381    def OnLayerSlider(event):
1382        layer = layerSel.GetValue()
1383        data['Layer'] = layer
1384        G2plt.PlotSngl(self)
1385       
1386    def OnSelZone(event):
1387        data['Zone'] = zoneSel.GetValue()
1388        G2plt.PlotSngl(self,newPlot=True)
1389       
1390    def OnSelType(event):
1391        data['Type'] = typeSel.GetValue()
1392        G2plt.PlotSngl(self)
1393       
1394    def SetStatusLine():
1395        Status.SetStatusText("look at me!!!")
1396                                     
1397    if self.dataDisplay:
1398        self.dataDisplay.Destroy()
1399    if not self.dataFrame.GetStatusBar():
1400        Status = self.dataFrame.CreateStatusBar()
1401    SetStatusLine()
1402    zones = ['100','010','001']
1403    HKLmax = data['HKLmax']
1404    HKLmin = data['HKLmin']
1405    if data['ifFc']:
1406        typeChoices = ['Fosq','Fo','|DFsq|/sig','|DFsq|>sig','|DFsq|>3sig']
1407    else:
1408        typeChoices = ['Fosq','Fo']
1409    self.dataDisplay = wx.Panel(self.dataFrame)
1410    self.dataFrame.SetMenuBar(self.dataFrame.BlankMenu)
1411    mainSizer = wx.BoxSizer(wx.VERTICAL)
1412    mainSizer.Add((5,10),0)
1413   
1414    scaleSizer = wx.BoxSizer(wx.HORIZONTAL)
1415    scaleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Scale'),0,
1416        wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
1417    scaleSel = wx.Slider(parent=self.dataDisplay,maxValue=1000,minValue=100,
1418        style=wx.SL_HORIZONTAL,value=int(data['Scale']*100))
1419    scaleSizer.Add(scaleSel,1,wx.EXPAND|wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
1420    scaleSel.SetLineSize(100)
1421    scaleSel.SetPageSize(900)
1422    scaleSel.Bind(wx.EVT_SLIDER, OnScaleSlider)
1423    mainSizer.Add(scaleSizer,1,wx.EXPAND|wx.RIGHT)
1424   
1425    zoneSizer = wx.BoxSizer(wx.HORIZONTAL)
1426    zoneSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Zone  '),0,
1427        wx.ALIGN_CENTER_VERTICAL)
1428    zoneSel = wx.ComboBox(parent=self.dataDisplay,value=data['Zone'],choices=['100','010','001'],
1429        style=wx.CB_READONLY|wx.CB_DROPDOWN)
1430    zoneSel.Bind(wx.EVT_COMBOBOX, OnSelZone)
1431    zoneSizer.Add(zoneSel,0,wx.ALIGN_CENTER_VERTICAL)
1432    zoneSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Plot type  '),0,
1433        wx.ALIGN_CENTER_VERTICAL)       
1434    typeSel = wx.ComboBox(parent=self.dataDisplay,value=data['Type'],choices=typeChoices,
1435        style=wx.CB_READONLY|wx.CB_DROPDOWN)
1436    typeSel.Bind(wx.EVT_COMBOBOX, OnSelType)
1437    zoneSizer.Add(typeSel,0,wx.ALIGN_CENTER_VERTICAL)
1438    zoneSizer.Add((10,0),0)   
1439    mainSizer.Add(zoneSizer,1,wx.EXPAND|wx.RIGHT)
1440       
1441    izone = zones.index(data['Zone'])
1442    layerSizer = wx.BoxSizer(wx.HORIZONTAL)
1443    layerSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Layer'),0,
1444        wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
1445    layerSel = wx.Slider(parent=self.dataDisplay,maxValue=HKLmax[izone],minValue=HKLmin[izone],
1446        style=wx.SL_HORIZONTAL|wx.SL_AUTOTICKS|wx.SL_LABELS,value=0)
1447    layerSel.SetLineSize(1)
1448    layerSel.SetLineSize(5)
1449    layerSel.Bind(wx.EVT_SLIDER, OnLayerSlider)   
1450    layerSizer.Add(layerSel,1,wx.EXPAND|wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
1451    layerSizer.Add((10,0),0)   
1452    mainSizer.Add(layerSizer,1,wx.EXPAND|wx.RIGHT)
1453
1454       
1455    mainSizer.Layout()   
1456    self.dataDisplay.SetSizer(mainSizer)
1457    self.dataDisplay.SetSize(mainSizer.Fit(self.dataFrame))
1458    self.dataFrame.setSizePosLeft(mainSizer.Fit(self.dataFrame))
1459
1460def GetPatternTreeDataNames(self,dataTypes):
1461    names = []
1462    item, cookie = self.PatternTree.GetFirstChild(self.root)       
1463    while item:
1464        name = self.PatternTree.GetItemText(item)
1465        if name[:4] in dataTypes:
1466            names.append(name)
1467        item, cookie = self.PatternTree.GetNextChild(self.root, cookie)
1468    return names
1469                         
1470def GetPatternTreeItemId(self, parentId, itemText):
1471    item, cookie = self.PatternTree.GetFirstChild(parentId)
1472    while item:
1473        if self.PatternTree.GetItemText(item) == itemText:
1474            return item
1475        item, cookie = self.PatternTree.GetNextChild(parentId, cookie)
1476    return 0               
1477
1478def MovePatternTreeToGrid(self,item):
1479   
1480#    print self.PatternTree.GetItemText(item)
1481   
1482    oldPage = 0
1483    if self.dataFrame:
1484        self.dataFrame.SetMenuBar(self.dataFrame.BlankMenu)
1485        if self.dataFrame.GetLabel() == 'Comments':
1486            data = [self.dataDisplay.GetValue()]
1487            self.dataDisplay.Clear() 
1488            Id = GetPatternTreeItemId(self,self.root, 'Comments')
1489            if Id: self.PatternTree.SetItemPyData(Id,data)
1490        elif self.dataFrame.GetLabel() == 'Notebook':
1491            data = [self.dataDisplay.GetValue()]
1492            self.dataDisplay.Clear() 
1493            Id = GetPatternTreeItemId(self,self.root, 'Notebook')
1494            if Id: self.PatternTree.SetItemPyData(Id,data)
1495        elif 'Phase Data for' in self.dataFrame.GetLabel():
1496            if self.dataDisplay: 
1497                oldPage = self.dataDisplay.GetSelection()
1498        self.dataFrame.Clear()
1499        self.dataFrame.SetLabel('')
1500    else:
1501        #create the frame for the data item window
1502        self.dataFrame = DataFrame(parent=self.mainPanel)
1503
1504    self.dataFrame.Raise()           
1505    self.PickId = 0
1506    parentID = self.root
1507    self.ExportPattern.Enable(False)
1508    defWid = [250,150]
1509    if item != self.root:
1510        parentID = self.PatternTree.GetItemParent(item)
1511    if self.PatternTree.GetItemParent(item) == self.root:
1512        self.PatternId = item
1513        self.PickId = item
1514        if self.PatternTree.GetItemText(item) == 'Notebook':
1515            self.dataFrame.SetMenuBar(self.dataFrame.DataNotebookMenu)
1516            self.PatternId = 0
1517            self.ExportPattern.Enable(False)
1518            data = self.PatternTree.GetItemPyData(item)
1519            UpdateNotebook(self,data)
1520        elif self.PatternTree.GetItemText(item) == 'Controls':
1521            self.PatternId = 0
1522            self.ExportPattern.Enable(False)
1523            data = self.PatternTree.GetItemPyData(item)
1524            if not data:           #fill in defaults
1525                data = {
1526                    #least squares controls
1527                    'deriv type':'analytic Jacobian','min dM/M':0.0001,'shift factor':1.0,'max cyc':3,
1528                    #Fourier controls
1529                    'mapType':'Fobs','d-max':100.,'d-min':0.2,'histograms':[],
1530                    'stepSize':[0.5,0.5,0.5],'minX':[0.,0.,0.],'maxX':[1.0,1.0,1.0],
1531                    #distance/angle controls
1532                    'distMax':0.0,'angleMax':0.0,'useMapPeaks':False}
1533                self.PatternTree.SetItemPyData(item,data)                             
1534            self.Refine.Enable(True)
1535            self.SeqRefine.Enable(True)
1536            UpdateControls(self,data)
1537        elif self.PatternTree.GetItemText(item) == 'Sequental results':
1538            data = self.PatternTree.GetItemPyData(item)
1539            UpdateSeqResults(self,data)           
1540        elif self.PatternTree.GetItemText(item) == 'Covariance':
1541            data = self.PatternTree.GetItemPyData(item)
1542            self.dataFrame.setSizePosLeft(defWid)
1543            wx.TextCtrl(parent=self.dataFrame,size=self.dataFrame.GetClientSize(),
1544                        value='See plot window for covariance display')
1545            G2plt.PlotCovariance(self)
1546        elif self.PatternTree.GetItemText(item) == 'Constraints':
1547            data = self.PatternTree.GetItemPyData(item)
1548            UpdateConstraints(self,data)
1549        elif self.PatternTree.GetItemText(item) == 'Restraints':
1550            data = self.PatternTree.GetItemPyData(item)
1551            UpdateRestraints(self,data)
1552        elif 'IMG' in self.PatternTree.GetItemText(item):
1553            self.Image = item
1554            G2plt.PlotImage(self,newPlot=True)
1555        elif 'PKS' in self.PatternTree.GetItemText(item):
1556            G2plt.PlotPowderLines(self)
1557        elif 'PWDR' in self.PatternTree.GetItemText(item):
1558            self.ExportPattern.Enable(True)
1559            self.dataFrame.setSizePosLeft(defWid)
1560            wx.TextCtrl(parent=self.dataFrame,size=self.dataFrame.GetClientSize(),
1561                style=wx.TE_MULTILINE,
1562                value='See plot window for powder data display\nor select a data item in histogram')
1563            G2plt.PlotPatterns(self,newPlot=True)
1564        elif 'HKLF' in self.PatternTree.GetItemText(item):
1565            self.Sngl = item
1566            G2plt.PlotSngl(self,newPlot=True)
1567        elif 'PDF' in self.PatternTree.GetItemText(item):
1568            self.PatternId = item
1569            self.ExportPDF.Enable(True)
1570            G2plt.PlotISFG(self,type='S(Q)')
1571        elif self.PatternTree.GetItemText(item) == 'Phases':
1572            self.dataFrame.setSizePosLeft(defWid)
1573            wx.TextCtrl(parent=self.dataFrame,size=self.dataFrame.GetClientSize(),
1574                value='Select one phase to see its parameters')           
1575    elif 'I(Q)' in self.PatternTree.GetItemText(item):
1576        self.PickId = item
1577        self.PatternId = self.PatternTree.GetItemParent(item)
1578        G2plt.PlotISFG(self,type='I(Q)',newPlot=True)
1579    elif 'S(Q)' in self.PatternTree.GetItemText(item):
1580        self.PickId = item
1581        self.PatternId = self.PatternTree.GetItemParent(item)
1582        G2plt.PlotISFG(self,type='S(Q)',newPlot=True)
1583    elif 'F(Q)' in self.PatternTree.GetItemText(item):
1584        self.PickId = item
1585        self.PatternId = self.PatternTree.GetItemParent(item)
1586        G2plt.PlotISFG(self,type='F(Q)',newPlot=True)
1587    elif 'G(R)' in self.PatternTree.GetItemText(item):
1588        self.PickId = item
1589        self.PatternId = self.PatternTree.GetItemParent(item)
1590        G2plt.PlotISFG(self,type='G(R)',newPlot=True)           
1591    elif self.PatternTree.GetItemText(parentID) == 'Phases':
1592        self.PickId = item
1593        data = self.PatternTree.GetItemPyData(item)           
1594        G2phG.UpdatePhaseData(self,item,data,oldPage)
1595    elif self.PatternTree.GetItemText(item) == 'Comments':
1596        self.dataFrame.SetMenuBar(self.dataFrame.DataCommentsMenu)
1597        self.PatternId = self.PatternTree.GetItemParent(item)
1598        self.PickId = item
1599        data = self.PatternTree.GetItemPyData(item)
1600        UpdateComments(self,data)
1601    elif self.PatternTree.GetItemText(item) == 'Image Controls':
1602        self.dataFrame.SetTitle('Image Controls')
1603        self.PickId = item
1604        self.Image = self.PatternTree.GetItemParent(item)
1605        masks = self.PatternTree.GetItemPyData(
1606            GetPatternTreeItemId(self,self.Image, 'Masks'))
1607        data = self.PatternTree.GetItemPyData(item)
1608        G2imG.UpdateImageControls(self,data,masks)
1609        G2plt.PlotImage(self)
1610    elif self.PatternTree.GetItemText(item) == 'Masks':
1611        self.dataFrame.SetTitle('Masks')
1612        self.PickId = item
1613        self.Image = self.PatternTree.GetItemParent(item)
1614        data = self.PatternTree.GetItemPyData(item)
1615        G2imG.UpdateMasks(self,data)
1616        G2plt.PlotImage(self)
1617    elif self.PatternTree.GetItemText(item) == 'HKL Plot Controls':
1618        self.PickId = item
1619        self.Sngl = self.PatternTree.GetItemParent(item)
1620        data = self.PatternTree.GetItemPyData(item)
1621        UpdateHKLControls(self,data)
1622        G2plt.PlotSngl(self)
1623    elif self.PatternTree.GetItemText(item) == 'PDF Controls':
1624        self.PatternId = self.PatternTree.GetItemParent(item)
1625        self.ExportPDF.Enable(True)
1626        self.PickId = item
1627        data = self.PatternTree.GetItemPyData(item)
1628        G2pdG.UpdatePDFGrid(self,data)
1629        G2plt.PlotISFG(self,type='I(Q)')
1630        G2plt.PlotISFG(self,type='S(Q)')
1631        G2plt.PlotISFG(self,type='F(Q)')
1632        G2plt.PlotISFG(self,type='G(R)')
1633    elif self.PatternTree.GetItemText(item) == 'Peak List':
1634        self.PatternId = self.PatternTree.GetItemParent(item)
1635        self.ExportPeakList.Enable(True)
1636        self.PickId = item
1637        data = self.PatternTree.GetItemPyData(item)
1638        G2pdG.UpdatePeakGrid(self,data)
1639        G2plt.PlotPatterns(self)
1640    elif self.PatternTree.GetItemText(item) == 'Background':
1641        self.PatternId = self.PatternTree.GetItemParent(item)
1642        self.PickId = item
1643        data = self.PatternTree.GetItemPyData(item)
1644        G2pdG.UpdateBackground(self,data)
1645        G2plt.PlotPatterns(self)
1646    elif self.PatternTree.GetItemText(item) == 'Limits':
1647        self.PatternId = self.PatternTree.GetItemParent(item)
1648        self.PickId = item
1649        data = self.PatternTree.GetItemPyData(item)
1650        G2pdG.UpdateLimitsGrid(self,data)
1651        G2plt.PlotPatterns(self)
1652    elif self.PatternTree.GetItemText(item) == 'Instrument Parameters':
1653        self.PatternId = self.PatternTree.GetItemParent(item)
1654        self.PickId = item
1655        data = self.PatternTree.GetItemPyData(item)
1656        G2pdG.UpdateInstrumentGrid(self,data)
1657        G2plt.PlotPeakWidths(self)
1658    elif self.PatternTree.GetItemText(item) == 'Sample Parameters':
1659        self.PatternId = self.PatternTree.GetItemParent(item)
1660        self.PickId = item
1661        data = self.PatternTree.GetItemPyData(item)
1662
1663        if 'Temperature' not in data:           #temp fix for old gpx files
1664            data = {'Scale':[1.0,True],'Type':'Debye-Scherrer','Absorption':[0.0,False],'DisplaceX':[0.0,False],
1665                'DisplaceY':[0.0,False],'Diffuse':[],'Temperature':300.,'Pressure':1.0,'Humidity':0.0,'Voltage':0.0,
1666                'Force':0.0,'Gonio. radius':200.0}
1667            self.PatternTree.SetItemPyData(item,data)
1668   
1669        G2pdG.UpdateSampleGrid(self,data)
1670        G2plt.PlotPatterns(self)
1671    elif self.PatternTree.GetItemText(item) == 'Index Peak List':
1672        self.PatternId = self.PatternTree.GetItemParent(item)
1673        self.ExportPeakList.Enable(True)
1674        self.PickId = item
1675        data = self.PatternTree.GetItemPyData(item)
1676        G2pdG.UpdateIndexPeaksGrid(self,data)
1677        if 'PKS' in self.PatternTree.GetItemText(self.PatternId):
1678            G2plt.PlotPowderLines(self)
1679        else:
1680            G2plt.PlotPatterns(self)
1681    elif self.PatternTree.GetItemText(item) == 'Unit Cells List':
1682        self.PatternId = self.PatternTree.GetItemParent(item)
1683        self.PickId = item
1684        data = self.PatternTree.GetItemPyData(item)
1685        if not data:
1686            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
1687            data.append([0,0,0,0,0,0,0,0,0,0,0,0,0,0])      #Bravais lattice flags
1688            data.append([])                                 #empty cell list
1689            data.append([])                                 #empty dmin
1690            self.PatternTree.SetItemPyData(item,data)                             
1691        G2pdG.UpdateUnitCellsGrid(self,data)
1692        if 'PKS' in self.PatternTree.GetItemText(self.PatternId):
1693            G2plt.PlotPowderLines(self)
1694        else:
1695            G2plt.PlotPatterns(self)
1696    elif self.PatternTree.GetItemText(item) == 'Reflection Lists':
1697        self.PatternId = self.PatternTree.GetItemParent(item)
1698        self.PickId = item
1699        data = self.PatternTree.GetItemPyData(item)
1700        self.RefList = ''
1701        if len(data):
1702            self.RefList = data.keys()[0]
1703        G2pdG.UpdateReflectionGrid(self,data)
1704        G2plt.PlotPatterns(self)
Note: See TracBrowser for help on using the repository browser.