source: branch/MPbranch/GSASIIgrid.py @ 2895

Last change on this file since 2895 was 496, checked in by vondreele, 13 years ago

making 1st multiprocess version of GSAS-II

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