source: trunk/GSASIIgrid.py @ 447

Last change on this file since 447 was 446, checked in by vondreele, 13 years ago

continue refactoring of GSASIIgrid.py - DrawAtoms?
fix error in background calc & deriv

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