source: trunk/GSASIIgrid.py @ 482

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

move FileDlgFixExt? to G2IO
begin to add a save selected seq results to file
move IO routines called in G2struct back there
remove wx stuff from G2pwd & G2struct
put progress bar in G2pwdGUI (not G2pwd)

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