source: trunk/GSASIIgrid.py @ 493

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

clean up help stuff - get OK respons from resize & now scrolls down a bit so text at top is seen.

  • Property svn:keywords set to Date Author Revision URL Id
File size: 79.0 KB
Line 
1#GSASII - data display routines
2########### SVN repository information ###################
3# $Date: 2012-02-24 19:11:44 +0000 (Fri, 24 Feb 2012) $
4# $Author: vondreele $
5# $Revision: 493 $
6# $URL: trunk/GSASIIgrid.py $
7# $Id: GSASIIgrid.py 493 2012-02-24 19:11:44Z 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 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    if 'shift factor' not in data:
747        data['shift factor'] = 1.
748    if 'max cyc' not in data:
749        data['max cyc'] = 3       
750    #end patch
751    def SeqSizer():
752       
753        def OnSelectData(event):
754            choices = ['All',]+GetPatternTreeDataNames(G2frame,['PWDR',])
755            sel = []
756            if 'Seq Data' in data:
757                for item in data['Seq Data']:
758                    sel.append(choices.index(item))
759            names = []
760            dlg = wx.MultiChoiceDialog(G2frame,'Select data:','Sequential refinement',choices)
761            dlg.SetSelections(sel)
762            if dlg.ShowModal() == wx.ID_OK:
763                sel = dlg.GetSelections()
764                for i in sel: names.append(choices[i])
765                if 'All' in names:
766                    names = choices[1:]
767                data['Seq Data'] = names               
768            dlg.Destroy()
769            reverseSel.Enable(True)
770           
771        def OnReverse(event):
772            data['Reverse Seq'] = reverseSel.GetValue()
773                   
774        seqSizer = wx.BoxSizer(wx.HORIZONTAL)
775        seqSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Sequential Refinement Powder Data: '),0,wx.ALIGN_CENTER_VERTICAL)
776        selSeqData = wx.Button(G2frame.dataDisplay,-1,label=' Select data')
777        selSeqData.Bind(wx.EVT_BUTTON,OnSelectData)
778        seqSizer.Add(selSeqData,0,wx.ALIGN_CENTER_VERTICAL)
779        seqSizer.Add((5,0),0)
780        reverseSel = wx.CheckBox(G2frame.dataDisplay,-1,label=' Reverse order?')
781        reverseSel.Bind(wx.EVT_CHECKBOX,OnReverse)
782        if 'Seq Data' not in data:
783            reverseSel.Enable(False)
784        if 'Reverse Seq' in data:
785            reverseSel.SetValue(data['Reverse Seq'])
786        seqSizer.Add(reverseSel,0,wx.ALIGN_CENTER_VERTICAL)
787        return seqSizer
788       
789    def LSSizer():       
790       
791        def OnDerivType(event):
792            data['deriv type'] = derivSel.GetValue()
793            derivSel.SetValue(data['deriv type'])
794            wx.CallAfter(UpdateControls,G2frame,data)
795           
796        def OnConvergence(event):
797            try:
798                value = max(1.e-9,min(1.0,float(Cnvrg.GetValue())))
799            except ValueError:
800                value = 0.0001
801            data['min dM/M'] = value
802            Cnvrg.SetValue('%.2g'%(value))
803           
804        def OnMaxCycles(event):
805            data['max cyc'] = int(maxCyc.GetValue())
806            maxCyc.SetValue(str(data['max cyc']))
807                       
808        def OnFactor(event):
809            try:
810                value = min(max(float(Factr.GetValue()),0.00001),100.)
811            except ValueError:
812                value = 1.0
813            data['shift factor'] = value
814            Factr.SetValue('%.5f'%(value))
815       
816        LSSizer = wx.FlexGridSizer(cols=6,vgap=5,hgap=5)
817        LSSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Refinement derivatives: '),0,wx.ALIGN_CENTER_VERTICAL)
818        Choice=['analytic Jacobian','numeric','analytic Hessian']
819        derivSel = wx.ComboBox(parent=G2frame.dataDisplay,value=data['deriv type'],choices=Choice,
820            style=wx.CB_READONLY|wx.CB_DROPDOWN)
821        derivSel.SetValue(data['deriv type'])
822        derivSel.Bind(wx.EVT_COMBOBOX, OnDerivType)
823           
824        LSSizer.Add(derivSel,0,wx.ALIGN_CENTER_VERTICAL)
825        LSSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Min delta-M/M: '),0,wx.ALIGN_CENTER_VERTICAL)
826        Cnvrg = wx.TextCtrl(G2frame.dataDisplay,-1,value='%.2g'%(data['min dM/M']),style=wx.TE_PROCESS_ENTER)
827        Cnvrg.Bind(wx.EVT_TEXT_ENTER,OnConvergence)
828        Cnvrg.Bind(wx.EVT_KILL_FOCUS,OnConvergence)
829        LSSizer.Add(Cnvrg,0,wx.ALIGN_CENTER_VERTICAL)
830        if 'Hessian' in data['deriv type']:
831            LSSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Max cycles: '),0,wx.ALIGN_CENTER_VERTICAL)
832            Choice = ['0','1','2','3','5','10','15','20']
833            maxCyc = wx.ComboBox(parent=G2frame.dataDisplay,value=str(data['max cyc']),choices=Choice,
834                style=wx.CB_READONLY|wx.CB_DROPDOWN)
835            maxCyc.SetValue(str(data['max cyc']))
836            maxCyc.Bind(wx.EVT_COMBOBOX, OnMaxCycles)
837            LSSizer.Add(maxCyc,0,wx.ALIGN_CENTER_VERTICAL)
838        else:
839            LSSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Initial shift factor: '),0,wx.ALIGN_CENTER_VERTICAL)
840            Factr = wx.TextCtrl(G2frame.dataDisplay,-1,value='%.5f'%(data['shift factor']),style=wx.TE_PROCESS_ENTER)
841            Factr.Bind(wx.EVT_TEXT_ENTER,OnFactor)
842            Factr.Bind(wx.EVT_KILL_FOCUS,OnFactor)
843            LSSizer.Add(Factr,0,wx.ALIGN_CENTER_VERTICAL)
844        return LSSizer
845       
846    if G2frame.dataDisplay:
847        G2frame.dataDisplay.Destroy()
848    if not G2frame.dataFrame.GetStatusBar():
849        Status = G2frame.dataFrame.CreateStatusBar()
850        Status.SetStatusText('')
851    G2frame.dataFrame.SetLabel('Controls')
852    G2frame.dataDisplay = wx.Panel(G2frame.dataFrame)
853    G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.ControlsMenu)
854    mainSizer = wx.BoxSizer(wx.VERTICAL)
855    mainSizer.Add((5,5),0)
856    mainSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Refinement Controls:'),0,wx.ALIGN_CENTER_VERTICAL)   
857    mainSizer.Add(LSSizer())
858    mainSizer.Add((5,5),0)
859    mainSizer.Add(SeqSizer())
860    mainSizer.Add((5,5),0)
861       
862    mainSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Density Map Controls:'),0,wx.ALIGN_CENTER_VERTICAL)
863
864    mainSizer.Layout()   
865    G2frame.dataDisplay.SetSizer(mainSizer)
866    G2frame.dataDisplay.SetSize(mainSizer.Fit(G2frame.dataFrame))
867    G2frame.dataFrame.setSizePosLeft(mainSizer.Fit(G2frame.dataFrame))
868     
869def UpdateComments(G2frame,data):                   
870    G2frame.dataFrame.SetLabel('Comments')
871    G2frame.dataDisplay = wx.TextCtrl(parent=G2frame.dataFrame,size=G2frame.dataFrame.GetClientSize(),
872        style=wx.TE_MULTILINE|wx.TE_PROCESS_ENTER | wx.TE_DONTWRAP)
873    for line in data:
874        if line[-1] == '\n':
875            G2frame.dataDisplay.AppendText(line)
876        else:
877            G2frame.dataDisplay.AppendText(line+'\n')
878           
879def UpdateSeqResults(G2frame,data):
880    """
881    input:
882        data - dictionary
883            'histNames' - list of histogram names in order as processed by Sequential Refinement
884            'varyList' - list of variables - identical over all refinements insequence
885            histName - dictionaries for all data sets processed:
886                'variables'- result[0] from leastsq call
887                'varyList' - list of variables; same as above
888                'sig' - esds for variables
889                'covMatrix' - covariance matrix from individual refinement
890                'title' - histogram name; same as dict item name
891                'newAtomDict' - new atom parameters after shifts applied
892                'newCellDict' - new cell parameters after shifts to A0-A5 applied'
893    """
894    if not data:
895        print 'No sequential refinement results'
896        return
897    histNames = data['histNames']
898       
899    def GetSampleParms():
900        sampleParmDict = {'Temperature':[],'Pressure':[],'Humidity':[],'Voltage':[],'Force':[],}
901        sampleParm = {}
902        for name in histNames:
903            Id = GetPatternTreeItemId(G2frame,G2frame.root,name)
904            sampleData = G2frame.PatternTree.GetItemPyData(GetPatternTreeItemId(G2frame,Id,'Sample Parameters'))
905            for item in sampleParmDict:
906                sampleParmDict[item].append(sampleData[item])
907        for item in sampleParmDict:
908            frstValue = sampleParmDict[item][0]
909            if np.any(np.array(sampleParmDict[item])-frstValue):
910                sampleParm[item] = sampleParmDict[item]           
911        return sampleParm
912           
913    def GetSigData(parm):
914        sigData = []
915        for name in histNames:
916            sigList = data[name]['sig']
917            if colLabels[parm] in atomList:
918                sigData.append(sigList[colLabels.index(atomList[colLabels[parm]])])
919            elif colLabels[parm] in cellList:
920                sigData.append(sigList[colLabels.index(cellList[colLabels[parm]])])
921            else:
922                sigData.append(sigList[parm])
923        return sigData
924   
925    def Select(event):
926        cols = G2frame.dataDisplay.GetSelectedCols()
927        rows = G2frame.dataDisplay.GetSelectedRows()
928        if cols:
929            plotData = []
930            plotSig = []
931            plotNames = []
932            for col in cols:
933                plotData.append(G2frame.SeqTable.GetColValues(col))
934                plotSig.append(GetSigData(col))
935                plotNames.append(G2frame.SeqTable.GetColLabelValue(col))
936            plotData = np.array(plotData)
937            G2plt.PlotSeq(G2frame,plotData,plotSig,plotNames,sampleParms)
938        elif rows:
939            name = histNames[rows[0]]
940            G2plt.PlotCovariance(G2frame,Data=data[name])
941           
942    def OnSaveSelSeq(event):       
943        cols = G2frame.dataDisplay.GetSelectedCols()
944        if cols:
945            numRows = G2frame.SeqTable.GetNumberRows()
946            dataNames = []
947            saveNames = [G2frame.SeqTable.GetRowLabelValue(r) for r in range(numRows)]
948            saveData = []
949            for col in cols:
950                dataNames.append(G2frame.SeqTable.GetColLabelValue(col))
951                saveData.append(zip(G2frame.SeqTable.GetColValues(col),GetSigData(col)))
952            lenName = len(saveNames[0])
953            saveData = np.swapaxes(np.array(saveData),0,1)
954            dlg = wx.FileDialog(G2frame, 'Choose text output file for your selection', '.', '', 
955                'Text output file (*.txt)|*.txt',wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT|wx.CHANGE_DIR)
956            try:
957                if dlg.ShowModal() == wx.ID_OK:
958                    SeqTextFile = dlg.GetPath()
959                    SeqTextFile = G2IO.FileDlgFixExt(dlg,SeqTextFile)
960                    SeqFile = open(SeqTextFile,'w')
961                    line = %s  '%('name'.center(lenName))
962                    for item in dataNames:
963                        line += ' %12s %12s '%(item.center(12),'esd'.center(12))
964                    line += '\n'
965                    SeqFile.write(line)
966                    for i,item in enumerate(saveData):
967                        line = " '%s' "%(saveNames[i])
968                        for val,esd in item:
969                            line += ' %12.6f %12.6f '%(val,esd)
970                        line += '\n'
971                        SeqFile.write(line)
972                    SeqFile.close()
973            finally:
974                dlg.Destroy()
975           
976               
977    if G2frame.dataDisplay:
978        G2frame.dataDisplay.Destroy()
979    cellList = {}
980    newCellDict = data[histNames[0]]['newCellDict']
981    for item in newCellDict:
982        if item in data['varyList']:
983            cellList[newCellDict[item][0]] = item
984    atomList = {}
985    newAtomDict = data[histNames[0]]['newAtomDict']
986    for item in newAtomDict:
987        if item in data['varyList']:
988            atomList[newAtomDict[item][0]] = item
989    sampleParms = GetSampleParms()
990    G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.SequentialMenu)
991    G2frame.dataFrame.SetLabel('Sequental refinement results')
992    G2frame.dataFrame.CreateStatusBar()
993    G2frame.dataFrame.Bind(wx.EVT_MENU, OnSaveSelSeq, id=wxID_SAVESEQSEL)
994    colLabels = data['varyList']+atomList.keys()+cellList.keys()
995    Types = len(data['varyList']+atomList.keys()+cellList.keys())*[wg.GRID_VALUE_FLOAT,]
996    seqList = [list(data[name]['variables']) for name in histNames]
997   
998    for i,item in enumerate(seqList):
999        newAtomDict = data[histNames[i]]['newAtomDict']
1000        newCellDict = data[histNames[i]]['newCellDict']
1001        item += [newAtomDict[atomList[parm]][1] for parm in atomList.keys()]
1002        item += [newCellDict[cellList[parm]][1] for parm in cellList.keys()]
1003    G2frame.SeqTable = Table(seqList,colLabels=colLabels,rowLabels=histNames,types=Types)
1004    G2frame.dataDisplay = GSGrid(parent=G2frame.dataFrame)
1005    G2frame.dataDisplay.SetTable(G2frame.SeqTable, True)
1006    G2frame.dataDisplay.EnableEditing(False)
1007    G2frame.dataDisplay.Bind(wg.EVT_GRID_LABEL_LEFT_DCLICK, Select)
1008    G2frame.dataDisplay.SetRowLabelSize(8*len(histNames[0]))       #pretty arbitrary 8
1009    G2frame.dataDisplay.SetMargins(0,0)
1010    G2frame.dataDisplay.AutoSizeColumns(True)
1011    G2frame.dataFrame.setSizePosLeft([700,350])
1012   
1013def UpdateConstraints(G2frame,data):             
1014#    data.update({'Hist':[],'HAP':[],'Phase':[]})       #empty dict - fill it
1015    if not data:
1016        data.update({'Hist':[],'HAP':[],'Phase':[]})       #empty dict - fill it
1017    Histograms,Phases = G2frame.GetUsedHistogramsAndPhasesfromTree()
1018    AtomDict = dict([Phases[phase]['pId'],Phases[phase]['Atoms']] for phase in Phases)
1019    Natoms,phaseVary,phaseDict,pawleyLookup,FFtable,BLtable = G2str.GetPhaseData(Phases,Print=False)
1020    phaseList = []
1021    for item in phaseDict:
1022        if item.split(':')[2] not in ['Ax','Ay','Az','Amul','AI/A','Atype','SHorder']:
1023            phaseList.append(item)
1024    phaseList.sort()
1025    phaseAtNames = {}
1026    for item in phaseList:
1027        Split = item.split(':')
1028        if Split[2][:2] in ['AU','Af','dA']:
1029            phaseAtNames[item] = AtomDict[int(Split[0])][int(Split[3])][0]
1030        else:
1031            phaseAtNames[item] = ''
1032           
1033    hapVary,hapDict,controlDict = G2str.GetHistogramPhaseData(Phases,Histograms,Print=False)
1034    hapList = hapDict.keys()
1035    hapList.sort()
1036    histVary,histDict,controlDict = G2str.GetHistogramData(Histograms,Print=False)
1037    histList = []
1038    for item in histDict:
1039        if item.split(':')[2] not in ['Omega','Type','Chi','Phi','Azimuth','Gonio. radius','Lam1','Lam2','Back']:
1040            histList.append(item)
1041    histList.sort()
1042    Indx = {}
1043    scope = {}                          #filled out later
1044    G2frame.Page = [0,'phs']
1045   
1046    def GetPHlegends(Phases,Histograms):
1047        plegend = '\n In p::name'
1048        hlegend = '\n In :h:name'
1049        phlegend = '\n In p:h:name'
1050        for phase in Phases:
1051            plegend += '\n p:: = '+str(Phases[phase]['pId'])+':: for '+phase
1052            count = 0
1053            for histogram in Phases[phase]['Histograms']:
1054                if count < 3:
1055                    phlegend += '\n p:h: = '+str(Phases[phase]['pId'])+':'+str(Histograms[histogram]['hId'])+': for '+phase+' in '+histogram
1056                else:
1057                    phlegend += '\n ... etc.'
1058                    break
1059                count += 1
1060        count = 0
1061        for histogram in Histograms:
1062            if count < 3:
1063                hlegend += '\n :h: = :'+str(Histograms[histogram]['hId'])+': for '+histogram
1064            else:
1065                hlegend += '\n ... etc.'
1066                break
1067            count += 1
1068        return plegend,hlegend,phlegend
1069       
1070    def FindEquivVarb(name,nameList):
1071        outList = []
1072        namelist = [name.split(':')[2],]
1073        if 'dA' in name:
1074            namelist = ['dAx','dAy','dAz']
1075        elif 'AU' in name:
1076            namelist = ['AUiso','AU11','AU22','AU33','AU12','AU13','AU23']
1077        for item in nameList:
1078            key = item.split(':')[2]
1079            if key in namelist and item != name:
1080                outList.append(item)
1081        return outList
1082       
1083    def SelectVarbs(page,FrstVarb,varList,legend,constType):
1084        #future -  add 'all:all:name', '0:all:name', etc. to the varList
1085        if page[1] == 'phs':
1086            atchoice = [item+' for '+phaseAtNames[item] for item in varList]
1087            dlg = wx.MultiChoiceDialog(G2frame,'Select more variables:'+legend,FrstVarb+' and:',atchoice)
1088        else:
1089            dlg = wx.MultiChoiceDialog(G2frame,'Select more variables:'+legend,FrstVarb+' and:',varList)
1090        varbs = [FrstVarb,]
1091        if dlg.ShowModal() == wx.ID_OK:
1092            sel = dlg.GetSelections()
1093            for x in sel:
1094                varbs.append(varList[x])
1095        dlg.Destroy()
1096        if len(varbs) > 1:
1097            if 'equivalence' in constType:
1098                constr = []
1099                for item in varbs[1:]:
1100                    constr += [[[1.0,FrstVarb],[-1.0,item],None,None],]
1101                return constr           #multiple constraints
1102            elif 'function' in constType:
1103                constr = map(list,zip([1.0 for i in range(len(varbs))],varbs))
1104                return [constr+[0.0,False]]         #just one constraint
1105            else:       #'constraint'
1106                constr = map(list,zip([1.0 for i in range(len(varbs))],varbs))
1107                return [constr+[1.0,None]]          #just one constraint - default sum to one
1108        return []
1109             
1110    def OnAddHold(event):
1111        for phase in Phases:
1112            Phase = Phases[phase]
1113            Atoms = Phase['Atoms']
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            data[choice[3]] += [[[0.0,FrstVarb],None,None],]
1126        dlg.Destroy()
1127        choice[4]()
1128       
1129    def OnAddEquivalence(event):
1130        constr = []
1131        page = G2frame.Page
1132        choice = scope[page[1]]
1133        if page[1] == 'phs':
1134            atchoice = [item+' for '+phaseAtNames[item] for item in choice[2]]
1135            dlg = wx.SingleChoiceDialog(G2frame,'Select 1st variable:'+choice[1],choice[0],atchoice)
1136        else:   
1137            dlg = wx.SingleChoiceDialog(G2frame,'Select 1st variable:'+choice[1],choice[0],choice[2])
1138        if dlg.ShowModal() == wx.ID_OK:
1139            sel = dlg.GetSelection()
1140            FrstVarb = choice[2][sel]
1141            moreVarb = FindEquivVarb(FrstVarb,choice[2])
1142            constr = SelectVarbs(page,FrstVarb,moreVarb,choice[1],'equivalence')
1143            if len(constr) > 0:
1144                data[choice[3]] += constr
1145        dlg.Destroy()
1146        choice[4]()
1147   
1148    def OnAddFunction(event):
1149        constr = []
1150        page = G2frame.Page
1151        choice = scope[page[1]]
1152        if page[1] == 'phs':
1153            atchoice = [item+' for '+phaseAtNames[item] for item in choice[2]]
1154            dlg = wx.SingleChoiceDialog(G2frame,'Select 1st variable:'+choice[1],choice[0],atchoice)
1155        else:   
1156            dlg = wx.SingleChoiceDialog(G2frame,'Select 1st variable:'+choice[1],choice[0],choice[2])
1157        if dlg.ShowModal() == wx.ID_OK:
1158            sel = dlg.GetSelection()
1159            FrstVarb = choice[2][sel]
1160            moreVarb = FindEquivVarb(FrstVarb,choice[2])
1161            constr = SelectVarbs(page,FrstVarb,moreVarb,choice[1],'function')
1162            if len(constr) > 0:
1163                data[choice[3]] += constr
1164        dlg.Destroy()
1165        choice[4]()
1166                       
1167    def OnAddConstraint(event):
1168        constr = []
1169        page = G2frame.Page
1170        choice = scope[page[1]]
1171        if page[1] == 'phs':
1172            atchoice = [item+' for '+phaseAtNames[item] for item in choice[2]]
1173            dlg = wx.SingleChoiceDialog(G2frame,'Select 1st variable:'+choice[1],choice[0],atchoice)
1174        else:   
1175            dlg = wx.SingleChoiceDialog(G2frame,'Select 1st variable:'+choice[1],choice[0],choice[2])
1176        if dlg.ShowModal() == wx.ID_OK:
1177            sel = dlg.GetSelection()
1178            FrstVarb = choice[2][sel]
1179            moreVarb = FindEquivVarb(FrstVarb,choice[2])
1180            constr = SelectVarbs(page,FrstVarb,moreVarb,choice[1],'constraint')
1181            if len(constr) > 0:
1182                data[choice[3]] += constr
1183        dlg.Destroy()
1184        choice[4]()
1185                       
1186    def ConstSizer(name,pageDisplay):
1187        constSizer = wx.FlexGridSizer(1,4,0,0)
1188        for Id,item in enumerate(data[name]):
1189            constDel = wx.Button(pageDisplay,-1,'Delete',style=wx.BU_EXACTFIT)
1190            constDel.Bind(wx.EVT_BUTTON,OnConstDel)
1191            Indx[constDel.GetId()] = [Id,name]
1192            if len(item) < 4:
1193                constSizer.Add((5,5),0)
1194                constSizer.Add(constDel)
1195                eqString = ' FIXED   '+item[0][1]+'   '
1196            else:
1197                constEdit = wx.Button(pageDisplay,-1,'Edit',style=wx.BU_EXACTFIT)
1198                constEdit.Bind(wx.EVT_BUTTON,OnConstEdit)
1199                Indx[constEdit.GetId()] = [Id,name]
1200                constSizer.Add(constEdit)           
1201                constSizer.Add(constDel)
1202                if isinstance(item[-1],bool):
1203                    eqString = ' FUNCT   '
1204                elif isinstance(item[-2],float):
1205                    eqString = ' CONSTR  '
1206                else:
1207                    eqString = ' EQUIV   '
1208                for term in item[:-2]:
1209                    eqString += '%+.3f*%s '%(term[0],term[1])
1210                if isinstance(item[-2],float):
1211                    eqString += ' = %.3f'%(item[-2])+'  '
1212                else:
1213                    eqString += ' = 0   '
1214            constSizer.Add(wx.StaticText(pageDisplay,-1,eqString),0,wx.ALIGN_CENTER_VERTICAL)
1215            if isinstance(item[-1],bool):
1216                constRef = wx.CheckBox(pageDisplay,-1,label=' Refine?')                   
1217                constRef.SetValue(item[-1])
1218                constRef.Bind(wx.EVT_CHECKBOX,OnConstRef)
1219                Indx[constRef.GetId()] = item
1220                constSizer.Add(constRef,0,wx.ALIGN_CENTER_VERTICAL)
1221            else:
1222                constSizer.Add((5,5),0)
1223        return constSizer
1224               
1225    def OnConstRef(event):
1226        Obj = event.GetEventObject()
1227        Indx[Obj.GetId()][-1] = Obj.GetValue()
1228       
1229    def OnConstDel(event):
1230        Obj = event.GetEventObject()
1231        Id,name = Indx[Obj.GetId()]
1232        del(data[name][Id])
1233        OnPageChanged(None)       
1234       
1235    def OnConstEdit(event):
1236        Obj = event.GetEventObject()
1237        Id,name = Indx[Obj.GetId()]
1238        const = data[name][Id][-2]       
1239        if isinstance(data[name][Id][-1],bool):
1240            items = data[name][Id][:-2]+[[],]
1241            constType = 'Function'
1242            extra = '; sum = new variable'
1243        elif isinstance(data[name][Id][-2],float):
1244            items = data[name][Id][:-2]+[[const,'= fixed value'],[]]
1245            constType = 'Constraint'
1246            extra = ' sum = constant'
1247        else:
1248            items = data[name][Id][:-2]+[[],]
1249            constType = 'Equivalence'
1250            extra = '; sum = 0'
1251        dlg = G2frame.SumDialog(G2frame,constType,'Enter value for each term in constraint'+extra,'',items)
1252        try:
1253            if dlg.ShowModal() == wx.ID_OK:
1254                result = dlg.GetData()
1255                if isinstance(data[name][Id][-2],float):
1256                    data[name][Id][:-2] = result[:-2]
1257                    data[name][Id][-2] = result[-2][0]
1258                else:
1259                    data[name][Id][:-2] = result[:-1]
1260        finally:
1261            dlg.Destroy()           
1262        OnPageChanged(None)                     
1263   
1264    def UpdateHAPConstr():
1265        HAPConstr.DestroyChildren()
1266        HAPDisplay = wx.Panel(HAPConstr)
1267        HAPSizer = wx.BoxSizer(wx.VERTICAL)
1268        HAPSizer.Add((5,5),0)
1269        HAPSizer.Add(ConstSizer('HAP',HAPDisplay))
1270        HAPDisplay.SetSizer(HAPSizer,True)
1271        Size = HAPSizer.GetMinSize()
1272        Size[0] += 40
1273        Size[1] = max(Size[1],250) + 20
1274        HAPDisplay.SetSize(Size)
1275        HAPConstr.SetScrollbars(10,10,Size[0]/10-4,Size[1]/10-1)
1276        Size[1] = min(Size[1],250)
1277        G2frame.dataFrame.setSizePosLeft(Size)
1278       
1279    def UpdateHistConstr():
1280        HistConstr.DestroyChildren()
1281        HistDisplay = wx.Panel(HistConstr)
1282        HistSizer = wx.BoxSizer(wx.VERTICAL)
1283        HistSizer.Add((5,5),0)       
1284        HistSizer.Add(ConstSizer('Hist',HistDisplay))
1285        HistDisplay.SetSizer(HistSizer,True)
1286        Size = HistSizer.GetMinSize()
1287        Size[0] += 40
1288        Size[1] = max(Size[1],250) + 20
1289        HistDisplay.SetSize(Size)
1290        HistConstr.SetScrollbars(10,10,Size[0]/10-4,Size[1]/10-1)
1291        Size[1] = min(Size[1],250)
1292        G2frame.dataFrame.setSizePosLeft(Size)
1293       
1294    def UpdatePhaseConstr():
1295        PhaseConstr.DestroyChildren()
1296        PhaseDisplay = wx.Panel(PhaseConstr)
1297        PhaseSizer = wx.BoxSizer(wx.VERTICAL)
1298        PhaseSizer.Add((5,5),0)       
1299        PhaseSizer.Add(ConstSizer('Phase',PhaseDisplay))
1300        PhaseDisplay.SetSizer(PhaseSizer,True)
1301        Size = PhaseSizer.GetMinSize()
1302        Size[0] += 40
1303        Size[1] = max(Size[1],250) + 20
1304        PhaseDisplay.SetSize(Size)
1305        PhaseConstr.SetScrollbars(10,10,Size[0]/10-4,Size[1]/10-1)
1306        Size[1] = min(Size[1],250)
1307        G2frame.dataFrame.setSizePosLeft(Size)
1308   
1309    def OnPageChanged(event):
1310        if event:       #page change event!
1311            page = event.GetSelection()
1312        else:
1313            page = G2frame.dataDisplay.GetSelection()
1314        oldPage = G2frame.dataDisplay.ChangeSelection(page)
1315        text = G2frame.dataDisplay.GetPageText(page)
1316        if text == 'Histogram/Phase constraints':
1317            G2frame.Page = [page,'hap']
1318            UpdateHAPConstr()
1319        elif text == 'Histogram constraints':
1320            G2frame.Page = [page,'hst']
1321            UpdateHistConstr()
1322        elif text == 'Phase constraints':
1323            G2frame.Page = [page,'phs']
1324            UpdatePhaseConstr()
1325
1326    def SetStatusLine(text):
1327        Status.SetStatusText(text)                                     
1328       
1329    plegend,hlegend,phlegend = GetPHlegends(Phases,Histograms)
1330    scope = {'hst':['Histogram variables:',hlegend,histList,'Hist',UpdateHistConstr],
1331        'hap':['HAP variables:',phlegend,hapList,'HAP',UpdateHAPConstr],
1332        'phs':['Phase variables:',plegend,phaseList,'Phase',UpdatePhaseConstr]}
1333    if G2frame.dataDisplay:
1334        G2frame.dataDisplay.Destroy()
1335    G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.ConstraintMenu)
1336    G2frame.dataFrame.SetLabel('Constraints')
1337    if not G2frame.dataFrame.GetStatusBar():
1338        Status = G2frame.dataFrame.CreateStatusBar()
1339    SetStatusLine('')
1340   
1341    G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.ConstraintMenu)
1342    G2frame.dataFrame.Bind(wx.EVT_MENU, OnAddConstraint, id=wxID_CONSTRAINTADD)
1343    G2frame.dataFrame.Bind(wx.EVT_MENU, OnAddFunction, id=wxID_FUNCTADD)
1344    G2frame.dataFrame.Bind(wx.EVT_MENU, OnAddEquivalence, id=wxID_EQUIVADD)
1345    G2frame.dataFrame.Bind(wx.EVT_MENU, OnAddHold, id=wxID_HOLDADD)
1346    G2frame.dataDisplay = GSNoteBook(parent=G2frame.dataFrame,size=G2frame.dataFrame.GetClientSize())
1347   
1348    PhaseConstr = wx.ScrolledWindow(G2frame.dataDisplay)
1349    G2frame.dataDisplay.AddPage(PhaseConstr,'Phase constraints')
1350    HAPConstr = wx.ScrolledWindow(G2frame.dataDisplay)
1351    G2frame.dataDisplay.AddPage(HAPConstr,'Histogram/Phase constraints')
1352    HistConstr = wx.ScrolledWindow(G2frame.dataDisplay)
1353    G2frame.dataDisplay.AddPage(HistConstr,'Histogram constraints')
1354    UpdatePhaseConstr()
1355
1356    G2frame.dataDisplay.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, OnPageChanged)
1357   
1358   
1359def UpdateRestraints(G2frame,data):
1360
1361    def OnAddRestraint(event):
1362        page = G2frame.dataDisplay.GetSelection()
1363        print G2frame.dataDisplay.GetPageText(page)
1364
1365    def UpdateAtomRestr():
1366        AtomRestr.DestroyChildren()
1367        dataDisplay = wx.Panel(AtomRestr)
1368        mainSizer = wx.BoxSizer(wx.VERTICAL)
1369        mainSizer.Add((5,5),0)
1370        mainSizer.Add(wx.StaticText(dataDisplay,-1,'Atom restraint data:'),0,wx.ALIGN_CENTER_VERTICAL)
1371        mainSizer.Add((5,5),0)
1372
1373
1374        dataDisplay.SetSizer(mainSizer)
1375        Size = mainSizer.Fit(G2frame.dataFrame)
1376        Size[1] += 26                           #compensate for status bar
1377        dataDisplay.SetSize(Size)
1378        G2frame.dataFrame.setSizePosLeft(Size)
1379       
1380    def UpdatePhaseRestr():
1381        PhaseRestr.DestroyChildren()
1382        dataDisplay = wx.Panel(PhaseRestr)
1383        mainSizer = wx.BoxSizer(wx.VERTICAL)
1384        mainSizer.Add((5,5),0)
1385        mainSizer.Add(wx.StaticText(dataDisplay,-1,'Phase restraint data:'),0,wx.ALIGN_CENTER_VERTICAL)
1386        mainSizer.Add((5,5),0)
1387
1388
1389        dataDisplay.SetSizer(mainSizer)
1390        Size = mainSizer.Fit(G2frame.dataFrame)
1391        Size[1] += 26                           #compensate for status bar
1392        dataDisplay.SetSize(Size)
1393        G2frame.dataFrame.setSizePosLeft(Size)
1394   
1395    def OnPageChanged(event):
1396        page = event.GetSelection()
1397        text = G2frame.dataDisplay.GetPageText(page)
1398        if text == 'Atom restraints':
1399            G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.RestraintMenu)
1400            UpdateAtomRestr()
1401        elif text == 'Phase restraints':
1402            UpdatePhaseRestr()
1403            G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.RestraintMenu)
1404        event.Skip()
1405
1406    if G2frame.dataDisplay:
1407        G2frame.dataDisplay.Destroy()
1408    G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.RestraintMenu)
1409    G2frame.dataFrame.SetLabel('restraints')
1410    G2frame.dataFrame.CreateStatusBar()
1411    G2frame.dataFrame.Bind(wx.EVT_MENU, OnAddRestraint, id=wxID_RESTRAINTADD)
1412    G2frame.dataDisplay = GSNoteBook(parent=G2frame.dataFrame,size=G2frame.dataFrame.GetClientSize())
1413   
1414    PhaseRestr = wx.ScrolledWindow(G2frame.dataDisplay)
1415    G2frame.dataDisplay.AddPage(PhaseRestr,'Phase restraints')
1416    AtomRestr = wx.ScrolledWindow(G2frame.dataDisplay)
1417    G2frame.dataDisplay.AddPage(AtomRestr,'Atom restraints')
1418    UpdatePhaseRestr()
1419#    AtomRestrData = data['AtomRestr']
1420
1421    G2frame.dataDisplay.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, OnPageChanged)       
1422             
1423def UpdateHKLControls(G2frame,data):
1424   
1425    def OnScaleSlider(event):
1426        scale = int(scaleSel.GetValue())/1000.
1427        scaleSel.SetValue(int(scale*1000.))
1428        data['Scale'] = scale*10.
1429        G2plt.PlotSngl(G2frame)
1430       
1431    def OnLayerSlider(event):
1432        layer = layerSel.GetValue()
1433        data['Layer'] = layer
1434        G2plt.PlotSngl(G2frame)
1435       
1436    def OnSelZone(event):
1437        data['Zone'] = zoneSel.GetValue()
1438        G2plt.PlotSngl(G2frame,newPlot=True)
1439       
1440    def OnSelType(event):
1441        data['Type'] = typeSel.GetValue()
1442        G2plt.PlotSngl(G2frame)
1443       
1444    def SetStatusLine():
1445        Status.SetStatusText("look at me!!!")
1446                                     
1447    if G2frame.dataDisplay:
1448        G2frame.dataDisplay.Destroy()
1449    if not G2frame.dataFrame.GetStatusBar():
1450        Status = G2frame.dataFrame.CreateStatusBar()
1451    SetStatusLine()
1452    zones = ['100','010','001']
1453    HKLmax = data['HKLmax']
1454    HKLmin = data['HKLmin']
1455    if data['ifFc']:
1456        typeChoices = ['Fosq','Fo','|DFsq|/sig','|DFsq|>sig','|DFsq|>3sig']
1457    else:
1458        typeChoices = ['Fosq','Fo']
1459    G2frame.dataDisplay = wx.Panel(G2frame.dataFrame)
1460    G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.BlankMenu)
1461    mainSizer = wx.BoxSizer(wx.VERTICAL)
1462    mainSizer.Add((5,10),0)
1463   
1464    scaleSizer = wx.BoxSizer(wx.HORIZONTAL)
1465    scaleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Scale'),0,
1466        wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
1467    scaleSel = wx.Slider(parent=G2frame.dataDisplay,maxValue=1000,minValue=100,
1468        style=wx.SL_HORIZONTAL,value=int(data['Scale']*100))
1469    scaleSizer.Add(scaleSel,1,wx.EXPAND|wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
1470    scaleSel.SetLineSize(100)
1471    scaleSel.SetPageSize(900)
1472    scaleSel.Bind(wx.EVT_SLIDER, OnScaleSlider)
1473    mainSizer.Add(scaleSizer,1,wx.EXPAND|wx.RIGHT)
1474   
1475    zoneSizer = wx.BoxSizer(wx.HORIZONTAL)
1476    zoneSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Zone  '),0,
1477        wx.ALIGN_CENTER_VERTICAL)
1478    zoneSel = wx.ComboBox(parent=G2frame.dataDisplay,value=data['Zone'],choices=['100','010','001'],
1479        style=wx.CB_READONLY|wx.CB_DROPDOWN)
1480    zoneSel.Bind(wx.EVT_COMBOBOX, OnSelZone)
1481    zoneSizer.Add(zoneSel,0,wx.ALIGN_CENTER_VERTICAL)
1482    zoneSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Plot type  '),0,
1483        wx.ALIGN_CENTER_VERTICAL)       
1484    typeSel = wx.ComboBox(parent=G2frame.dataDisplay,value=data['Type'],choices=typeChoices,
1485        style=wx.CB_READONLY|wx.CB_DROPDOWN)
1486    typeSel.Bind(wx.EVT_COMBOBOX, OnSelType)
1487    zoneSizer.Add(typeSel,0,wx.ALIGN_CENTER_VERTICAL)
1488    zoneSizer.Add((10,0),0)   
1489    mainSizer.Add(zoneSizer,1,wx.EXPAND|wx.RIGHT)
1490       
1491    izone = zones.index(data['Zone'])
1492    layerSizer = wx.BoxSizer(wx.HORIZONTAL)
1493    layerSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Layer'),0,
1494        wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
1495    layerSel = wx.Slider(parent=G2frame.dataDisplay,maxValue=HKLmax[izone],minValue=HKLmin[izone],
1496        style=wx.SL_HORIZONTAL|wx.SL_AUTOTICKS|wx.SL_LABELS,value=0)
1497    layerSel.SetLineSize(1)
1498    layerSel.SetLineSize(5)
1499    layerSel.Bind(wx.EVT_SLIDER, OnLayerSlider)   
1500    layerSizer.Add(layerSel,1,wx.EXPAND|wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
1501    layerSizer.Add((10,0),0)   
1502    mainSizer.Add(layerSizer,1,wx.EXPAND|wx.RIGHT)
1503
1504       
1505    mainSizer.Layout()   
1506    G2frame.dataDisplay.SetSizer(mainSizer)
1507    G2frame.dataDisplay.SetSize(mainSizer.Fit(G2frame.dataFrame))
1508    G2frame.dataFrame.setSizePosLeft(mainSizer.Fit(G2frame.dataFrame))
1509
1510def GetPatternTreeDataNames(G2frame,dataTypes):
1511    names = []
1512    item, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root)       
1513    while item:
1514        name = G2frame.PatternTree.GetItemText(item)
1515        if name[:4] in dataTypes:
1516            names.append(name)
1517        item, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie)
1518    return names
1519                         
1520def GetPatternTreeItemId(G2frame, parentId, itemText):
1521    item, cookie = G2frame.PatternTree.GetFirstChild(parentId)
1522    while item:
1523        if G2frame.PatternTree.GetItemText(item) == itemText:
1524            return item
1525        item, cookie = G2frame.PatternTree.GetNextChild(parentId, cookie)
1526    return 0               
1527
1528def MovePatternTreeToGrid(G2frame,item):
1529   
1530#    print G2frame.PatternTree.GetItemText(item)
1531   
1532    oldPage = 0
1533    if G2frame.dataFrame:
1534        G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.BlankMenu)
1535        if G2frame.dataFrame.GetLabel() == 'Comments':
1536            data = [G2frame.dataDisplay.GetValue()]
1537            G2frame.dataDisplay.Clear() 
1538            Id = GetPatternTreeItemId(G2frame,G2frame.root, 'Comments')
1539            if Id: G2frame.PatternTree.SetItemPyData(Id,data)
1540        elif G2frame.dataFrame.GetLabel() == 'Notebook':
1541            data = [G2frame.dataDisplay.GetValue()]
1542            G2frame.dataDisplay.Clear() 
1543            Id = GetPatternTreeItemId(G2frame,G2frame.root, 'Notebook')
1544            if Id: G2frame.PatternTree.SetItemPyData(Id,data)
1545        elif 'Phase Data for' in G2frame.dataFrame.GetLabel():
1546            if G2frame.dataDisplay: 
1547                oldPage = G2frame.dataDisplay.GetSelection()
1548        G2frame.dataFrame.Clear()
1549        G2frame.dataFrame.SetLabel('')
1550    else:
1551        #create the frame for the data item window
1552        G2frame.dataFrame = DataFrame(parent=G2frame.mainPanel)
1553
1554    G2frame.dataFrame.Raise()           
1555    G2frame.PickId = 0
1556    parentID = G2frame.root
1557    G2frame.ExportPattern.Enable(False)
1558    defWid = [250,150]
1559    if item != G2frame.root:
1560        parentID = G2frame.PatternTree.GetItemParent(item)
1561    if G2frame.PatternTree.GetItemParent(item) == G2frame.root:
1562        G2frame.PatternId = item
1563        G2frame.PickId = item
1564        if G2frame.PatternTree.GetItemText(item) == 'Notebook':
1565            G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.DataNotebookMenu)
1566            G2frame.PatternId = 0
1567            G2frame.ExportPattern.Enable(False)
1568            data = G2frame.PatternTree.GetItemPyData(item)
1569            UpdateNotebook(G2frame,data)
1570        elif G2frame.PatternTree.GetItemText(item) == 'Controls':
1571            G2frame.PatternId = 0
1572            G2frame.ExportPattern.Enable(False)
1573            data = G2frame.PatternTree.GetItemPyData(item)
1574            if not data:           #fill in defaults
1575                data = {
1576                    #least squares controls
1577                    'deriv type':'analytic Jacobian','min dM/M':0.0001,'shift factor':1.0,'max cyc':3,
1578                    #Fourier controls
1579                    'mapType':'Fobs','d-max':100.,'d-min':0.2,'histograms':[],
1580                    'stepSize':[0.5,0.5,0.5],'minX':[0.,0.,0.],'maxX':[1.0,1.0,1.0],
1581                    #distance/angle controls
1582                    'distMax':0.0,'angleMax':0.0,'useMapPeaks':False}
1583                G2frame.PatternTree.SetItemPyData(item,data)                             
1584            G2frame.Refine.Enable(True)
1585            G2frame.SeqRefine.Enable(True)
1586            UpdateControls(G2frame,data)
1587        elif G2frame.PatternTree.GetItemText(item) == 'Sequental results':
1588            data = G2frame.PatternTree.GetItemPyData(item)
1589            UpdateSeqResults(G2frame,data)           
1590        elif G2frame.PatternTree.GetItemText(item) == 'Covariance':
1591            data = G2frame.PatternTree.GetItemPyData(item)
1592            G2frame.dataFrame.setSizePosLeft(defWid)
1593            wx.TextCtrl(parent=G2frame.dataFrame,size=G2frame.dataFrame.GetClientSize(),
1594                        value='See plot window for covariance display')
1595            G2plt.PlotCovariance(G2frame)
1596        elif G2frame.PatternTree.GetItemText(item) == 'Constraints':
1597            data = G2frame.PatternTree.GetItemPyData(item)
1598            UpdateConstraints(G2frame,data)
1599        elif G2frame.PatternTree.GetItemText(item) == 'Restraints':
1600            data = G2frame.PatternTree.GetItemPyData(item)
1601            UpdateRestraints(G2frame,data)
1602        elif 'IMG' in G2frame.PatternTree.GetItemText(item):
1603            G2frame.Image = item
1604            G2plt.PlotImage(G2frame,newPlot=True)
1605        elif 'PKS' in G2frame.PatternTree.GetItemText(item):
1606            G2plt.PlotPowderLines(G2frame)
1607        elif 'PWDR' in G2frame.PatternTree.GetItemText(item):
1608            G2frame.ExportPattern.Enable(True)
1609            G2frame.dataFrame.setSizePosLeft(defWid)
1610            wx.TextCtrl(parent=G2frame.dataFrame,size=G2frame.dataFrame.GetClientSize(),
1611                style=wx.TE_MULTILINE,
1612                value='See plot window for powder data display\nor select a data item in histogram')
1613            G2plt.PlotPatterns(G2frame,newPlot=True)
1614        elif 'HKLF' in G2frame.PatternTree.GetItemText(item):
1615            G2frame.Sngl = item
1616            G2plt.PlotSngl(G2frame,newPlot=True)
1617        elif 'PDF' in G2frame.PatternTree.GetItemText(item):
1618            G2frame.PatternId = item
1619            G2frame.ExportPDF.Enable(True)
1620            G2plt.PlotISFG(G2frame,type='S(Q)')
1621        elif G2frame.PatternTree.GetItemText(item) == 'Phases':
1622            G2frame.dataFrame.setSizePosLeft(defWid)
1623            wx.TextCtrl(parent=G2frame.dataFrame,size=G2frame.dataFrame.GetClientSize(),
1624                value='Select one phase to see its parameters')           
1625    elif 'I(Q)' in G2frame.PatternTree.GetItemText(item):
1626        G2frame.PickId = item
1627        G2frame.PatternId = G2frame.PatternTree.GetItemParent(item)
1628        G2plt.PlotISFG(G2frame,type='I(Q)',newPlot=True)
1629    elif 'S(Q)' in G2frame.PatternTree.GetItemText(item):
1630        G2frame.PickId = item
1631        G2frame.PatternId = G2frame.PatternTree.GetItemParent(item)
1632        G2plt.PlotISFG(G2frame,type='S(Q)',newPlot=True)
1633    elif 'F(Q)' in G2frame.PatternTree.GetItemText(item):
1634        G2frame.PickId = item
1635        G2frame.PatternId = G2frame.PatternTree.GetItemParent(item)
1636        G2plt.PlotISFG(G2frame,type='F(Q)',newPlot=True)
1637    elif 'G(R)' in G2frame.PatternTree.GetItemText(item):
1638        G2frame.PickId = item
1639        G2frame.PatternId = G2frame.PatternTree.GetItemParent(item)
1640        G2plt.PlotISFG(G2frame,type='G(R)',newPlot=True)           
1641    elif G2frame.PatternTree.GetItemText(parentID) == 'Phases':
1642        G2frame.PickId = item
1643        data = G2frame.PatternTree.GetItemPyData(item)           
1644        G2phG.UpdatePhaseData(G2frame,item,data,oldPage)
1645    elif G2frame.PatternTree.GetItemText(item) == 'Comments':
1646        G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.DataCommentsMenu)
1647        G2frame.PatternId = G2frame.PatternTree.GetItemParent(item)
1648        G2frame.PickId = item
1649        data = G2frame.PatternTree.GetItemPyData(item)
1650        UpdateComments(G2frame,data)
1651    elif G2frame.PatternTree.GetItemText(item) == 'Image Controls':
1652        G2frame.dataFrame.SetTitle('Image Controls')
1653        G2frame.PickId = item
1654        G2frame.Image = G2frame.PatternTree.GetItemParent(item)
1655        masks = G2frame.PatternTree.GetItemPyData(
1656            GetPatternTreeItemId(G2frame,G2frame.Image, 'Masks'))
1657        data = G2frame.PatternTree.GetItemPyData(item)
1658        G2imG.UpdateImageControls(G2frame,data,masks)
1659        G2plt.PlotImage(G2frame)
1660    elif G2frame.PatternTree.GetItemText(item) == 'Masks':
1661        G2frame.dataFrame.SetTitle('Masks')
1662        G2frame.PickId = item
1663        G2frame.Image = G2frame.PatternTree.GetItemParent(item)
1664        data = G2frame.PatternTree.GetItemPyData(item)
1665        G2imG.UpdateMasks(G2frame,data)
1666        G2plt.PlotImage(G2frame)
1667    elif G2frame.PatternTree.GetItemText(item) == 'HKL Plot Controls':
1668        G2frame.PickId = item
1669        G2frame.Sngl = G2frame.PatternTree.GetItemParent(item)
1670        data = G2frame.PatternTree.GetItemPyData(item)
1671        UpdateHKLControls(G2frame,data)
1672        G2plt.PlotSngl(G2frame)
1673    elif G2frame.PatternTree.GetItemText(item) == 'PDF Controls':
1674        G2frame.PatternId = G2frame.PatternTree.GetItemParent(item)
1675        G2frame.ExportPDF.Enable(True)
1676        G2frame.PickId = item
1677        data = G2frame.PatternTree.GetItemPyData(item)
1678        G2pdG.UpdatePDFGrid(G2frame,data)
1679        G2plt.PlotISFG(G2frame,type='I(Q)')
1680        G2plt.PlotISFG(G2frame,type='S(Q)')
1681        G2plt.PlotISFG(G2frame,type='F(Q)')
1682        G2plt.PlotISFG(G2frame,type='G(R)')
1683    elif G2frame.PatternTree.GetItemText(item) == 'Peak List':
1684        G2frame.PatternId = G2frame.PatternTree.GetItemParent(item)
1685        G2frame.ExportPeakList.Enable(True)
1686        G2frame.PickId = item
1687        data = G2frame.PatternTree.GetItemPyData(item)
1688        G2pdG.UpdatePeakGrid(G2frame,data)
1689        G2plt.PlotPatterns(G2frame)
1690    elif G2frame.PatternTree.GetItemText(item) == 'Background':
1691        G2frame.PatternId = G2frame.PatternTree.GetItemParent(item)
1692        G2frame.PickId = item
1693        data = G2frame.PatternTree.GetItemPyData(item)
1694        G2pdG.UpdateBackground(G2frame,data)
1695        G2plt.PlotPatterns(G2frame)
1696    elif G2frame.PatternTree.GetItemText(item) == 'Limits':
1697        G2frame.PatternId = G2frame.PatternTree.GetItemParent(item)
1698        G2frame.PickId = item
1699        data = G2frame.PatternTree.GetItemPyData(item)
1700        G2pdG.UpdateLimitsGrid(G2frame,data)
1701        G2plt.PlotPatterns(G2frame)
1702    elif G2frame.PatternTree.GetItemText(item) == 'Instrument Parameters':
1703        G2frame.PatternId = G2frame.PatternTree.GetItemParent(item)
1704        G2frame.PickId = item
1705        data = G2frame.PatternTree.GetItemPyData(item)
1706        G2pdG.UpdateInstrumentGrid(G2frame,data)
1707        G2plt.PlotPeakWidths(G2frame)
1708    elif G2frame.PatternTree.GetItemText(item) == 'Sample Parameters':
1709        G2frame.PatternId = G2frame.PatternTree.GetItemParent(item)
1710        G2frame.PickId = item
1711        data = G2frame.PatternTree.GetItemPyData(item)
1712
1713        if 'Temperature' not in data:           #temp fix for old gpx files
1714            data = {'Scale':[1.0,True],'Type':'Debye-Scherrer','Absorption':[0.0,False],'DisplaceX':[0.0,False],
1715                'DisplaceY':[0.0,False],'Diffuse':[],'Temperature':300.,'Pressure':1.0,'Humidity':0.0,'Voltage':0.0,
1716                'Force':0.0,'Gonio. radius':200.0}
1717            G2frame.PatternTree.SetItemPyData(item,data)
1718   
1719        G2pdG.UpdateSampleGrid(G2frame,data)
1720        G2plt.PlotPatterns(G2frame)
1721    elif G2frame.PatternTree.GetItemText(item) == 'Index Peak List':
1722        G2frame.PatternId = G2frame.PatternTree.GetItemParent(item)
1723        G2frame.ExportPeakList.Enable(True)
1724        G2frame.PickId = item
1725        data = G2frame.PatternTree.GetItemPyData(item)
1726        G2pdG.UpdateIndexPeaksGrid(G2frame,data)
1727        if 'PKS' in G2frame.PatternTree.GetItemText(G2frame.PatternId):
1728            G2plt.PlotPowderLines(G2frame)
1729        else:
1730            G2plt.PlotPatterns(G2frame)
1731    elif G2frame.PatternTree.GetItemText(item) == 'Unit Cells List':
1732        G2frame.PatternId = G2frame.PatternTree.GetItemParent(item)
1733        G2frame.PickId = item
1734        data = G2frame.PatternTree.GetItemPyData(item)
1735        if not data:
1736            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
1737            data.append([0,0,0,0,0,0,0,0,0,0,0,0,0,0])      #Bravais lattice flags
1738            data.append([])                                 #empty cell list
1739            data.append([])                                 #empty dmin
1740            G2frame.PatternTree.SetItemPyData(item,data)                             
1741        G2pdG.UpdateUnitCellsGrid(G2frame,data)
1742        if 'PKS' in G2frame.PatternTree.GetItemText(G2frame.PatternId):
1743            G2plt.PlotPowderLines(G2frame)
1744        else:
1745            G2plt.PlotPatterns(G2frame)
1746    elif G2frame.PatternTree.GetItemText(item) == 'Reflection Lists':
1747        G2frame.PatternId = G2frame.PatternTree.GetItemParent(item)
1748        G2frame.PickId = item
1749        data = G2frame.PatternTree.GetItemPyData(item)
1750        G2frame.RefList = ''
1751        if len(data):
1752            G2frame.RefList = data.keys()[0]
1753        G2pdG.UpdateReflectionGrid(G2frame,data)
1754        G2plt.PlotPatterns(G2frame)
Note: See TracBrowser for help on using the repository browser.