source: trunk/GSASIIgrid.py @ 449

Last change on this file since 449 was 449, checked in by toby, 11 years ago

Help updates: refactor help routine; use internal browser on Windows; add help to more (all?) windows; add text to avoid blank data windows;remove some unused code

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