source: trunk/GSASIIpwdGUI.py @ 1249

Last change on this file since 1249 was 1249, checked in by vondreele, 8 years ago

include the 'sky' parameter in MaxEnt?; scale it by Scale & Contrast - makes it more universal.
Reorder the opus & tropus routines back to original definitions as per Pete J.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Author Revision URL Id
File size: 146.0 KB
Line 
1# -*- coding: utf-8 -*-
2#GSASIIpwdGUI - powder data display routines
3########### SVN repository information ###################
4# $Date: 2014-03-14 16:18:21 +0000 (Fri, 14 Mar 2014) $
5# $Author: vondreele $
6# $Revision: 1249 $
7# $URL: trunk/GSASIIpwdGUI.py $
8# $Id: GSASIIpwdGUI.py 1249 2014-03-14 16:18:21Z vondreele $
9########### SVN repository information ###################
10'''
11*GSASIIpwdGUI: Powder Pattern GUI routines*
12-------------------------------------------
13
14Used to define GUI controls for the routines that interact
15with the powder histogram (PWDR) data tree items.
16
17'''
18import sys
19import os.path
20import wx
21import wx.grid as wg
22import wx.lib.scrolledpanel as wxscroll
23import numpy as np
24import numpy.ma as ma
25import math
26import time
27import copy
28import random as ran
29import cPickle
30import GSASIIpath
31GSASIIpath.SetVersionNumber("$Revision: 1249 $")
32import GSASIImath as G2mth
33import GSASIIpwd as G2pwd
34import GSASIIIO as G2IO
35import GSASIIlattice as G2lat
36import GSASIIspc as G2spc
37import GSASIIindex as G2indx
38import GSASIIplot as G2plt
39import GSASIIgrid as G2gd
40import GSASIIElemGUI as G2elemGUI
41import GSASIIElem as G2elem
42import GSASIIsasd as G2sasd
43VERY_LIGHT_GREY = wx.Colour(235,235,235)
44WACV = wx.ALIGN_CENTER_VERTICAL
45# trig functions in degrees
46sind = lambda x: math.sin(x*math.pi/180.)
47tand = lambda x: math.tan(x*math.pi/180.)
48cosd = lambda x: math.cos(x*math.pi/180.)
49asind = lambda x: 180.*math.asin(x)/math.pi
50   
51def IsHistogramInAnyPhase(G2frame,histoName):
52    'Needs a doc string'
53    phases = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,'Phases')
54    if phases:
55        item, cookie = G2frame.PatternTree.GetFirstChild(phases)
56        while item:
57            data = G2frame.PatternTree.GetItemPyData(item)
58            histoList = data['Histograms'].keys()
59            if histoName in histoList:
60                return True
61            item, cookie = G2frame.PatternTree.GetNextChild(phases, cookie)
62        return False
63    else:
64        return False
65
66def SetDefaultSample():
67    'Fills in default items for the Sample dictionary'
68    return {
69        'InstrName':'',
70        'ranId':ran.randint(0,sys.maxint),
71        'Scale':[1.0,True],'Type':'Debye-Scherrer','Absorption':[0.0,False],
72        'DisplaceX':[0.0,False],'DisplaceY':[0.0,False],'Diffuse':[],
73        'Temperature':300.,'Pressure':0.1,
74        'FreePrm1':0.,'FreePrm2':0.,'FreePrm3':0.,
75        'Gonio. radius':200.0,
76        'Omega':0.0,'Chi':0.0,'Phi':0.0,
77#SASD items
78        'Materials':[{'Name':'vacuum','VolFrac':1.0,},{'Name':'vacuum','VolFrac':0.0,}],
79        'Thick':1.0,'Contrast':[0.0,0.0],       #contrast & anomalous contrast
80        'Trans':1.0,                            #measured transmission
81        }
82       
83def SetDefaultSASDModel():
84    'Fills in default items for the SASD Models dictionary'   
85    return {'Back':[0.0,False],'Size':{'MinDiam':50,'MaxDiam':10000,'Nbins':100,
86        'logBins':True,'Method':'MaxEnt','Distribution':[],
87        'Shape':['Spheroid',1.0],'MaxEnt':{'Niter':100,'Precision':0.01,'Sky':-6},
88        'IPG':{'Niter':100,'Approach':0.8},'Reg':{},},           
89        'Unified':{'Levels':[],},           
90        'Particle':{'Levels':[],},
91        'Current':'Size dist.',
92        }
93       
94def SetDefaultSubstances():
95    'Fills in default items for the SASD Substances dictionary'
96    return {'Substances':{'vacuum':{'Elements':{},'Volume':1.0,'Density':0.0,'Scatt density':0.0}}}
97                         
98################################################################################
99#####  Powder Peaks
100################################################################################           
101       
102def UpdatePeakGrid(G2frame, data):
103    '''respond to selection of PWDR powder peaks data tree item.
104    '''
105    if G2frame.dataDisplay:
106        G2frame.dataFrame.Clear()
107       
108    def OnAutoSearch(event):
109        PatternId = G2frame.PatternId
110        PickId = G2frame.PickId
111        limits = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Limits'))[1]
112        inst,inst2 = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Instrument Parameters'))
113        profile = G2frame.PatternTree.GetItemPyData(PatternId)[1]
114        x0 = profile[0]
115        iBeg = np.searchsorted(x0,limits[0])
116        iFin = np.searchsorted(x0,limits[1])
117        x = x0[iBeg:iFin]
118        y0 = profile[1][iBeg:iFin]
119        y1 = copy.copy(y0)
120        ysig = np.std(y1)
121        offset = [-1,1]
122        ymask = ma.array(y0,mask=(y0<ysig))
123        for off in offset:
124            ymask = ma.array(ymask,mask=(ymask-np.roll(y0,off)<=0.))
125        indx = ymask.nonzero()
126        mags = ymask[indx]
127        poss = x[indx]
128        refs = zip(poss,mags)
129        refs = G2mth.sortArray(refs,0,reverse=True)
130        for i,ref1 in enumerate(refs):
131            for ref2 in refs[i+1:]:
132                if abs(ref2[0]-ref1[0]) < 0.1*G2pwd.getFWHM(ref1[0],inst):
133                    del(refs[i])   
134        refs = G2mth.sortArray(refs,1,reverse=True)
135        for pos,mag in refs:
136            data.append(G2mth.setPeakparms(inst,inst2,pos,mag))
137        UpdatePeakGrid(G2frame,data)
138        G2plt.PlotPatterns(G2frame,plotType='PWDR')       
139   
140    def OnUnDo(event):
141        DoUnDo()
142        G2frame.dataFrame.UnDo.Enable(False)
143       
144    def DoUnDo():
145        print 'Undo last refinement'
146        file = open(G2frame.undofile,'rb')
147        PatternId = G2frame.PatternId
148        for item in ['Background','Instrument Parameters','Peak List']:
149            G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, item),cPickle.load(file))
150            if G2frame.dataDisplay.GetName() == item:
151                if item == 'Background':
152                    UpdateBackground(G2frame,G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, item)))
153                elif item == 'Instrument Parameters':
154                    UpdateInstrumentGrid(G2frame,G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, item)))
155                elif item == 'Peak List':
156                    UpdatePeakGrid(G2frame,G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, item)))
157            print item,' recovered'
158        file.close()
159       
160    def SaveState():
161        G2frame.undofile = os.path.join(G2frame.dirname,'GSASII.save')
162        file = open(G2frame.undofile,'wb')
163        PatternId = G2frame.PatternId
164        for item in ['Background','Instrument Parameters','Peak List']:
165            cPickle.dump(G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId,item)),file,1)
166        file.close()
167        G2frame.dataFrame.UnDo.Enable(True)
168       
169    def OnLSQPeakFit(event):
170        if not G2frame.GSASprojectfile:            #force a save of the gpx file so SaveState can wirte in the same directory
171            G2frame.OnFileSaveas(event)
172        OnPeakFit('LSQ')
173       
174    def OnOneCycle(event):
175        OnPeakFit('LSQ',oneCycle=True)
176       
177    def OnClearPeaks(event):
178        dlg = wx.MessageDialog(G2frame,'Delete all peaks?','Clear peak list',wx.OK|wx.CANCEL)
179        try:
180            if dlg.ShowModal() == wx.ID_OK:
181                peaks = []
182        finally:
183            dlg.Destroy()
184        UpdatePeakGrid(G2frame,peaks)
185        G2plt.PlotPatterns(G2frame,plotType='PWDR')
186       
187    def OnPeakFit(FitPgm,oneCycle=False):
188        SaveState()
189        controls = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.root, 'Controls'))
190        if not controls:
191            controls = {'deriv type':'analytic','min dM/M':0.0001,}     #fill in defaults if needed
192        print 'Peak Fitting with '+controls['deriv type']+' derivatives:'
193        PatternId = G2frame.PatternId
194        PickId = G2frame.PickId
195        peaks = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Peak List'))
196        if not peaks:
197            G2frame.ErrorDialog('No peaks!','Nothing to fit!')
198            return
199        background = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Background'))
200        limits = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Limits'))[1]
201        inst,inst2 = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Instrument Parameters'))
202        data = G2frame.PatternTree.GetItemPyData(PatternId)[1]
203        wx.BeginBusyCursor()
204        dlg = wx.ProgressDialog('Residual','Peak fit Rwp = ',101.0, 
205            style = wx.PD_ELAPSED_TIME|wx.PD_AUTO_HIDE|wx.PD_REMAINING_TIME|wx.PD_CAN_ABORT)
206        screenSize = wx.ClientDisplayRect()
207        Size = dlg.GetSize()
208        dlg.SetPosition(wx.Point(screenSize[2]-Size[0]-305,screenSize[1]+5))
209        try:
210            G2pwd.DoPeakFit(FitPgm,peaks,background,limits,inst,inst2,data,oneCycle,controls,dlg)
211        finally:
212            wx.EndBusyCursor()   
213        UpdatePeakGrid(G2frame,peaks)
214        G2plt.PlotPatterns(G2frame,plotType='PWDR')
215        print 'finished'
216        return
217       
218    def OnResetSigGam(event):
219        PatternId = G2frame.PatternId
220        PickId = G2frame.PickId
221        Inst,Inst2 = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Instrument Parameters'))
222        peaks = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Peak List'))
223        if not peaks:
224            G2frame.ErrorDialog('No peaks!','Nothing to do!')
225            return
226        newpeaks = []
227        for peak in peaks:
228            newpeaks.append(G2mth.setPeakparms(Inst,Inst2,peak[0],peak[2]))
229        G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Peak List'),newpeaks)
230        UpdatePeakGrid(G2frame,newpeaks)
231               
232    def RefreshPeakGrid(event):
233        r,c =  event.GetRow(),event.GetCol()
234       
235        event.StopPropagation()
236        data = G2frame.PeakTable.GetData()
237        T = []
238        for peak in data:T.append(peak[0])
239        D = dict(zip(T,data))
240        T.sort()
241        X = []
242        for key in T: X.append(D[key])
243        data = X       
244       
245    def setBackgroundColors():
246       for r in range(G2frame.dataDisplay.GetNumberRows()):
247           for c in range(G2frame.dataDisplay.GetNumberCols()):
248               if G2frame.dataDisplay.GetColLabelValue(c) in ['position','intensity','alpha','beta','sigma','gamma']:
249                   if float(G2frame.dataDisplay.GetCellValue(r,c)) < 0.:
250                       G2frame.dataDisplay.SetCellBackgroundColour(r,c,wx.RED)
251                   else:
252                       G2frame.dataDisplay.SetCellBackgroundColour(r,c,wx.WHITE)
253                                                 
254    def KeyEditPeakGrid(event):
255        rowList = G2frame.dataDisplay.GetSelectedRows()
256        colList = G2frame.dataDisplay.GetSelectedCols()
257        selectList = G2frame.dataDisplay.GetSelectedCells()
258        data = G2frame.PatternTree.GetItemPyData(G2frame.PickId)
259        if event.GetKeyCode() == wx.WXK_RETURN:
260            event.Skip(True)
261        elif event.GetKeyCode() == wx.WXK_CONTROL:
262            event.Skip(True)
263        elif event.GetKeyCode() == wx.WXK_SHIFT:
264            event.Skip(True)
265        elif rowList:
266            G2frame.dataDisplay.ClearSelection()
267            if event.GetKeyCode() == wx.WXK_DELETE:
268                G2frame.dataDisplay.ClearGrid()
269                rowList.sort()
270                rowList.reverse()
271                nDel = 0
272                for row in rowList:
273                    G2frame.PeakTable.DeleteRow(row)
274                    nDel += 1
275                if nDel:
276                    msg = wg.GridTableMessage(G2frame.PeakTable, 
277                        wg.GRIDTABLE_NOTIFY_ROWS_DELETED,0,nDel)
278                    G2frame.dataDisplay.ProcessTableMessage(msg)
279                data = G2frame.PeakTable.GetData()
280                G2frame.PatternTree.SetItemPyData(G2frame.PickId,data[:-nDel])
281                G2frame.dataDisplay.ForceRefresh()
282                setBackgroundColors()
283                if not len(G2frame.PatternTree.GetItemPyData(G2frame.PickId)): 
284                    G2frame.dataFrame.PeakFit.Enable(False)
285                       
286        elif colList:
287            G2frame.dataDisplay.ClearSelection()
288            key = event.GetKeyCode()
289            for col in colList:
290                if G2frame.PeakTable.GetTypeName(0,col) == wg.GRID_VALUE_BOOL:
291                    if key == 89: #'Y'
292                        for row in range(G2frame.PeakTable.GetNumberRows()): data[row][col]=True
293                    elif key == 78:  #'N'
294                        for row in range(G2frame.PeakTable.GetNumberRows()): data[row][col]=False
295        elif selectList:
296            G2frame.dataDisplay.ClearSelection()
297            key = event.GetKeyCode()
298            for row,col in selectList:
299                if G2frame.PeakTable.GetTypeName(row,col) == wg.GRID_VALUE_BOOL:
300                    if key == 89: #'Y'
301                        data[row][col]=True
302                    elif key == 78:  #'N'
303                        data[row][col]=False
304        G2plt.PlotPatterns(G2frame,plotType='PWDR')
305           
306    G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.PeakMenu)
307    if not G2frame.dataFrame.GetStatusBar():
308        Status = G2frame.dataFrame.CreateStatusBar()
309    Status.SetStatusText('Global refine: select refine column & press Y or N')
310    G2frame.Bind(wx.EVT_MENU, OnAutoSearch, id=G2gd.wxID_AUTOSEARCH)
311    G2frame.Bind(wx.EVT_MENU, OnUnDo, id=G2gd.wxID_UNDO)
312    G2frame.Bind(wx.EVT_MENU, OnLSQPeakFit, id=G2gd.wxID_LSQPEAKFIT)
313    G2frame.Bind(wx.EVT_MENU, OnOneCycle, id=G2gd.wxID_LSQONECYCLE)
314    G2frame.Bind(wx.EVT_MENU, OnClearPeaks, id=G2gd.wxID_CLEARPEAKS)
315    G2frame.Bind(wx.EVT_MENU, OnResetSigGam, id=G2gd.wxID_RESETSIGGAM)
316    G2frame.dataFrame.PeakFit.Enable(False)
317    if data:
318        G2frame.dataFrame.PeakFit.Enable(True)
319        G2frame.dataFrame.PFOneCycle.Enable(True)
320    G2frame.PickTable = []
321    rowLabels = []
322    PatternId = G2frame.PatternId
323    Inst = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Instrument Parameters'))[0]
324    for i in range(len(data)): rowLabels.append(str(i+1))
325    if 'C' in Inst['Type'][0]:
326        colLabels = ['position','refine','intensity','refine','sigma','refine','gamma','refine']
327        Types = [wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_BOOL,
328            wg.GRID_VALUE_FLOAT+':10,1',wg.GRID_VALUE_BOOL,
329            wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_BOOL,
330            wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_BOOL]
331    else:
332        colLabels = ['position','refine','intensity','refine','alpha','refine',
333            'beta','refine','sigma','refine','gamma','refine']
334        Types = [wg.GRID_VALUE_FLOAT+':10,1',wg.GRID_VALUE_BOOL,
335            wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_BOOL,
336            wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_BOOL,
337            wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_BOOL,
338            wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_BOOL,
339            wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_BOOL]
340    T = []
341    for peak in data:
342        T.append(peak[0])
343    D = dict(zip(T,data))
344    T.sort()
345    X = []
346    for key in T: X.append(D[key])
347    data = X
348    G2frame.PatternTree.SetItemPyData(G2frame.PickId,data)
349    G2frame.PeakTable = G2gd.Table(data,rowLabels=rowLabels,colLabels=colLabels,types=Types)
350    G2frame.dataFrame.SetLabel('Peak List')
351    G2frame.dataDisplay = G2gd.GSGrid(parent=G2frame.dataFrame)
352    G2frame.dataDisplay.SetTable(G2frame.PeakTable, True)
353    setBackgroundColors()                         
354    G2frame.dataDisplay.Bind(wg.EVT_GRID_CELL_CHANGE, RefreshPeakGrid)
355    G2frame.dataDisplay.Bind(wx.EVT_KEY_DOWN, KeyEditPeakGrid)
356    G2frame.dataDisplay.SetMargins(0,0)
357    G2frame.dataDisplay.AutoSizeColumns(False)
358    G2frame.dataFrame.setSizePosLeft([535,350])
359       
360################################################################################
361#####  Background
362################################################################################           
363       
364def UpdateBackground(G2frame,data):
365    '''respond to selection of PWDR background data tree item.
366    '''
367    if len(data) < 2:       #add Debye diffuse & peaks scattering here
368        data.append({'nDebye':0,'debyeTerms':[],'nPeaks':0,'peaksList':[]})
369    if 'nPeaks' not in data[1]:
370        data[1].update({'nPeaks':0,'peaksList':[]})
371    ValObj = {}
372   
373    def OnBackFlagCopy(event):
374        flag = data[0][1]
375        backDict = data[-1]
376        if backDict['nDebye']:
377            DBflags = []
378            for term in backDict['debyeTerms']:
379                DBflags.append(term[1::2])
380        if backDict['nPeaks']:
381            PKflags = []
382            for term in backDict['peaksList']:
383                PKflags.append(term[1::2])           
384        histList = ['All',]+G2gd.GetPatternTreeDataNames(G2frame,['PWDR',])
385        copyList = []
386        dlg = wx.MultiChoiceDialog(G2frame, 
387            'Copy refinement flags to which histograms?', 'Copy flags', 
388            histList, wx.CHOICEDLG_STYLE)
389        try:
390            if dlg.ShowModal() == wx.ID_OK:
391                result = dlg.GetSelections()
392                for i in result: 
393                    copyList.append(histList[i])
394                if 'All' in copyList: 
395                    copyList = histList[1:]
396            for item in copyList:
397                Id = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,item)
398                backData = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,Id,'Background'))
399                backData[0][1] = copy.copy(flag)
400                bkDict = backData[-1]
401                if bkDict['nDebye'] == backDict['nDebye']:
402                    for i,term in enumerate(bkDict['debyeTerms']):
403                        term[1::2] = copy.copy(DBflags[i])
404                if bkDict['nPeaks'] == backDict['nPeaks']:
405                    for i,term in enumerate(bkDict['peaksList']):
406                        term[1::2] = copy.copy(PKflags[i])                   
407        finally:
408            dlg.Destroy()
409           
410    def OnBackCopy(event):
411        histList = ['All',]+G2gd.GetPatternTreeDataNames(G2frame,['PWDR',])
412        copyList = []
413        dlg = wx.MultiChoiceDialog(G2frame, 
414            'Copy parameters to which histograms?', 'Copy parameters', 
415            histList, wx.CHOICEDLG_STYLE)
416        try:
417            if dlg.ShowModal() == wx.ID_OK:
418                result = dlg.GetSelections()
419                for i in result: 
420                    copyList.append(histList[i])
421                if 'All' in copyList: 
422                    copyList = histList[1:]
423            for item in copyList:
424                Id = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,item)
425                G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,Id,'Background'),
426                    copy.copy(data))
427        finally:
428            dlg.Destroy()
429       
430    def BackSizer():
431       
432        def OnNewType(event):
433            data[0][0] = bakType.GetValue()
434           
435        def OnBakRef(event):
436            data[0][1] = bakRef.GetValue()
437           
438        def OnBakTerms(event):
439            data[0][2] = int(bakTerms.GetValue())
440            M = len(data[0])
441            N = data[0][2]+3
442            item = data[0]
443            if N > M:       #add terms
444                for i in range(M,N): 
445                    item.append(0.0)
446            elif N < M:     #delete terms
447                for i in range(N,M):
448                    del(item[-1])
449            G2frame.PatternTree.SetItemPyData(BackId,data)
450            wx.CallAfter(UpdateBackground,G2frame,data)
451           
452        def OnBakVal(event):
453            Obj = event.GetEventObject()
454            item = ValObj[Obj.GetId()][0]
455            try:
456                value = float(Obj.GetValue())
457            except ValueError:
458                value = data[0][item]
459            data[0][item] = value
460            Obj.SetValue('%10.4f'%(value))
461       
462        backSizer = wx.BoxSizer(wx.VERTICAL)
463        topSizer = wx.BoxSizer(wx.HORIZONTAL)
464        topSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' Background function: '),0,WACV)
465        bakType = wx.ComboBox(G2frame.dataDisplay,value=data[0][0],
466                choices=Choices,style=wx.CB_READONLY|wx.CB_DROPDOWN)
467        bakType.Bind(wx.EVT_COMBOBOX, OnNewType)
468        topSizer.Add(bakType)
469        topSizer.Add((5,0),0)
470        bakRef = wx.CheckBox(G2frame.dataDisplay,label=' Refine?')
471        bakRef.SetValue(bool(data[0][1]))
472        bakRef.Bind(wx.EVT_CHECKBOX, OnBakRef)
473        topSizer.Add(bakRef,0,WACV)
474        topSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' No. coeff.: '),0,WACV)
475        bakTerms = wx.ComboBox(G2frame.dataDisplay,-1,value=str(data[0][2]),choices=[str(i+1) for i in range(36)],
476            style=wx.CB_READONLY|wx.CB_DROPDOWN)
477        bakTerms.Bind(wx.EVT_COMBOBOX,OnBakTerms)
478        topSizer.Add(bakTerms,0,WACV)
479        topSizer.Add((5,0),0)
480        backSizer.Add(topSizer)
481        backSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' Background coefficients:'),0,WACV)
482        bakSizer = wx.FlexGridSizer(1,5,5,5)
483        for i,value in enumerate(data[0][3:]):
484            bakVal = wx.TextCtrl(G2frame.dataDisplay,wx.ID_ANY,'%10.4f'%(value),style=wx.TE_PROCESS_ENTER)
485            bakSizer.Add(bakVal,0,WACV)
486            ValObj[bakVal.GetId()] = [i+3]
487            bakVal.Bind(wx.EVT_TEXT_ENTER,OnBakVal)
488            bakVal.Bind(wx.EVT_KILL_FOCUS,OnBakVal)
489        backSizer.Add(bakSizer)
490        return backSizer
491       
492    def DebyeSizer():
493       
494        def OnDebTerms(event):
495            data[1]['nDebye'] = int(debTerms.GetValue())
496            M = len(data[1]['debyeTerms'])
497            N = data[1]['nDebye']
498            if N > M:       #add terms
499                for i in range(M,N): 
500                    data[1]['debyeTerms'].append([1.0,False,1.0,False,0.010,False])
501            elif N < M:     #delete terms
502                for i in range(N,M):
503                    del(data[1]['debyeTerms'][-1])
504            wx.CallAfter(UpdateBackground,G2frame,data)
505           
506        def KeyEditPeakGrid(event):
507            colList = debyeGrid.GetSelectedCols()
508            if event.GetKeyCode() == wx.WXK_RETURN:
509                event.Skip(True)
510            elif event.GetKeyCode() == wx.WXK_CONTROL:
511                event.Skip(True)
512            elif event.GetKeyCode() == wx.WXK_SHIFT:
513                event.Skip(True)
514            elif colList:
515                debyeGrid.ClearSelection()
516                key = event.GetKeyCode()
517                for col in colList:
518                    if debyeTable.GetTypeName(0,col) == wg.GRID_VALUE_BOOL:
519                        if key == 89: #'Y'
520                            for row in range(debyeGrid.GetNumberRows()): data[1]['debyeTerms'][row][col]=True
521                        elif key == 78:  #'N'
522                            for row in range(debyeGrid.GetNumberRows()): data[1]['debyeTerms'][row][col]=False
523
524       
525        debSizer = wx.BoxSizer(wx.VERTICAL)
526        topSizer = wx.BoxSizer(wx.HORIZONTAL)
527        topSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' Debye scattering: '),0,WACV)
528        topSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' No. coeff.: '),0,WACV)
529        debTerms = wx.ComboBox(G2frame.dataDisplay,-1,value=str(data[1]['nDebye']),choices=[str(i) for i in range(12)],
530            style=wx.CB_READONLY|wx.CB_DROPDOWN)
531        debTerms.Bind(wx.EVT_COMBOBOX,OnDebTerms)
532        topSizer.Add(debTerms,0,WACV)
533        topSizer.Add((5,0),0)
534        debSizer.Add(topSizer)
535        if data[1]['nDebye']:
536            debSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' Debye diffuse terms:'),0,WACV)       
537            rowLabels = []
538            for i in range(len(data[1]['debyeTerms'])): rowLabels.append(str(i))
539            colLabels = ['A','refine','R','refine','U','refine']
540            Types = [wg.GRID_VALUE_FLOAT+':10,2',wg.GRID_VALUE_BOOL,
541            wg.GRID_VALUE_FLOAT+':10,3',wg.GRID_VALUE_BOOL,
542            wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_BOOL]
543            debyeTable = G2gd.Table(data[1]['debyeTerms'],rowLabels=rowLabels,colLabels=colLabels,types=Types)
544            debyeGrid = G2gd.GSGrid(parent=G2frame.dataDisplay)
545            debyeGrid.SetTable(debyeTable, True)
546            debyeGrid.Bind(wx.EVT_KEY_DOWN, KeyEditPeakGrid)
547            debyeGrid.AutoSizeColumns(False)
548            debSizer.Add(debyeGrid)       
549        return debSizer
550     
551    def PeaksSizer():
552
553        def OnPeaks(event):
554            data[1]['nPeaks'] = int(peaks.GetValue())
555            M = len(data[1]['peaksList'])
556            N = data[1]['nPeaks']
557            if N > M:       #add terms
558                for i in range(M,N): 
559                    data[1]['peaksList'].append([1.0,False,1.0,False,0.10,False,0.10,False])
560            elif N < M:     #delete terms
561                for i in range(N,M):
562                    del(data[1]['peaksList'][-1])
563            wx.CallAfter(UpdateBackground,G2frame,data)
564           
565        def KeyEditPeakGrid(event):
566            colList = peaksGrid.GetSelectedCols()
567            if event.GetKeyCode() == wx.WXK_RETURN:
568                event.Skip(True)
569            elif event.GetKeyCode() == wx.WXK_CONTROL:
570                event.Skip(True)
571            elif event.GetKeyCode() == wx.WXK_SHIFT:
572                event.Skip(True)
573            elif colList:
574                peaksGrid.ClearSelection()
575                key = event.GetKeyCode()
576                for col in colList:
577                    if peaksTable.GetTypeName(0,col) == wg.GRID_VALUE_BOOL:
578                        if key == 89: #'Y'
579                            for row in range(peaksGrid.GetNumberRows()): data[1]['peaksList'][row][col]=True
580                        elif key == 78:  #'N'
581                            for row in range(peaksGrid.GetNumberRows()): data[1]['peaksList'][row][col]=False
582
583        peaksSizer = wx.BoxSizer(wx.VERTICAL)
584        topSizer = wx.BoxSizer(wx.HORIZONTAL)
585        topSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' Peaks in background: '),0,WACV)
586        topSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' No. peaks: '),0,WACV)
587        peaks = wx.ComboBox(G2frame.dataDisplay,-1,value=str(data[1]['nPeaks']),choices=[str(i) for i in range(12)],
588            style=wx.CB_READONLY|wx.CB_DROPDOWN)
589        peaks.Bind(wx.EVT_COMBOBOX,OnPeaks)
590        topSizer.Add(peaks,0,WACV)
591        topSizer.Add((5,0),0)
592        peaksSizer.Add(topSizer)
593        if data[1]['nPeaks']:
594            peaksSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' Peak list:'),0,WACV)       
595            rowLabels = []
596            for i in range(len(data[1]['peaksList'])): rowLabels.append(str(i))
597            colLabels = ['pos','refine','int','refine','sig','refine','gam','refine']
598            Types = [wg.GRID_VALUE_FLOAT+':10,2',wg.GRID_VALUE_BOOL,
599            wg.GRID_VALUE_FLOAT+':10,3',wg.GRID_VALUE_BOOL,
600            wg.GRID_VALUE_FLOAT+':10,3',wg.GRID_VALUE_BOOL,
601            wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_BOOL]
602            peaksTable = G2gd.Table(data[1]['peaksList'],rowLabels=rowLabels,colLabels=colLabels,types=Types)
603            peaksGrid = G2gd.GSGrid(parent=G2frame.dataDisplay)
604            peaksGrid.SetTable(peaksTable, True)
605            peaksGrid.Bind(wx.EVT_KEY_DOWN, KeyEditPeakGrid)
606            peaksGrid.AutoSizeColumns(False)
607            peaksSizer.Add(peaksGrid)       
608        return peaksSizer
609               
610    if G2frame.dataDisplay:
611#        G2frame.dataFrame.Clear()
612        G2frame.dataFrame.DestroyChildren()
613    G2frame.dataDisplay = wx.Panel(G2frame.dataFrame)
614    G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.BackMenu)
615    G2frame.dataFrame.SetLabel('Background')
616    if not G2frame.dataFrame.GetStatusBar():
617        Status = G2frame.dataFrame.CreateStatusBar()
618    G2frame.Bind(wx.EVT_MENU,OnBackCopy,id=G2gd.wxID_BACKCOPY)
619    G2frame.Bind(wx.EVT_MENU,OnBackFlagCopy,id=G2gd.wxID_BACKFLAGCOPY)
620    BackId = G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Background')
621    Choices = ['chebyschev','cosine','lin interpolate','inv interpolate','log interpolate']
622    mainSizer = wx.BoxSizer(wx.VERTICAL)
623    mainSizer.Add(BackSizer())
624    mainSizer.Add((0,5),0)
625    mainSizer.Add(DebyeSizer())
626    mainSizer.Add((0,5),0)
627    mainSizer.Add(PeaksSizer())
628    mainSizer.Layout()   
629    G2frame.dataDisplay.SetSizer(mainSizer)
630    G2frame.dataFrame.setSizePosLeft(mainSizer.Fit(G2frame.dataFrame))
631       
632################################################################################
633#####  Limits
634################################################################################           
635       
636def UpdateLimitsGrid(G2frame, data,plottype):
637    '''respond to selection of PWDR Limits data tree item.
638    '''
639    if G2frame.dataDisplay:
640        G2frame.dataFrame.Clear()
641    G2frame.ifGetExclude = False
642       
643    def KeyEditPeakGrid(event):
644        if event.GetKeyCode() == wx.WXK_DELETE:
645            row = G2frame.dataDisplay.GetSelectedRows()[0]
646            if row > 1: #can't delete limits!
647                del(data[row])
648                wx.CallAfter(UpdateLimitsGrid,G2frame,data,plottype)
649                G2plt.PlotPatterns(G2frame,plotType=plottype)
650                       
651    def RefreshLimitsGrid(event):
652        event.StopPropagation()
653        data = G2frame.LimitsTable.GetData()
654        old = data[0]
655        new = data[1]
656        new[0] = max(old[0],new[0])
657        new[1] = max(new[0],min(old[1],new[1]))
658        excl = []
659        if len(data) > 2:
660            excl = data[2:]
661            for item in excl:
662                item[0] = max(old[0],item[0])
663                item[1] = max(item[0],min(old[1],item[1]))
664        data = [old,new]+excl
665        G2frame.LimitsTable.SetData(data)
666        G2plt.PlotPatterns(G2frame,plotType=plottype)
667       
668    def OnLimitCopy(event):
669        histList = ['All',]+G2gd.GetPatternTreeDataNames(G2frame,['PWDR','SASD',])
670        copyList = []
671        dlg = wx.MultiChoiceDialog(G2frame, 
672            'Copy limits to which histograms?', 'Copy limits', 
673            histList, wx.CHOICEDLG_STYLE)
674        try:
675            if dlg.ShowModal() == wx.ID_OK:
676                result = dlg.GetSelections()
677                for i in result: 
678                    copyList.append(histList[i])
679                if 'All' in copyList: 
680                    copyList = histList[1:]
681            for item in copyList:
682                Id = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,item)
683                G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,Id,'Limits'),
684                    copy.copy(data))
685        finally:
686            dlg.Destroy()
687           
688    def OnAddExcl(event):
689        G2frame.ifGetExclude = True
690        print 'Add excluded region'
691       
692    G2frame.LimitsTable = []
693    colLabels = ['Tmin','Tmax']
694    rowLabels = ['original','changed']
695    for i in range(len(data)-2):
696        rowLabels.append('exclude')
697    Types = 2*[wg.GRID_VALUE_FLOAT+':12,5',]
698    G2frame.LimitsTable = G2gd.Table(data,rowLabels=rowLabels,colLabels=colLabels,types=Types)
699    G2frame.dataFrame.SetLabel('Limits')
700    G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.LimitMenu)
701    if not G2frame.dataFrame.GetStatusBar():
702        Status = G2frame.dataFrame.CreateStatusBar()
703    G2frame.Bind(wx.EVT_MENU,OnLimitCopy,id=G2gd.wxID_LIMITCOPY)
704    G2frame.Bind(wx.EVT_MENU,OnAddExcl,id=G2gd.wxID_ADDEXCLREGION)   
705    G2frame.dataDisplay = G2gd.GSGrid(parent=G2frame.dataFrame)
706    G2frame.dataDisplay.SetTable(G2frame.LimitsTable, True)
707    G2frame.dataDisplay.Bind(wg.EVT_GRID_CELL_CHANGE, RefreshLimitsGrid)               
708    G2frame.dataDisplay.Bind(wx.EVT_KEY_DOWN, KeyEditPeakGrid)
709    G2frame.dataDisplay.SetMargins(0,0)
710    G2frame.dataDisplay.AutoSizeColumns(False)
711    G2frame.dataFrame.setSizePosLeft([230,260])
712   
713################################################################################
714#####  Instrument parameters
715################################################################################           
716       
717def UpdateInstrumentGrid(G2frame,data):
718    '''respond to selection of PWDR/SASD Instrument Parameters
719    data tree item.
720    '''
721    def keycheck(keys):
722        good = []
723        for key in keys:
724            if key in ['Type','U','V','W','X','Y','SH/L','I(L2)/I(L1)','alpha',
725                'beta-0','beta-1','beta-q','sig-0','sig-1','sig-q','Polariz.',
726                'Lam','Azimuth','2-theta','difC','difA','Zero','Lam1','Lam2']:
727                good.append(key)
728        return good
729       
730    keys = keycheck(data.keys())
731    if 'P' in data['Type'][0]:          #powder data
732        insVal = dict(zip(keys,[data[key][1] for key in keys]))
733        insDef = dict(zip(keys,[data[key][0] for key in keys]))
734        insRef = dict(zip(keys,[data[key][2] for key in keys]))
735        if 'NC' in data['Type'][0]:
736            del(insDef['Polariz.'])
737            del(insVal['Polariz.'])
738            del(insRef['Polariz.'])
739    elif 'S' in data['Type'][0]:                               #single crystal data
740        insVal = dict(zip(keys,[data[key][1] for key in keys]))
741        insDef = dict(zip(keys,[data[key][0] for key in keys]))
742        insRef = {}
743    elif 'L' in data['Type'][0]:                               #low angle data
744        insVal = dict(zip(keys,[data[key][1] for key in keys]))
745        insDef = dict(zip(keys,[data[key][0] for key in keys]))
746        insRef = {}
747    ValObj = {}
748    RefObj = {}
749    waves = {'CuKa':[1.54051,1.54433],'TiKa':[2.74841,2.75207],'CrKa':[2.28962,2.29351],
750        'FeKa':[1.93597,1.93991],'CoKa':[1.78892,1.79278],'MoKa':[0.70926,0.713543],
751        'AgKa':[0.559363,0.563775]}
752    Inst2 = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,
753            G2frame.PatternId,'Instrument Parameters'))[1]
754       
755    def inst2data(inst,ref,data):
756        for item in data:
757            try:
758                data[item] = [data[item][0],inst[item],ref[item]]
759            except KeyError:
760                pass        #skip 'Polariz.' for N-data
761        return data
762       
763    def updateData(inst,ref):
764        return inst2data(inst,ref,G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,
765            G2frame.PatternId,'Instrument Parameters'))[0])       
766   
767    def RefreshInstrumentGrid(event,doAnyway=False):
768        if doAnyway or event.GetRow() == 1:
769            peaks = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Peak List'))
770            newpeaks = []
771            for peak in peaks:
772                newpeaks.append(G2mth.setPeakparms(data,Inst2,peak[0],peak[2]))
773            G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Peak List'),newpeaks)
774                   
775    def OnLoad(event):
776        '''Loads instrument parameters from a G2 .instprm file
777        in response to the Instrument Parameters-Operations/Load Profile menu
778       
779        Note that similar code is found in ReadPowderInstprm (GSASII.py)
780        '''
781        dlg = wx.FileDialog(G2frame, 'Choose GSAS-II instrument parameters file', '.', '', 
782            'instrument parameter files (*.instprm)|*.instprm',wx.OPEN|wx.CHANGE_DIR)
783        try:
784            if dlg.ShowModal() == wx.ID_OK:
785                filename = dlg.GetPath()
786                File = open(filename,'r')
787                S = File.readline()
788                newItems = []
789                newVals = []
790                while S:
791                    if S[0] == '#':
792                        S = File.readline()
793                        continue
794                    [item,val] = S[:-1].split(':')
795                    newItems.append(item)
796                    try:
797                        newVals.append(float(val))
798                    except ValueError:
799                        newVals.append(val)                       
800                    S = File.readline()               
801                File.close()
802                Inst,Inst2 = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId,'Instrument Parameters'))
803                inst = G2IO.makeInstDict(newItems,newVals,len(newVals)*[False,])
804                G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId,'Instrument Parameters'),[inst,Inst2])
805                RefreshInstrumentGrid(event,doAnyway=True)          #to get peaks updated
806                UpdateInstrumentGrid(G2frame,data)
807                G2plt.PlotPeakWidths(G2frame)
808        finally:
809            dlg.Destroy()
810       
811    def OnSave(event):
812        '''Respond to the Instrument Parameters Operations/Save Profile menu
813        item: writes current parameters to a .instprm file
814        '''
815        dlg = wx.FileDialog(G2frame, 'Choose GSAS-II instrument parameters file', '.', '', 
816            'instrument parameter files (*.instprm)|*.instprm',wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT|wx.CHANGE_DIR)
817        try:
818            if dlg.ShowModal() == wx.ID_OK:
819                filename = dlg.GetPath()
820                # make sure extension is .instprm
821                filename = os.path.splitext(filename)[0]+'.instprm'
822                File = open(filename,'w')
823                File.write("#GSAS-II instrument parameter file; do not add/delete or change order of items!\n")
824                for item in data:
825                    File.write(item+':'+str(data[item][1])+'\n')
826                File.close()
827        finally:
828            dlg.Destroy()
829                                               
830    def OnReset(event):
831        insVal.update(insDef)
832        data = updateData(insVal,insRef)
833        RefreshInstrumentGrid(event,doAnyway=True)          #to get peaks updated
834        UpdateInstrumentGrid(G2frame,data)
835        G2plt.PlotPeakWidths(G2frame)
836       
837    def OnInstFlagCopy(event):
838        histName = G2frame.PatternTree.GetItemText(G2frame.PatternId)
839        keys = data.keys()
840        flags = dict(zip(keys,[data[key][2] for key in keys]))
841        instType = data['Type'][0]
842        histList = ['All',]+G2gd.GetPatternTreeDataNames(G2frame,['PWDR',])
843        copyList = []
844        dlg = wx.MultiChoiceDialog(G2frame, 
845            'Copy refinement flags from\n'+histName, 'Copy refinement flags', 
846            histList, wx.CHOICEDLG_STYLE)
847        try:
848            if dlg.ShowModal() == wx.ID_OK:
849                result = dlg.GetSelections()
850                for i in result: 
851                    copyList.append(histList[i])
852                if 'All' in copyList: 
853                    copyList = histList[1:]
854            for item in copyList:
855                Id = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,item)
856                instData = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,Id,'Instrument Parameters'))[0]
857                if len(data) == len(instData) and instType == instData['Type'][0]:   #don't mix data types or lam & lam1/lam2 parms!
858                    for item in instData:
859                        instData[item][2] = copy.copy(flags[item])
860                else:
861                    print item+' not copied - instrument parameters not commensurate'
862        finally:
863            dlg.Destroy()
864       
865    def OnInstCopy(event):
866        #need fix for dictionary
867        histName = G2frame.PatternTree.GetItemText(G2frame.PatternId)
868        histList = ['All',]+G2gd.GetPatternTreeDataNames(G2frame,['PWDR',])
869        copyList = []
870        instType = data['Type'][0]
871        dlg = wx.MultiChoiceDialog(G2frame, 
872            'Copy parameters from\n'+histName, 'Copy parameters', 
873            histList, wx.CHOICEDLG_STYLE)
874        try:
875            if dlg.ShowModal() == wx.ID_OK:
876                result = dlg.GetSelections()
877                for i in result: 
878                    copyList.append(histList[i])
879                if 'All' in copyList: 
880                    copyList = histList[1:]
881            for item in copyList:
882                Id = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,item)
883                instData = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,Id,'Instrument Parameters'))[0]
884                if len(data) == len(instData) and instType == instData['Type'][0]:  #don't mix data types or lam & lam1/lam2 parms!
885                    instData.update(data)
886                else:
887                    print item+' not copied - instrument parameters not commensurate'
888        finally:
889            dlg.Destroy()
890       
891    def OnWaveChange(event):
892        if 'Lam' in insVal:
893            data['Lam1'] = [waves['CuKa'][0],waves['CuKa'][0],0]
894            data['Lam2'] = [waves['CuKa'][1],waves['CuKa'][1],0]
895            data['I(L2)/I(L1)'] = [0.5,0.5,0]
896            del(data['Lam'])
897        else:
898            data['Lam'] = [data['Lam1'][0],data['Lam1'][0],0]
899            del(data['Lam1'])
900        wx.CallAfter(UpdateInstrumentGrid,data)
901               
902    def OnLamPick(event):
903        lamType = lamPick.GetValue()
904        insVal['Lam1'] = waves[lamType][0]
905        insVal['Lam2'] = waves[lamType][1]
906        data = updateData(insVal,insRef)
907        UpdateInstrumentGrid(G2frame,data)
908                 
909    def OnRatValue(event):
910        try:
911            value = float(ratVal.GetValue())
912            if value < 0:
913                raise ValueError
914        except ValueError:
915            value = insVal['I(L2)/I(L1)']
916        insVal['I(L2)/I(L1)'] = value
917        ratVal.SetValue('%10.4f'%(value))
918        data = updateData(insVal,insRef)
919       
920    def OnRatRef(event):
921        insRef['I(L2)/I(L1)'] = ratRef.GetValue()
922        data = updateData(insVal,insRef)
923       
924    def OnWaveValue(event):
925        try:
926            value = float(waveVal.GetValue())
927            if value < 0:
928                raise ValueError
929        except ValueError:
930            value = insVal['Lam']
931        insVal['Lam'] = value
932        waveVal.SetValue('%10.6f'%(value))
933        data = updateData(insVal,insRef)
934       
935    def OnWaveRef(event):
936        insRef['Lam'] = waveRef.GetValue()
937        data = updateData(insVal,insRef)
938       
939    def OnItemValue(event):
940        Obj = event.GetEventObject()
941        item,fmt = ValObj[Obj.GetId()]
942        try:
943            value = float(Obj.GetValue())
944        except ValueError:
945            value = insVal[item]
946        insVal[item] = value
947        Obj.SetValue(fmt%(value))
948        data = updateData(insVal,insRef)
949        G2plt.PlotPeakWidths(G2frame)
950       
951    def OnItemRef(event):
952        Obj = event.GetEventObject()
953        item = RefObj[Obj.GetId()]
954        insRef[item] = Obj.GetValue()
955        data = updateData(insVal,insRef)
956               
957    if G2frame.dataDisplay:
958        G2frame.dataFrame.Clear()
959    try:
960        histoName = G2frame.PatternTree.GetItemPyData(G2frame.PatternId)[-1]
961        ifHisto = IsHistogramInAnyPhase(G2frame,histoName)
962    except TypeError:       #PKS data never used in a phase as data
963        ifhisto = False
964    G2gd.SetDataMenuBar(G2frame)
965    G2frame.dataFrame.SetLabel('Instrument Parameters')
966    G2frame.dataDisplay = wx.Panel(G2frame.dataFrame)
967    topSizer = wx.FlexGridSizer(1,6,5,5)
968    instSizer = wx.FlexGridSizer(2,6,5,5)
969    topSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' Histogram Type: '+insVal['Type']),0,WACV)
970#    topSizer.Add((5,5),0)
971    if 'P' in insVal['Type']:                   #powder data
972        G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.InstMenu)
973        if not G2frame.dataFrame.GetStatusBar():
974            Status = G2frame.dataFrame.CreateStatusBar()
975        G2frame.Bind(wx.EVT_MENU,OnLoad,id=G2gd.wxID_INSTLOAD)
976        G2frame.Bind(wx.EVT_MENU,OnSave,id=G2gd.wxID_INSTSAVE)
977        G2frame.Bind(wx.EVT_MENU,OnReset,id=G2gd.wxID_INSTPRMRESET)
978        G2frame.Bind(wx.EVT_MENU,OnInstCopy,id=G2gd.wxID_INSTCOPY)
979        G2frame.Bind(wx.EVT_MENU,OnInstFlagCopy,id=G2gd.wxID_INSTFLAGCOPY)
980        G2frame.Bind(wx.EVT_MENU,OnWaveChange,id=G2gd.wxID_CHANGEWAVETYPE)       
981        if 'C' in insVal['Type']:               #constant wavelength
982            #patch
983            if 'Azimuth' not in insVal:
984                insVal['Azimuth'] = 0.0
985                insDef['Azimuth'] = 0.0
986                insRef['Azimuth'] = False
987            #end of patch
988            topSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,'  Azimuth: %7.2f'%(insVal['Azimuth'])),0,WACV)
989            if 'Lam1' in insVal:
990                topSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,'  Ka1/Ka2:'),
991                        0,WACV)
992                topSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,u%8.6f/%8.6f\xc5'%(insVal['Lam1'],insVal['Lam2'])),
993                        0,WACV)
994                waveSizer = wx.BoxSizer(wx.HORIZONTAL)
995                waveSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,'  Select: '),0,WACV)
996                choice = ['TiKa','CrKa','FeKa','CoKa','CuKa','MoKa','AgKa']
997                lamPick = wx.ComboBox(G2frame.dataDisplay,value=' ',choices=choice,style=wx.CB_READONLY|wx.CB_DROPDOWN)
998                lamPick.Bind(wx.EVT_COMBOBOX, OnLamPick)
999                waveSizer.Add(lamPick,0)
1000                topSizer.Add(waveSizer,0)
1001                instSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' I(L2)/I(L1): (%10.4f)'%(insDef['I(L2)/I(L1)'])),
1002                        0,WACV)
1003                ratVal = wx.TextCtrl(G2frame.dataDisplay,wx.ID_ANY,'%10.4f'%(insVal['I(L2)/I(L1)']),style=wx.TE_PROCESS_ENTER)
1004                ratVal.Bind(wx.EVT_TEXT_ENTER,OnRatValue)
1005                ratVal.Bind(wx.EVT_KILL_FOCUS,OnRatValue)
1006                instSizer.Add(ratVal,0)
1007                ratRef = wx.CheckBox(G2frame.dataDisplay,label=' Refine?')
1008                ratRef.SetValue(bool(insRef['I(L2)/I(L1)']))
1009                ratRef.Bind(wx.EVT_CHECKBOX, OnRatRef)
1010                instSizer.Add(ratRef,0,WACV)
1011               
1012            else:
1013                topSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,u' Lam (\xc5): (%10.6f)'%(insDef['Lam'])),
1014                    0,WACV)
1015                waveVal = wx.TextCtrl(G2frame.dataDisplay,wx.ID_ANY,'%10.6f'%(insVal['Lam']),style=wx.TE_PROCESS_ENTER)
1016                waveVal.Bind(wx.EVT_TEXT_ENTER,OnWaveValue)
1017                waveVal.Bind(wx.EVT_KILL_FOCUS,OnWaveValue)
1018                topSizer.Add(waveVal,0,WACV)
1019                if ifHisto:
1020                    waveRef = wx.CheckBox(G2frame.dataDisplay,label=' Refine?')
1021                    waveRef.SetValue(bool(insRef['Lam']))
1022                    waveRef.Bind(wx.EVT_CHECKBOX, OnWaveRef)
1023                    topSizer.Add(waveRef,0,WACV)
1024            for item in ['Zero','Polariz.']:
1025                fmt = '%10.4f'
1026                Fmt = ' %s: ('+fmt+')'
1027                if item in insDef:
1028                    instSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,Fmt%(item,insDef[item])),
1029                            0,WACV)
1030                    itemVal = wx.TextCtrl(G2frame.dataDisplay,wx.ID_ANY,fmt%(insVal[item]),style=wx.TE_PROCESS_ENTER)
1031                    ValObj[itemVal.GetId()] = [item,fmt]
1032                    itemVal.Bind(wx.EVT_TEXT_ENTER,OnItemValue)
1033                    itemVal.Bind(wx.EVT_KILL_FOCUS,OnItemValue)
1034                    instSizer.Add(itemVal,0,WACV)
1035                    if ifHisto:
1036                        itemRef = wx.CheckBox(G2frame.dataDisplay,wx.ID_ANY,label=' Refine?')
1037                        itemRef.SetValue(bool(insRef[item]))
1038                        RefObj[itemRef.GetId()] = item
1039                        itemRef.Bind(wx.EVT_CHECKBOX, OnItemRef)
1040                        instSizer.Add(itemRef,0,WACV)
1041                    else:
1042                        instSizer.Add((5,5),0)
1043                else:                           #skip Polariz. for neutrons
1044                    instSizer.Add((5,5),0)
1045                    instSizer.Add((5,5),0)
1046                    instSizer.Add((5,5),0)
1047            for item in ['U','V','W','X','Y','SH/L']:
1048                fmt = '%10.3f'
1049                if item == 'SH/L':
1050                    fmt = '%10.5f'
1051                Fmt = ' %s: ('+fmt+')'
1052                instSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,Fmt%(item,insDef[item])),
1053                        0,WACV)
1054                itemVal = wx.TextCtrl(G2frame.dataDisplay,wx.ID_ANY,fmt%(insVal[item]),style=wx.TE_PROCESS_ENTER)
1055                ValObj[itemVal.GetId()] = [item,fmt]
1056                itemVal.Bind(wx.EVT_TEXT_ENTER,OnItemValue)
1057                itemVal.Bind(wx.EVT_KILL_FOCUS,OnItemValue)
1058                instSizer.Add(itemVal,0,WACV)
1059                itemRef = wx.CheckBox(G2frame.dataDisplay,wx.ID_ANY,label=' Refine?')
1060                itemRef.SetValue(bool(insRef[item]))
1061                RefObj[itemRef.GetId()] = item
1062                itemRef.Bind(wx.EVT_CHECKBOX, OnItemRef)
1063                instSizer.Add(itemRef,0,WACV)
1064        else:                                   #time of flight (neutrons)
1065            topSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' Azimuth: %7.2f'%(insVal['Azimuth'])),0,WACV)
1066            topSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' 2-theta: %7.2f'%(insVal['2-theta'])),0,WACV)
1067            if 'Pdabc' in Inst2:
1068                Items = ['sig-0','sig-1','X','Y']
1069                topSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' difC: %8.2f'%(insVal['difC'])),0,WACV)
1070                topSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' alpha, beta: fixed by table'),0,WACV)
1071            else:
1072                Items = ['difC','difA','Zero','alpha','beta-0','beta-1','beta-q','sig-0','sig-1','sig-q','X','Y']
1073            for item in Items:
1074                fmt = '%10.3f'
1075                if 'beta' in item:
1076                    fmt = '%12.4g'
1077                Fmt = ' %s: ('+fmt+')'
1078                instSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,Fmt%(item,insDef[item])),
1079                        0,WACV)
1080                itemVal = wx.TextCtrl(G2frame.dataDisplay,wx.ID_ANY,fmt%(insVal[item]),style=wx.TE_PROCESS_ENTER)
1081                ValObj[itemVal.GetId()] = [item,fmt]
1082                itemVal.Bind(wx.EVT_TEXT_ENTER,OnItemValue)
1083                itemVal.Bind(wx.EVT_KILL_FOCUS,OnItemValue)
1084                instSizer.Add(itemVal,0,WACV)
1085                if not ifHisto and item in ['difC','difA','Zero',]:
1086                    instSizer.Add((5,5),0)
1087                else:
1088                    itemRef = wx.CheckBox(G2frame.dataDisplay,wx.ID_ANY,label=' Refine?')
1089                    itemRef.SetValue(bool(insRef[item]))
1090                    RefObj[itemRef.GetId()] = item
1091                    itemRef.Bind(wx.EVT_CHECKBOX, OnItemRef)
1092                    instSizer.Add(itemRef,0,WACV)
1093       
1094    elif 'S' in insVal['Type']:                       #single crystal data
1095        if 'C' in insVal['Type']:               #constant wavelength
1096            instSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,u' Lam (\xc5): (%10.6f)'%(insDef['Lam'])),
1097                0,WACV)
1098            waveVal = wx.TextCtrl(G2frame.dataDisplay,wx.ID_ANY,'%10.6f'%(insVal['Lam']),style=wx.TE_PROCESS_ENTER)
1099            waveVal.Bind(wx.EVT_TEXT_ENTER,OnWaveValue)
1100            waveVal.Bind(wx.EVT_KILL_FOCUS,OnWaveValue)
1101            instSizer.Add(waveVal,0,WACV)
1102        else:                                   #time of flight (neutrons)
1103            pass                                #for now
1104    elif 'L' in insVal['Type']:
1105        if 'C' in insVal['Type']:       
1106            instSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,u' Lam (\xc5): (%10.6f)'%(insDef['Lam'])),
1107                0,WACV)
1108            waveVal = wx.TextCtrl(G2frame.dataDisplay,wx.ID_ANY,'%10.6f'%(insVal['Lam']),style=wx.TE_PROCESS_ENTER)
1109            waveVal.Bind(wx.EVT_TEXT_ENTER,OnWaveValue)
1110            waveVal.Bind(wx.EVT_KILL_FOCUS,OnWaveValue)
1111            instSizer.Add(waveVal,0,WACV)
1112            instSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,'  Azimuth: %7.2f'%(insVal['Azimuth'])),0,WACV)
1113        else:                                   #time of flight (neutrons)
1114            pass                                #for now
1115       
1116    mainSizer = wx.BoxSizer(wx.VERTICAL)
1117    mainSizer.Add(topSizer,0)
1118    mainSizer.Add(instSizer,0)
1119    mainSizer.Layout()   
1120    G2frame.dataDisplay.SetSizer(mainSizer)
1121    G2frame.dataFrame.setSizePosLeft(mainSizer.Fit(G2frame.dataFrame))
1122   
1123################################################################################
1124#####  Sample parameters
1125################################################################################           
1126       
1127def UpdateSampleGrid(G2frame,data):
1128    '''respond to selection of PWDR/SASD Sample Parameters
1129    data tree item.
1130    '''
1131                                                       
1132    def SetCopyNames(histName,addNames=[]):
1133        copyNames = ['Scale',]
1134        dataType = data['Type']
1135        histType = 'HKLF'
1136        if 'PWDR' in histName:
1137            histType = 'PWDR'
1138            if 'Debye' in dataType:
1139                copyNames += ['DisplaceX','DisplaceY','Absorption']
1140            else:       #Bragg-Brentano
1141                copyNames += ['Shift','Transparency','SurfRoughA','SurfRoughB']
1142        elif 'SASD' in histName:
1143            histType = 'SASD'
1144            copyNames += ['Materials','Thick',]
1145        if len(addNames):
1146         copyNames += addNames
1147        return histType,copyNames
1148       
1149    def OnSampleSave(event):
1150        '''Respond to the Sample Parameters Operations/Save menu
1151        item: writes current parameters to a .samprm file
1152        '''
1153        dlg = wx.FileDialog(G2frame, 'Choose GSAS-II sample parameters file', '.', '', 
1154            'sample parameter files (*.samprm)|*.samprm',wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT|wx.CHANGE_DIR)
1155        try:
1156            if dlg.ShowModal() == wx.ID_OK:
1157                filename = dlg.GetPath()
1158                # make sure extension is .samprm
1159                filename = os.path.splitext(filename)[0]+'.samprm'
1160                File = open(filename,'w')
1161                File.write("#GSAS-II sample parameter file\n")
1162                File.write("'Type':'"+str(data['Type'])+"'\n")
1163                File.write("'Gonio. radius':"+str(data['Gonio. radius'])+"\n")
1164                if data.get('InstrName'):
1165                    File.write("'InstrName':'"+str(data['InstrName'])+"'\n")
1166                File.close()
1167        finally:
1168            dlg.Destroy()
1169           
1170    def OnSampleLoad(event):
1171        '''Loads sample parameters from a G2 .samprm file
1172        in response to the Sample Parameters-Operations/Load menu
1173       
1174        Note that similar code is found in ReadPowderInstprm (GSASII.py)
1175        '''
1176        dlg = wx.FileDialog(G2frame, 'Choose GSAS-II sample parameters file', '.', '', 
1177            'sample parameter files (*.samprm)|*.samprm',wx.OPEN|wx.CHANGE_DIR)
1178        try:
1179            if dlg.ShowModal() == wx.ID_OK:
1180                filename = dlg.GetPath()
1181                File = open(filename,'r')
1182                S = File.readline()
1183                newItems = {}
1184                while S:
1185                    if S[0] == '#':
1186                        S = File.readline()
1187                        continue
1188                    [item,val] = S[:-1].split(':')
1189                    newItems[item.strip("'")] = eval(val)
1190                    S = File.readline()               
1191                File.close()
1192                data.update(newItems)
1193                G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId,'Sample Parameters'),data)
1194                UpdateSampleGrid(G2frame,data)
1195        finally:
1196            dlg.Destroy()
1197   
1198    def OnSetScale(event):
1199        histList = []
1200        item, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root)
1201        while item:
1202            name = G2frame.PatternTree.GetItemText(item)
1203            if 'SASD' in name and name != histName:
1204                histList.append(name)
1205            item, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie)
1206        if not len(histList):      #nothing to copy to!
1207            return
1208        dlg = wx.SingleChoiceDialog(G2frame,'Select reference histogram for scaling',
1209            'Reference histogram',histList)
1210        try:
1211            if dlg.ShowModal() == wx.ID_OK:
1212                sel = dlg.GetSelection()
1213                refHist = histList[sel]
1214        finally:
1215            dlg.Destroy()
1216        Limits = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Limits'))
1217        Profile = G2frame.PatternTree.GetItemPyData(G2frame.PatternId)[1]
1218        Data = [Profile,Limits,data]
1219        refId = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,refHist)
1220        refSample = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,refId, 'Sample Parameters'))
1221        refLimits = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,refId, 'Limits'))
1222        refProfile = G2frame.PatternTree.GetItemPyData(refId)[1]
1223        refData = [refProfile,refLimits,refSample]
1224        G2sasd.SetScale(Data,refData)
1225        UpdateSampleGrid(G2frame,data)       
1226        G2plt.PlotPatterns(G2frame,plotType='SASD',newPlot=True)
1227       
1228    def OnSampleCopy(event):
1229        histType,copyNames = SetCopyNames(histName,
1230            addNames = ['Omega','Chi','Phi','Gonio. radius','InstrName'])
1231        copyDict = {}
1232        for parm in copyNames:
1233            copyDict[parm] = data[parm]
1234        histList = ['All '+histType,]
1235        AllList = {}
1236        item, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root)
1237        while item:
1238            name = G2frame.PatternTree.GetItemText(item)
1239            if histType in name and name != histName:
1240                allname = name.split(' Azm=')[0]
1241                if allname in AllList:
1242                    AllList[allname] += 1
1243                else:
1244                    AllList[allname] = 1
1245                histList.append(name)
1246            item, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie)
1247        if len(histList) == 1:      #nothing to copy to!
1248            return
1249        nAll = 0
1250        AllNames = AllList.keys()
1251        AllNames.sort()
1252        for allname in AllNames:
1253            if AllList[allname] > 1:
1254                histList.insert(1+nAll,'All '+allname)
1255                nAll += 1
1256        copyList = []
1257        dlg = wx.MultiChoiceDialog(G2frame,'Copy parameters from\n'+histName,
1258            'Copy parameters',histList,wx.CHOICEDLG_STYLE)
1259        try:
1260            if dlg.ShowModal() == wx.ID_OK:
1261                result = dlg.GetSelections()
1262                for i in result: 
1263                    copyList.append(histList[i])
1264                for allname in AllList:
1265                    if 'All '+allname in copyList:
1266                        copyList = []
1267                        for name in histList:
1268                            if name.split(' Azm=')[0] == allname:
1269                                copyList.append(name)
1270                        break       #only one All allowed
1271                if 'All '+histType in copyList: 
1272                    copyList = histList[1+nAll:]
1273            for item in copyList:
1274                Id = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,item)
1275                sampleData = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,Id,'Sample Parameters'))
1276                sampleData.update(copy.deepcopy(copyDict))
1277        finally:
1278            dlg.Destroy()
1279
1280    def OnSampleFlagCopy(event):
1281        histType,copyNames = SetCopyNames(histName)
1282        flagDict = {}
1283        for parm in copyNames:
1284            flagDict[parm] = data[parm][1]
1285        histList = ['All '+histType,]
1286        item, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root)
1287        while item:
1288            name = G2frame.PatternTree.GetItemText(item)
1289            if histType in name and name != histName:
1290                histList.append(name)
1291            item, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie)
1292        if len(histList) == 1:      #nothing to copy to!
1293            return
1294        copyList = []
1295        dlg = wx.MultiChoiceDialog(G2frame,'Copy parameters from\n'+histName,
1296            'Copy refinement flags',histList,wx.CHOICEDLG_STYLE)
1297        try:
1298            if dlg.ShowModal() == wx.ID_OK:
1299                result = dlg.GetSelections()
1300                for i in result: 
1301                    copyList.append(histList[i])
1302                if 'All '+histType in copyList: 
1303                    copyList = histList[1:]
1304            for item in copyList:
1305                Id = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,item)
1306                sampleData = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,Id,'Sample Parameters'))
1307                for name in copyNames:
1308                    sampleData[name][1] = copy.copy(flagDict[name])
1309        finally:
1310            dlg.Destroy()
1311
1312    def OnHistoType(event):
1313        Obj = event.GetEventObject()
1314        data['Type'] = Obj.GetValue()
1315        if data['Type'] == 'Bragg-Brentano' and 'Shift' not in data:    #set up defaults for new type(s)
1316            data['Shift'] = [0.0,False]
1317            data['Transparency'] = [0.0,False]
1318        wx.CallAfter(UpdateSampleGrid,G2frame,data)
1319       
1320    def SetNameVal():
1321        inst = instNameVal.GetValue()
1322        data['InstrName'] = inst.strip()
1323
1324    def OnNameVal(event):
1325        event.Skip()
1326        wx.CallAfter(SetNameVal)
1327       
1328    def AfterChange(invalid,value,tc):
1329        if invalid:
1330            return
1331        if tc.key == 0 and 'SASD' in histName:          #a kluge for Scale!
1332            G2plt.PlotPatterns(G2frame,plotType='SASD',newPlot=True)
1333        elif tc.key == 'Thick':
1334            wx.CallAfter(UpdateSampleGrid,G2frame,data)           
1335           
1336    def OnMaterial(event):
1337        Obj = event.GetEventObject()
1338        id,key = Info[Obj.GetId()]
1339        if key == 'Name':
1340            data['Materials'][id][key] = Obj.GetValue()
1341        elif key == 'VolFrac':
1342            try:
1343                value = min(max(0.,float(Obj.GetValue())),1.)
1344            except ValueError:
1345                value = data['Materials'][id][key]
1346            data['Materials'][id][key] = value
1347            data['Materials'][not id][key] = 1.-value
1348        wx.CallAfter(UpdateSampleGrid,G2frame,data)
1349
1350    ######## DEBUG #######################################################
1351    #import GSASIIpwdGUI
1352    #reload(GSASIIpwdGUI)
1353    #reload(G2gd)
1354    ######################################################################
1355    histName = G2frame.PatternTree.GetItemText(G2frame.PatternId)
1356    if G2frame.dataDisplay:
1357        G2frame.dataFrame.Clear()
1358    G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.SampleMenu)
1359    G2frame.dataFrame.SetLabel('Sample Parameters')
1360    G2frame.Bind(wx.EVT_MENU, OnSetScale, id=G2gd.wxID_SETSCALE)
1361    G2frame.Bind(wx.EVT_MENU, OnSampleCopy, id=G2gd.wxID_SAMPLECOPY)
1362    G2frame.Bind(wx.EVT_MENU, OnSampleFlagCopy, id=G2gd.wxID_SAMPLEFLAGCOPY)
1363    G2frame.Bind(wx.EVT_MENU, OnSampleSave, id=G2gd.wxID_SAMPLESAVE)
1364    G2frame.Bind(wx.EVT_MENU, OnSampleLoad, id=G2gd.wxID_SAMPLELOAD)
1365    if 'SASD' in histName:
1366        G2frame.dataFrame.SetScale.Enable(True)
1367    if not G2frame.dataFrame.GetStatusBar():
1368        Status = G2frame.dataFrame.CreateStatusBar()   
1369    G2frame.dataDisplay = wx.Panel(G2frame.dataFrame)
1370    Controls = G2frame.PatternTree.GetItemPyData(
1371        G2gd.GetPatternTreeItemId(G2frame,G2frame.root, 'Controls'))
1372#patch
1373    if 'ranId' not in data:
1374        data['ranId'] = ran.randint(0,sys.maxint)
1375    if not 'Gonio. radius' in data:
1376        data['Gonio. radius'] = 200.0
1377    if not 'Omega' in data:
1378        data.update({'Omega':0.0,'Chi':0.0,'Phi':0.0})
1379    if type(data['Temperature']) is int:
1380        data['Temperature'] = float(data['Temperature'])
1381    if 'FreePrm1' not in Controls:
1382        Controls['FreePrm1'] = 'Sample humidity (%)'
1383    if 'FreePrm2' not in Controls:
1384        Controls['FreePrm2'] = 'Sample voltage (V)'
1385    if 'FreePrm3' not in Controls:
1386        Controls['FreePrm3'] = 'Applied load (MN)'
1387    if 'FreePrm1' not in data:
1388        data['FreePrm1'] = 0.
1389    if 'FreePrm2' not in data:
1390        data['FreePrm2'] = 0.
1391    if 'FreePrm3' not in data:
1392        data['FreePrm3'] = 0.
1393    if 'SurfRoughA' not in data and 'PWDR' in histName:
1394        data['SurfRoughA'] = [0.,False]
1395        data['SurfRoughB'] = [0.,False]
1396    if 'Trans' not in data and 'SASD' in histName:
1397        data['Trans'] = 1.0
1398#patch end
1399   
1400    parms = []
1401    parms.append(['Scale','Histogram scale factor: ',[10,4]])
1402    parms.append(['Gonio. radius','Goniometer radius (mm): ',[10,3]])
1403    if 'PWDR' in histName:
1404        if data['Type'] == 'Debye-Scherrer':
1405            parms += [['DisplaceX',u'Sample X displ. perp. to beam (\xb5m): ',[10,3]],
1406                ['DisplaceY',u'Sample Y displ. || to beam (\xb5m): ',[10,3]],
1407                ['Absorption',u'Sample absorption (\xb5\xb7r): ',[10,4]],]
1408        elif data['Type'] == 'Bragg-Brentano':
1409            parms += [['Shift',u'Sample displacement(\xb5m): ',[10,4]],
1410                ['Transparency',u'Sample transparency(1/\xb5eff, cm): ',[10,3]],
1411                ['SurfRoughA','Surface roughness A: ',[10,4]],
1412                ['SurfRoughB','Surface roughness B: ',[10,4]]]
1413    elif 'SASD' in histName:
1414        parms.append(['Thick','Sample thickness (mm)',[10,3]])
1415        parms.append(['Trans','Transmission (meas)',[10,3]])
1416    parms.append(['Omega','Goniometer omega:',[10,3]])
1417    parms.append(['Chi','Goniometer chi:',[10,3]])
1418    parms.append(['Phi','Goniometer phi:',[10,3]])
1419    parms.append(['Temperature','Sample temperature (K): ',[10,3]])
1420    parms.append(['Pressure','Sample pressure (MPa): ',[10,3]])
1421               
1422    mainSizer = wx.BoxSizer(wx.VERTICAL)
1423    topSizer = wx.BoxSizer(wx.HORIZONTAL)
1424    topSizer.Add((-1,-1),1,wx.EXPAND,1)
1425    topSizer.Add(wx.StaticText(G2frame.dataDisplay,label='Sample and Experimental Parameters'))
1426    topSizer.Add((-1,-1),1,wx.EXPAND,1)
1427    mainSizer.Add(topSizer,0,wx.EXPAND,1)
1428    nameSizer = wx.BoxSizer(wx.HORIZONTAL)
1429    nameSizer.Add(wx.StaticText(G2frame.dataDisplay,wx.ID_ANY,' Instrument Name'),
1430                0,WACV)
1431    nameSizer.Add((-1,-1),1,wx.EXPAND,1)
1432    instNameVal = wx.TextCtrl(G2frame.dataDisplay,wx.ID_ANY,data.get('InstrName',''),
1433                              size=(200,-1),style=wx.TE_PROCESS_ENTER)       
1434    nameSizer.Add(instNameVal)
1435    instNameVal.Bind(wx.EVT_CHAR,OnNameVal)
1436    mainSizer.Add(nameSizer,0,wx.EXPAND,1)
1437    mainSizer.Add((5,5),0)
1438
1439    if 'PWDR' in histName:
1440        nameSizer = wx.BoxSizer(wx.HORIZONTAL)
1441        nameSizer.Add(wx.StaticText(G2frame.dataDisplay,wx.ID_ANY,' Diffractometer type: '),
1442                    0,WACV)
1443        choices = ['Debye-Scherrer','Bragg-Brentano',]
1444        histoType = wx.ComboBox(G2frame.dataDisplay,wx.ID_ANY,value=data['Type'],choices=choices,
1445            style=wx.CB_READONLY|wx.CB_DROPDOWN)
1446        histoType.Bind(wx.EVT_COMBOBOX, OnHistoType)
1447        nameSizer.Add(histoType)
1448        mainSizer.Add(nameSizer,0,wx.EXPAND,1)
1449        mainSizer.Add((5,5),0)
1450
1451    parmSizer = wx.FlexGridSizer(10,2,5,0)
1452    for key,lbl,nDig in parms:
1453        if 'list' in str(type(data[key])):
1454            parmRef = G2gd.G2CheckBox(G2frame.dataDisplay,' '+lbl,data[key],1)
1455            parmSizer.Add(parmRef,0,WACV|wx.EXPAND)
1456            parmVal = G2gd.ValidatedTxtCtrl(G2frame.dataDisplay,data[key],0,
1457                nDig=nDig,typeHint=float,OnLeave=AfterChange)
1458        else:
1459            parmSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' '+lbl),
1460                0,WACV|wx.EXPAND)
1461            parmVal = G2gd.ValidatedTxtCtrl(G2frame.dataDisplay,data,key,
1462                typeHint=float,OnLeave=AfterChange)
1463        parmSizer.Add(parmVal,1,wx.EXPAND)
1464    Info = {}
1465
1466       
1467    for key in ('FreePrm1','FreePrm2','FreePrm3'):
1468        parmVal = G2gd.ValidatedTxtCtrl(G2frame.dataDisplay,Controls,key,typeHint=str,
1469                                        notBlank=False)
1470        parmSizer.Add(parmVal,1,wx.EXPAND)
1471        parmVal = G2gd.ValidatedTxtCtrl(G2frame.dataDisplay,data,key,typeHint=float)
1472        parmSizer.Add(parmVal,1,wx.EXPAND)
1473    mainSizer.Add(parmSizer,1,wx.EXPAND)
1474    mainSizer.Add((0,5),0)   
1475    if 'SASD' in histName:
1476        rho = [0.,0.]
1477        anomrho = [0.,0.]
1478        mu = 0.
1479        subSizer = wx.FlexGridSizer(1,4,5,5)
1480        Substances = G2frame.PatternTree.GetItemPyData(
1481            G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Substances'))
1482        for id,item in enumerate(data['Materials']):
1483            subSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Material: '),0,WACV)
1484            matsel = wx.ComboBox(G2frame.dataDisplay,value=item['Name'],choices=Substances['Substances'].keys(),
1485                style=wx.CB_READONLY|wx.CB_DROPDOWN)
1486            Info[matsel.GetId()] = [id,'Name']
1487            matsel.Bind(wx.EVT_COMBOBOX,OnMaterial)       
1488            subSizer.Add(matsel,0,WACV)
1489            subSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Volume fraction: '),0,WACV)
1490            volfrac = wx.TextCtrl(G2frame.dataDisplay,value=str('%.3f'%(item['VolFrac'])),style=wx.TE_PROCESS_ENTER)
1491            Info[volfrac.GetId()] = [id,'VolFrac']
1492            volfrac.Bind(wx.EVT_TEXT_ENTER,OnMaterial)
1493            volfrac.Bind(wx.EVT_KILL_FOCUS,OnMaterial)
1494            subSizer.Add(volfrac,0,WACV)
1495            material = Substances['Substances'][item['Name']]
1496            mu += item['VolFrac']*material.get('XAbsorption',0.)
1497            rho[id] = material['Scatt density']
1498            anomrho[id] = material.get('XAnom density',0.)
1499        data['Contrast'] = [(rho[1]-rho[0])**2,(anomrho[1]-anomrho[0])**2]
1500        mainSizer.Add(subSizer,0)
1501        conSizer = wx.BoxSizer(wx.HORIZONTAL)
1502        conSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Contrast: %10.2f '%(data['Contrast'][0])),0,WACV)
1503        conSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Anom. Contrast: %10.2f '%(data['Contrast'][1])),0,WACV)
1504        mut =  mu*data['Thick']
1505        conSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Transmission (calc): %10.3f  '%(np.exp(-mut))),0,WACV)
1506        mainSizer.Add(conSizer,0)
1507   
1508    mainSizer.Layout()   
1509    G2frame.dataDisplay.SetSizer(mainSizer)
1510    Size = mainSizer.Fit(G2frame.dataFrame)
1511    G2frame.dataDisplay.SetSize(Size)
1512    G2frame.dataFrame.setSizePosLeft(Size)
1513               
1514################################################################################
1515#####  Indexing Peaks
1516################################################################################           
1517       
1518def UpdateIndexPeaksGrid(G2frame, data):
1519    '''respond to selection of PWDR Index Peak List data
1520    tree item.
1521    '''
1522    IndexId = G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Index Peak List')
1523    Inst = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Instrument Parameters'))[0]
1524    wave = G2mth.getWave(Inst)
1525   
1526    def RefreshIndexPeaksGrid(event):
1527        r,c =  event.GetRow(),event.GetCol()
1528        data = G2frame.IndexPeaksTable.GetData()
1529        if c == 2:
1530            if data[r][c]:
1531                data[r][c] = False
1532            else:
1533                data[r][c] = True
1534            G2frame.IndexPeaksTable.SetData(data)
1535            G2frame.PatternTree.SetItemPyData(IndexId,data)
1536            G2frame.dataDisplay.ForceRefresh()
1537           
1538    def OnReload(event):
1539        data = []
1540        peaks = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Peak List'))
1541        for peak in peaks:
1542            dsp = wave/(2.0*sind((peak[0]-Inst['Zero'][1])/2.0))
1543            data.append([peak[0],peak[2],True,False,0,0,0,dsp,0.0])
1544        G2frame.PatternTree.SetItemPyData(IndexId,data)
1545        UpdateIndexPeaksGrid(G2frame,data)
1546       
1547    def KeyEditPickGrid(event):
1548        colList = G2frame.dataDisplay.GetSelectedCols()
1549        rowList = G2frame.dataDisplay.GetSelectedRows()
1550        data = G2frame.PatternTree.GetItemPyData(IndexId)
1551        if event.GetKeyCode() == wx.WXK_RETURN:
1552            event.Skip(True)
1553        elif event.GetKeyCode() == wx.WXK_CONTROL:
1554            event.Skip(True)
1555        elif event.GetKeyCode() == wx.WXK_SHIFT:
1556            event.Skip(True)
1557        elif colList:
1558            G2frame.dataDisplay.ClearSelection()
1559            key = event.GetKeyCode()
1560            for col in colList:
1561                if G2frame.IndexPeaksTable.GetColLabelValue(col) in ['use','refine']:
1562                    if key == 89: #'Y'
1563                        for row in range(G2frame.IndexPeaksTable.GetNumberRows()): data[row][col]=True
1564                    elif key == 78:  #'N'
1565                        for row in range(G2frame.IndexPeaksTable.GetNumberRows()): data[row][col]=False
1566           
1567    if G2frame.dataDisplay:
1568        G2frame.dataFrame.Clear()
1569    if not G2frame.dataFrame.GetStatusBar():
1570        Status = G2frame.dataFrame.CreateStatusBar()
1571    if 'PWD' in G2frame.PatternTree.GetItemText(G2frame.PatternId):
1572        G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.IndPeaksMenu)
1573        G2frame.Bind(wx.EVT_MENU, OnReload, id=G2gd.wxID_INDXRELOAD)
1574    G2frame.dataFrame.IndexPeaks.Enable(False)
1575    G2frame.IndexPeaksTable = []
1576    if data:
1577        G2frame.dataFrame.IndexPeaks.Enable(True)
1578        cells = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Unit Cells List'))
1579        if cells:
1580            cellist = cells[2]
1581            dmin = cells[3]
1582            G2frame.HKL = []
1583            for i,cell in enumerate(cellist):
1584                if cell[-1]:
1585                    ibrav = cell[2]
1586                    A = G2lat.cell2A(cell[3:9])
1587                    G2frame.HKL = G2lat.GenHBravais(dmin,ibrav,A)
1588                    G2indx.IndexPeaks(data,G2frame.HKL)
1589                    for hkl in G2frame.HKL:
1590                        hkl.append(2.0*asind(wave/(2.*hkl[3]))+Inst['Zero'][1])             
1591    rowLabels = []
1592    for i in range(len(data)): rowLabels.append(str(i+1))
1593    colLabels = ['position','intensity','use','indexed','h','k','l','d-obs','d-calc']
1594    Types = [wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_FLOAT+':10,1',wg.GRID_VALUE_BOOL,
1595        wg.GRID_VALUE_BOOL,wg.GRID_VALUE_LONG,wg.GRID_VALUE_LONG,wg.GRID_VALUE_LONG,
1596        wg.GRID_VALUE_FLOAT+':10,5',wg.GRID_VALUE_FLOAT+':10,5']
1597    G2frame.PatternTree.SetItemPyData(IndexId,data)
1598    G2frame.IndexPeaksTable = G2gd.Table(data,rowLabels=rowLabels,colLabels=colLabels,types=Types)
1599    G2frame.dataFrame.SetLabel('Index Peak List')
1600    G2frame.dataDisplay = G2gd.GSGrid(parent=G2frame.dataFrame)               
1601    G2frame.dataDisplay.SetTable(G2frame.IndexPeaksTable, True)
1602    for r in range(G2frame.dataDisplay.GetNumberRows()):
1603        for c in range(G2frame.dataDisplay.GetNumberCols()):
1604            if c == 2:
1605                G2frame.dataDisplay.SetReadOnly(r,c,isReadOnly=False)
1606            else:
1607                G2frame.dataDisplay.SetReadOnly(r,c,isReadOnly=True)
1608    G2frame.dataDisplay.Bind(wg.EVT_GRID_CELL_LEFT_CLICK, RefreshIndexPeaksGrid)
1609    G2frame.dataDisplay.Bind(wx.EVT_KEY_DOWN, KeyEditPickGrid)                 
1610    G2frame.dataDisplay.SetMargins(0,0)
1611    G2frame.dataDisplay.AutoSizeColumns(False)
1612    G2frame.dataFrame.setSizePosLeft([490,300])
1613 
1614################################################################################
1615#####  Unit cells
1616################################################################################           
1617       
1618def UpdateUnitCellsGrid(G2frame, data):
1619    '''respond to selection of PWDR Unit Cells data tree item.
1620    '''
1621    UnitCellsId = G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Unit Cells List')
1622    SPGlist = G2spc.spglist
1623    bravaisSymb = ['Fm3m','Im3m','Pm3m','R3-H','P6/mmm','I4/mmm',
1624        'P4/mmm','Fmmm','Immm','Cmmm','Pmmm','C2/m','P2/m','P1']
1625    spaceGroups = ['F m 3 m','I m 3 m','P m 3 m','R 3 m','P 6/m m m','I 4/m m m',
1626        'P 4/m m m','F m m m','I m m m','C m m m','P m m m','C 2/m','P 2/m','P -1']
1627    Inst = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Instrument Parameters'))[0]
1628    wave = G2mth.getWave(Inst)
1629   
1630    def SetLattice(controls):
1631        ibrav = bravaisSymb.index(controls[5])
1632        if ibrav in [0,1,2]:
1633            controls[7] = controls[8] = controls[6]
1634            controls[9] = controls[10] = controls[11] = 90.
1635        elif ibrav in [3,4,5,6]:
1636            controls[7] = controls[6]
1637            controls[9] = controls[10] = controls[11] = 90.
1638            if ibrav in [3,4]:
1639                controls[11] = 120.
1640        elif ibrav in [7,8,9,10]:
1641            controls[9] = controls[10] = controls[11] = 90.
1642        elif ibrav in [11,12]:
1643            controls[9] = controls[11] = 90.  # b unique
1644        if len(controls) < 13: controls.append(0)
1645        controls[12] = G2lat.calc_V(G2lat.cell2A(controls[6:12]))
1646        return ibrav
1647       
1648    def OnNcNo(event):
1649        controls[2] = NcNo.GetValue()
1650       
1651    def OnStartVol(event):
1652        try:
1653            stVol = int(float(startVol.GetValue()))
1654            if stVol < 25:
1655                raise ValueError
1656        except ValueError:
1657            stVol = 25
1658        controls[3] = stVol
1659        startVol.SetValue("%d"%(stVol))
1660       
1661    def OnBravais(event):
1662        Obj = event.GetEventObject()
1663        bravais[bravList.index(Obj.GetId())] = Obj.GetValue()
1664       
1665    def OnZero(event):
1666        try:
1667            Zero = min(5.0,max(-5.0,float(zero.GetValue())))
1668        except ValueError:
1669            Zero = 0.0
1670        controls[1] = Zero
1671        zero.SetValue("%.4f"%(Zero))
1672       
1673    def OnZeroVar(event):
1674        controls[0] = zeroVar.GetValue()
1675       
1676    def OnBravSel(event):
1677        brav = bravSel.GetString(bravSel.GetSelection())
1678        controls[5] = brav
1679        controls[13] = SPGlist[brav][0]       
1680        wx.CallAfter(UpdateUnitCellsGrid,G2frame,data)
1681       
1682    def OnSpcSel(event):
1683        controls[13] = spcSel.GetString(spcSel.GetSelection())       
1684       
1685    def OnCellChange(event):
1686        ibrav = bravaisSymb.index(controls[5])
1687        Obj = event.GetEventObject()
1688        ObjId = cellList.index(Obj.GetId())
1689        try:
1690            value = max(1.0,float(Obj.GetValue()))
1691        except ValueError:
1692            if ObjId < 3:               #bad cell edge - reset
1693                value = controls[6+ObjId]
1694            else:                       #bad angle
1695                value = 90.
1696        if ibrav in [0,1,2]:
1697            controls[6] = controls[7] = controls[8] = value
1698            controls[9] = controls[10] = controls[11] = 90.0
1699            Obj.SetValue("%.5f"%(controls[6]))
1700        elif ibrav in [3,4,5,6]:
1701            if ObjId == 0:
1702                controls[6] = controls[7] = value
1703                Obj.SetValue("%.5f"%(controls[6]))
1704            else:
1705                controls[8] = value
1706                Obj.SetValue("%.5f"%(controls[8]))
1707            controls[9] = controls[10] = controls[11] = 90.0
1708            if ibrav in [3,4]:
1709                controls[11] = 120.
1710        elif ibrav in [7,8,9,10]:
1711            controls[6+ObjId] = value
1712            Obj.SetValue("%.5f"%(controls[6+ObjId]))
1713            controls[9] = controls[10] = controls[11] = 90.0
1714        elif ibrav in [11,12]:
1715            controls[9] = controls[11] = 90.0
1716            if ObjId != 3:
1717                controls[6+ObjId] = value
1718                Obj.SetValue("%.5f"%(controls[6+ObjId]))
1719            else:
1720                controls[10] = value
1721                Obj.SetValue("%.3f"%(controls[10]))
1722        else:
1723            controls[6+ObjId] = value
1724            if ObjId < 3:
1725                Obj.SetValue("%.5f"%(controls[6+ObjId]))
1726            else:
1727                Obj.SetValue("%.3f"%(controls[6+ObjId]))
1728        controls[12] = G2lat.calc_V(G2lat.cell2A(controls[6:12]))
1729        volVal.SetValue("%.3f"%(controls[12]))
1730       
1731    def OnHklShow(event):
1732        PatternId = G2frame.PatternId
1733        PickId = G2frame.PickId   
1734        limits = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Limits'))[1]
1735        controls,bravais,cells,dmin = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Unit Cells List'))
1736        cell = controls[6:12]
1737        A = G2lat.cell2A(cell)
1738        ibrav = bravaisSymb.index(controls[5])
1739        spc = controls[13]
1740        SGData = G2spc.SpcGroup(spc)[1]
1741        dmin = wave/(2.0*sind(limits[1]/2.0))
1742        G2frame.HKL = G2pwd.getHKLpeak(dmin,SGData,A)
1743        for hkl in G2frame.HKL:
1744            hkl.append(2.0*asind(wave/(2.*hkl[3]))+controls[1]+Inst['Zero'][1])             
1745        if 'PKS' in G2frame.PatternTree.GetItemText(G2frame.PatternId):
1746            G2plt.PlotPowderLines(G2frame)
1747        else:
1748            G2plt.PlotPatterns(G2frame)
1749           
1750    def OnSortCells(event):
1751        controls,bravais,cells,dmin = G2frame.PatternTree.GetItemPyData(UnitCellsId)
1752        c =  event.GetCol()
1753        if colLabels[c] == 'M20':
1754            cells = G2indx.sortM20(cells)
1755        elif colLabels[c] == 'Volume':
1756            cells = G2indx.sortVolume(cells)
1757        else:
1758            return
1759        data = [controls,bravais,cells,dmin]
1760        G2frame.PatternTree.SetItemPyData(UnitCellsId,data)
1761        wx.CallAfter(UpdateUnitCellsGrid,G2frame,data)
1762       
1763    def CopyUnitCell(event):
1764        controls,bravais,cells,dmin = G2frame.PatternTree.GetItemPyData(UnitCellsId)
1765        for Cell in cells:
1766            if Cell[-2]:
1767                break
1768        cell = Cell[2:9]
1769        controls[4] = 1
1770        controls[5] = bravaisSymb[cell[0]]
1771        controls[6:12] = cell[1:8]
1772        controls[12] = G2lat.calc_V(G2lat.cell2A(controls[6:12]))
1773        controls[13] = spaceGroups[bravaisSymb.index(controls[5])]
1774        G2frame.PatternTree.SetItemPyData(UnitCellsId,[controls,bravais,cells,dmin])
1775        G2frame.dataFrame.RefineCell.Enable(True)
1776        wx.CallAfter(UpdateUnitCellsGrid,G2frame,data)       
1777               
1778    def RefineCell(event):
1779        def cellPrint(ibrav,A):
1780            cell = G2lat.A2cell(A)
1781            Vol = G2lat.calc_V(A)
1782            if ibrav in [0,1,2]:
1783                print "%s%10.6f" % ('a =',cell[0])
1784            elif ibrav in [3,4,5,6]:
1785                print "%s%10.6f %s%10.6f %s%12.3f" % ('a =',cell[0],' c =',cell[2],' volume =',Vol)
1786            elif ibrav in [7,8,9,10]:
1787                print "%s%10.6f %s%10.6f %s%10.6f %s%12.3f" % ('a =',cell[0],'b =',cell[1],'c =',cell[2],' volume =',Vol)
1788            elif ibrav in [11,12]:
1789                print "%s%10.6f %s%10.6f %s%10.6f %s%8.3f %s%12.3f" % ('a =',cell[0],'b =',cell[1],'c =',cell[2],'beta =',cell[4],' volume =',Vol)
1790            else:
1791                print "%s%10.6f %s%10.6f %s%10.6f" % ('a =',cell[0],'b =',cell[1],'c =',cell[2])
1792                print "%s%8.3f %s%8.3f %s%8.3f %s%12.3f" % ('alpha =',cell[3],'beta =',cell[4],'gamma =',cell[5],' volume =',Vol)
1793             
1794        PatternId = G2frame.PatternId
1795        PickId = G2frame.PickId   
1796        peaks = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Index Peak List'))
1797        if not peaks:
1798            G2frame.ErrorDialog('No peaks!', 'Nothing to refine!')
1799            return       
1800        print 'Refine cell'
1801        controls,bravais,cells,dmin = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Unit Cells List'))
1802        cell = controls[6:12]
1803        A = G2lat.cell2A(cell)
1804        ibrav = bravaisSymb.index(controls[5])
1805        SGData = G2spc.SpcGroup(controls[13])[1]
1806        dmin = G2indx.getDmin(peaks)-0.005
1807        G2frame.HKL = G2pwd.getHKLpeak(dmin,SGData,A)
1808        G2indx.IndexPeaks(peaks,G2frame.HKL)
1809        Lhkl,M20,X20,Aref,Zero = G2indx.refinePeaksZ(peaks,wave,ibrav,A,controls[1],controls[0])           
1810        controls[1] = Zero
1811        controls[6:12] = G2lat.A2cell(Aref)
1812        controls[12] = G2lat.calc_V(Aref)
1813        data = [controls,bravais,cells,dmin]
1814        cells = G2frame.PatternTree.GetItemPyData(UnitCellsId)[2]
1815        for cell in cells:
1816            cell[-2] = False
1817        cells.insert(0,[M20,X20,ibrav]+controls[6:13]+[True,False])
1818        data[2] = cells
1819        G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Unit Cells List'),data)
1820        G2frame.HKL = G2lat.GenHBravais(dmin,ibrav,Aref)
1821        print "%s%10.3f" % ('refinement M20 = ',M20)
1822        print 'unindexed lines = ',X20
1823        cellPrint(ibrav,Aref)
1824        for hkl in G2frame.HKL:
1825            hkl.append(2.0*asind(wave/(2.*hkl[3]))+controls[1]+Inst['Zero'][1])             
1826        if 'PKS' in G2frame.PatternTree.GetItemText(G2frame.PatternId):
1827            G2plt.PlotPowderLines(G2frame)
1828        else:
1829            G2plt.PlotPatterns(G2frame)
1830        wx.CallAfter(UpdateUnitCellsGrid,G2frame,data)
1831       
1832    def IndexPeaks(event):
1833        PatternId = G2frame.PatternId   
1834        print 'Peak Indexing'
1835        keepcells = []
1836        try:
1837            controls,bravais,cells,dmin = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Unit Cells List'))
1838            for cell in cells:
1839                if cell[11]:
1840                    keepcells.append(cell)
1841        except IndexError:
1842            pass
1843        except ValueError:
1844            G2frame.ErrorDialog('Error','Need to set controls in Unit Cell List first')
1845            return
1846        if True not in bravais:
1847            G2frame.ErrorDialog('Error','No Bravais lattices selected')
1848            return
1849        G2frame.dataFrame.CopyCell.Enable(False)
1850        G2frame.dataFrame.RefineCell.Enable(False)
1851        OK,dmin,newcells = G2indx.DoIndexPeaks(peaks,wave,controls,bravais)
1852        cells = keepcells+newcells
1853        cells = G2indx.sortM20(cells)
1854        cells[0][10] = True
1855        if OK:
1856            data = [controls,bravais,cells,dmin]
1857            G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Unit Cells List'),data)
1858            bestCell = cells[0]
1859            if bestCell[0] > 10.:
1860                G2frame.HKL = G2lat.GenHBravais(dmin,bestCell[2],G2lat.cell2A(bestCell[3:9]))
1861                for hkl in G2frame.HKL:
1862                    hkl.append(2.0*asind(wave/(2.*hkl[3]))+controls[1]+Inst['Zero'][1])             
1863                if 'PKS' in G2frame.PatternTree.GetItemText(G2frame.PatternId):
1864                    G2plt.PlotPowderLines(G2frame)
1865                else:
1866                    G2plt.PlotPatterns(G2frame)
1867            G2frame.dataFrame.CopyCell.Enable(True)
1868            G2frame.dataFrame.IndexPeaks.Enable(True)
1869            G2frame.dataFrame.MakeNewPhase.Enable(True)
1870        wx.CallAfter(UpdateUnitCellsGrid,G2frame,data)
1871               
1872    def RefreshUnitCellsGrid(event):
1873        data =G2frame.PatternTree.GetItemPyData(UnitCellsId)
1874        cells,dmin = data[2:]
1875        r,c =  event.GetRow(),event.GetCol()
1876        if cells:
1877            if c == 2:
1878                for i in range(len(cells)):
1879                    cells[i][-2] = False
1880                    UnitCellsTable.SetValue(i,c,False)
1881                UnitCellsTable.SetValue(r,c,True)
1882                gridDisplay.ForceRefresh()
1883                cells[r][-2] = True
1884                ibrav = cells[r][2]
1885                A = G2lat.cell2A(cells[r][3:9])
1886                G2frame.HKL = G2lat.GenHBravais(dmin,ibrav,A)
1887                for hkl in G2frame.HKL:
1888                    hkl.append(2.0*asind(wave/(2.*hkl[3]))+controls[1]+Inst['Zero'][1])             
1889                if 'PKS' in G2frame.PatternTree.GetItemText(G2frame.PatternId):
1890                    G2plt.PlotPowderLines(G2frame)
1891                else:
1892                    G2plt.PlotPatterns(G2frame)
1893            elif c == 11:
1894                if UnitCellsTable.GetValue(r,c):
1895                    UnitCellsTable.SetValue(r,c,False)
1896                    cells[r][c] = False
1897                else:
1898                    cells[r][c] = True
1899                    UnitCellsTable.SetValue(r,c,True)
1900                gridDisplay.ForceRefresh()
1901            G2frame.PatternTree.SetItemPyData(UnitCellsId,data)               
1902       
1903    def MakeNewPhase(event):
1904        if not G2gd.GetPatternTreeItemId(G2frame,G2frame.root,'Phases'):
1905            sub = G2frame.PatternTree.AppendItem(parent=G2frame.root,text='Phases')
1906        else:
1907            sub = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,'Phases')
1908        PhaseName = ''
1909        dlg = wx.TextEntryDialog(None,'Enter a name for this phase','Phase Name Entry','New phase',
1910            style=wx.OK)
1911        try:
1912            if dlg.ShowModal() == wx.ID_OK:
1913                PhaseName = dlg.GetValue()
1914                cells = G2frame.PatternTree.GetItemPyData(UnitCellsId)[2]
1915                for Cell in cells:
1916                    if Cell[-2]:
1917                        break
1918                cell = Cell[2:10]       
1919                sub = G2frame.PatternTree.AppendItem(parent=sub,text=PhaseName)
1920                E,SGData = G2spc.SpcGroup(controls[13])
1921                G2frame.PatternTree.SetItemPyData(sub, \
1922                    G2IO.SetNewPhase(Name=PhaseName,SGData=SGData,cell=cell[1:]))
1923                Status.SetStatusText('Change space group from '+str(controls[13])+' if needed')
1924        finally:
1925            dlg.Destroy()
1926           
1927    if G2frame.dataDisplay:
1928        G2frame.dataFrame.Clear()
1929    G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.IndexMenu)
1930    if not G2frame.dataFrame.GetStatusBar():
1931        Status = G2frame.dataFrame.CreateStatusBar()
1932    G2frame.Bind(wx.EVT_MENU, IndexPeaks, id=G2gd.wxID_INDEXPEAKS)
1933    G2frame.Bind(wx.EVT_MENU, CopyUnitCell, id=G2gd.wxID_COPYCELL)
1934    G2frame.Bind(wx.EVT_MENU, RefineCell, id=G2gd.wxID_REFINECELL)
1935    G2frame.Bind(wx.EVT_MENU, MakeNewPhase, id=G2gd.wxID_MAKENEWPHASE)
1936   
1937    controls,bravais,cells,dmin = data
1938    if len(controls) < 13:              #add cell volume if missing
1939        controls.append(G2lat.calc_V(G2lat.cell2A(controls[6:12])))
1940    if len(controls) < 14:              #add space gropu used in indexing
1941        controls.append(spaceGroups[bravaisSymb.index(controls[5])])
1942    G2frame.PatternTree.SetItemPyData(UnitCellsId,data)            #update with volume
1943    bravaisNames = ['Cubic-F','Cubic-I','Cubic-P','Trigonal-R','Trigonal/Hexagonal-P',
1944        'Tetragonal-I','Tetragonal-P','Orthorhombic-F','Orthorhombic-I','Orthorhombic-C',
1945        'Orthorhombic-P','Monoclinic-C','Monoclinic-P','Triclinic']
1946    cellGUIlist = [[[0,1,2],4,zip([" Unit cell: a = "," Vol = "],["%.5f","%.3f"],[True,False],[0,0])],
1947    [[3,4,5,6],6,zip([" Unit cell: a = "," c = "," Vol = "],["%.5f","%.5f","%.3f"],[True,True,False],[0,2,0])],
1948    [[7,8,9,10],8,zip([" Unit cell: a = "," b = "," c = "," Vol = "],["%.5f","%.5f","%.5f","%.3f"],
1949        [True,True,True,False],[0,1,2,0])],
1950    [[11,12],10,zip([" Unit cell: a = "," b = "," c = "," beta = "," Vol = "],
1951        ["%.5f","%.5f","%.5f","%.3f","%.3f"],[True,True,True,True,False],[0,1,2,4,0])],
1952    [[13,],8,zip([" Unit cell: a = "," b = "," c = "," Vol = "," alpha = "," beta = "," gamma = "],
1953        ["%.5f","%.5f","%.5f","%.3f","%.3f","%.3f","%.3f"],
1954        [True,True,True,False,True,True,True],[0,1,2,0,3,4,5])]]
1955   
1956    G2frame.dataFrame.SetLabel('Unit Cells List')
1957    G2frame.sp = wx.SplitterWindow(G2frame.dataFrame)
1958    G2frame.dataDisplay = wx.Panel(G2frame.sp, style=wx.SUNKEN_BORDER)
1959    G2frame.dataFrame.IndexPeaks.Enable(False)
1960    peaks = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Index Peak List'))
1961    if peaks:
1962        G2frame.dataFrame.IndexPeaks.Enable(True)
1963    G2frame.dataFrame.RefineCell.Enable(False)
1964    if controls[12] > 1.0:                               #if a "real" volume (i.e. not default)
1965        G2frame.dataFrame.RefineCell.Enable(True)   
1966    G2frame.dataFrame.CopyCell.Enable(False)
1967    G2frame.dataFrame.MakeNewPhase.Enable(False)       
1968    if cells:
1969        G2frame.bottom = wx.Panel(G2frame.sp, style=wx.SUNKEN_BORDER)
1970        G2frame.sp.SplitHorizontally(G2frame.dataDisplay,G2frame.bottom,0)
1971        G2frame.dataFrame.CopyCell.Enable(True)
1972        G2frame.dataFrame.MakeNewPhase.Enable(True)       
1973    mainSizer = wx.BoxSizer(wx.VERTICAL)
1974    mainSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Indexing controls: '),0,WACV)
1975    mainSizer.Add((5,5),0)
1976    littleSizer = wx.FlexGridSizer(2,5,5,5)
1977    littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Max Nc/Nobs '),0,WACV)
1978    NcNo = wx.SpinCtrl(G2frame.dataDisplay)
1979    NcNo.SetRange(1,6)
1980    NcNo.SetValue(controls[2])
1981    NcNo.Bind(wx.EVT_SPINCTRL,OnNcNo)
1982    littleSizer.Add(NcNo,0,WACV)
1983    littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Start Volume '),0,WACV)
1984    startVol = wx.TextCtrl(G2frame.dataDisplay,value=str('%d'%(controls[3])),style=wx.TE_PROCESS_ENTER)
1985    startVol.Bind(wx.EVT_TEXT_ENTER,OnStartVol)
1986    startVol.Bind(wx.EVT_KILL_FOCUS,OnStartVol)
1987    littleSizer.Add(startVol,0,WACV)
1988    mainSizer.Add(littleSizer,0)
1989    mainSizer.Add((5,5),0)
1990    mainSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Select Bravais Lattices for indexing: '),
1991        0,WACV)
1992    mainSizer.Add((5,5),0)
1993    littleSizer = wx.FlexGridSizer(2,7,5,5)
1994    bravList = []
1995    bravs = zip(bravais,bravaisNames)
1996    for brav,bravName in bravs:
1997        bravCk = wx.CheckBox(G2frame.dataDisplay,label=bravName)
1998        bravList.append(bravCk.GetId())
1999        bravCk.SetValue(brav)
2000        bravCk.Bind(wx.EVT_CHECKBOX,OnBravais)
2001        littleSizer.Add(bravCk,0,WACV)
2002    mainSizer.Add(littleSizer,0)
2003    mainSizer.Add((5,5),0)
2004   
2005    mainSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Cell Refinement: '),0,WACV)
2006    mainSizer.Add((5,5),0)
2007    littleSizer = wx.BoxSizer(wx.HORIZONTAL)
2008    littleSizer.Add(wx.StaticText(G2frame.dataDisplay,label=" Bravais lattice "),0,WACV)
2009    bravSel = wx.Choice(G2frame.dataDisplay,choices=bravaisSymb)
2010    bravSel.SetSelection(bravaisSymb.index(controls[5]))
2011    bravSel.Bind(wx.EVT_CHOICE,OnBravSel)
2012    littleSizer.Add(bravSel,0,WACV)
2013    littleSizer.Add(wx.StaticText(G2frame.dataDisplay,label=" Space group "),0,WACV)
2014    spcSel = wx.Choice(G2frame.dataDisplay,choices=SPGlist[controls[5]])
2015    spcSel.SetSelection(SPGlist[controls[5]].index(controls[13]))
2016    spcSel.Bind(wx.EVT_CHOICE,OnSpcSel)
2017    littleSizer.Add(spcSel,0,WACV)
2018    littleSizer.Add(wx.StaticText(G2frame.dataDisplay,label=" Zero offset"),0,WACV)
2019    zero = wx.TextCtrl(G2frame.dataDisplay,value="%.4f"%(controls[1]),style=wx.TE_PROCESS_ENTER)
2020    zero.Bind(wx.EVT_TEXT_ENTER,OnZero)
2021    zero.Bind(wx.EVT_KILL_FOCUS,OnZero)
2022    littleSizer.Add(zero,0,WACV)
2023    zeroVar = wx.CheckBox(G2frame.dataDisplay,label="Refine?")
2024    zeroVar.SetValue(controls[0])
2025    zeroVar.Bind(wx.EVT_CHECKBOX,OnZeroVar)
2026    littleSizer.Add(zeroVar,0,WACV)
2027    hklShow = wx.Button(G2frame.dataDisplay,label="Show hkl positions")
2028    hklShow.Bind(wx.EVT_BUTTON,OnHklShow)
2029    littleSizer.Add(hklShow,0,WACV)
2030    mainSizer.Add(littleSizer,0)
2031   
2032    mainSizer.Add((5,5),0)
2033    ibrav = SetLattice(controls)
2034    for cellGUI in cellGUIlist:
2035        if ibrav in cellGUI[0]:
2036            useGUI = cellGUI
2037    cellList = []
2038    littleSizer = wx.FlexGridSizer(2,useGUI[1],5,5)
2039    for txt,fmt,ifEdit,Id in useGUI[2]:
2040        littleSizer.Add(wx.StaticText(G2frame.dataDisplay,label=txt),0,WACV)
2041        if ifEdit:          #a,b,c,etc.
2042            cellVal = wx.TextCtrl(G2frame.dataDisplay,value=(fmt%(controls[6+Id])),style=wx.TE_PROCESS_ENTER)
2043            cellVal.Bind(wx.EVT_TEXT_ENTER,OnCellChange)       
2044            cellVal.Bind(wx.EVT_KILL_FOCUS,OnCellChange)
2045            littleSizer.Add(cellVal,0,WACV)
2046            cellList.append(cellVal.GetId())
2047        else:               #volume
2048            volVal = wx.TextCtrl(G2frame.dataDisplay,value=(fmt%(controls[12])),style=wx.TE_READONLY)
2049            volVal.SetBackgroundColour(VERY_LIGHT_GREY)
2050            littleSizer.Add(volVal,0,WACV)
2051    mainSizer.Add(littleSizer,0)
2052       
2053    mainSizer.Layout()   
2054    G2frame.dataDisplay.SetSizer(mainSizer)
2055    topSize = mainSizer.Fit(G2frame.dataFrame)
2056    G2frame.dataDisplay.SetSize(topSize)
2057    if cells:
2058        if ibrav == 13:
2059            topSize[1] += 230
2060        else:
2061            topSize[1] += 200
2062    G2frame.dataFrame.setSizePosLeft(topSize)   
2063   
2064    if cells:
2065        bottomSize = topSize        #screwy but bottom doesn't have a size in linux!
2066        bottomSize[0] -= 20         #to reveal slider
2067        if ibrav == 13:
2068            bottomSize[1] -= 240
2069        else:
2070            bottomSize[1] -= 210
2071        wx.StaticText(parent=G2frame.bottom,label=' Indexing Result ')
2072        rowLabels = []
2073        colLabels = ['M20','X20','use','Bravais','a','b','c','alpha','beta','gamma','Volume','Keep']
2074        Types = [wg.GRID_VALUE_FLOAT+':10,2',wg.GRID_VALUE_NUMBER,wg.GRID_VALUE_BOOL,wg.GRID_VALUE_STRING,]+ \
2075            3*[wg.GRID_VALUE_FLOAT+':10,5',]+3*[wg.GRID_VALUE_FLOAT+':10,3',]+ \
2076            [wg.GRID_VALUE_FLOAT+':10,2',wg.GRID_VALUE_BOOL]
2077        numRows = len(cells)
2078        table = []
2079        for cell in cells:
2080            rowLabels.append('')
2081            row = cell[0:2]+[cell[-2]]+[bravaisSymb[cell[2]]]+cell[3:10]+[cell[11],]
2082            if cell[-2]:
2083                A = G2lat.cell2A(cell[3:9])
2084                G2frame.HKL = G2lat.GenHBravais(dmin,cell[2],A)
2085                for hkl in G2frame.HKL:
2086                    hkl.append(2.0*asind(wave/(2.*hkl[3]))+controls[1]+Inst['Zero'][1])             
2087            table.append(row)
2088        UnitCellsTable = G2gd.Table(table,rowLabels=rowLabels,colLabels=colLabels,types=Types)
2089        gridDisplay = G2gd.GSGrid(G2frame.bottom)
2090        gridDisplay.SetPosition(wx.Point(0,20))               
2091        gridDisplay.SetTable(UnitCellsTable, True)
2092        G2frame.dataFrame.CopyCell.Enable(True)
2093        gridDisplay.Bind(wg.EVT_GRID_CELL_LEFT_CLICK,RefreshUnitCellsGrid)
2094        gridDisplay.Bind(wg.EVT_GRID_LABEL_LEFT_DCLICK,OnSortCells)
2095        gridDisplay.SetMargins(0,0)
2096        gridDisplay.SetRowLabelSize(0)
2097        gridDisplay.AutoSizeColumns(False)
2098        for r in range(gridDisplay.GetNumberRows()):
2099            for c in range(gridDisplay.GetNumberCols()):
2100                if c == 2:
2101                    gridDisplay.SetReadOnly(r,c,isReadOnly=False)
2102                else:
2103                    gridDisplay.SetReadOnly(r,c,isReadOnly=True)
2104        gridDisplay.SetSize(bottomSize)
2105
2106################################################################################
2107#####  Reflection list
2108################################################################################           
2109       
2110def UpdateReflectionGrid(G2frame,data,HKLF=False,Name=''):
2111    '''respond to selection of PWDR Reflections data tree item.
2112    '''
2113    if not data:
2114        print 'No phases, no reflections'
2115        return
2116    if HKLF:
2117        G2frame.RefList = 1
2118        phaseName = Name
2119    else:
2120        phaseName = G2frame.RefList
2121        phases = data.keys()
2122   
2123        def OnSelectPhase(event):
2124            dlg = wx.SingleChoiceDialog(G2frame,'Select','Phase',phases)
2125            try:
2126                if dlg.ShowModal() == wx.ID_OK:
2127                    sel = dlg.GetSelection()
2128                    G2frame.RefList = phases[sel]
2129                    UpdateReflectionGrid(G2frame,data)
2130            finally:
2131                dlg.Destroy()
2132            G2plt.PlotPatterns(G2frame)
2133       
2134    if G2frame.dataDisplay:
2135        G2frame.dataFrame.Clear()
2136    rowLabels = []
2137    if HKLF:
2138        G2gd.SetDataMenuBar(G2frame)
2139        refs = data[1]['RefList']
2140    else:       
2141        G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.ReflMenu)
2142        if not G2frame.dataFrame.GetStatusBar():
2143            Status = G2frame.dataFrame.CreateStatusBar()   
2144        G2frame.Bind(wx.EVT_MENU, OnSelectPhase, id=G2gd.wxID_SELECTPHASE)
2145        G2frame.dataFrame.SelectPhase.Enable(False)
2146        if len(data) > 1:
2147            G2frame.dataFrame.SelectPhase.Enable(True)
2148        try:            #patch for old reflection lists
2149            refList = np.array(data[G2frame.RefList]['RefList'])
2150            I100 = refList.T[8]*refList.T[11]
2151        except TypeError:
2152            refList = np.array([refl[:11] for refl in data[G2frame.RefList]])
2153            I100 = refList.T[8]*np.array([refl[13] for refl in data[G2frame.RefList]])
2154        Imax = np.max(I100)
2155        if Imax:
2156            I100 *= 100.0/Imax
2157        refs = np.vstack((refList.T[:11],I100)).T
2158    for i in range(len(refs)): rowLabels.append(str(i))
2159    if HKLF:
2160        colLabels = ['H','K','L','mul','d','Fosq','sig','Fcsq','FoTsq','FcTsq','phase',]
2161    else:
2162        colLabels = ['H','K','L','mul','d','pos','sig','gam','Fosq','Fcsq','phase','I100',]
2163    Types = 4*[wg.GRID_VALUE_LONG,]+4*[wg.GRID_VALUE_FLOAT+':10,4',]+ \
2164        2*[wg.GRID_VALUE_FLOAT+':10,2',]+[wg.GRID_VALUE_FLOAT+':10,3',]+ \
2165        [wg.GRID_VALUE_FLOAT+':10,2',]
2166    G2frame.PeakTable = G2gd.Table(refs,rowLabels=rowLabels,colLabels=colLabels,types=Types)
2167    G2frame.dataFrame.SetLabel('Reflection List for '+phaseName)
2168    G2frame.dataDisplay = G2gd.GSGrid(parent=G2frame.dataFrame)
2169    G2frame.dataDisplay.SetTable(G2frame.PeakTable, True)
2170    G2frame.dataDisplay.EnableEditing(False)
2171    G2frame.dataDisplay.SetMargins(0,0)
2172    G2frame.dataDisplay.AutoSizeColumns(False)
2173    G2frame.dataDisplay.Fit()
2174    size = G2frame.dataDisplay.GetSize()
2175    G2frame.dataFrame.setSizePosLeft([size[0]+32,350])
2176   
2177################################################################################
2178#####  SASD Substances
2179################################################################################
2180           
2181def UpdateSubstanceGrid(G2frame,data):
2182    '''respond to selection of SASD Substance data tree item.
2183    '''
2184    import Substances as substFile
2185   
2186    def OnLoadSubstance(event):
2187        names = substFile.Substances.keys()
2188        names.sort()
2189        dlg = wx.SingleChoiceDialog(G2frame, 'Which substance?', 'Select substance', names, wx.CHOICEDLG_STYLE)
2190        try:
2191            if dlg.ShowModal() == wx.ID_OK:
2192                name = names[dlg.GetSelection()]
2193            else:
2194                return
2195        finally:
2196            dlg.Destroy()
2197        data['Substances'][name] = {'Elements':{},'Volume':1.0,'Density':1.0,
2198            'Scatt density':0.0,'XAnom density':0.0,'XAbsorption':0.0}
2199        subst = substFile.Substances[name]
2200        ElList = subst['Elements'].keys()
2201        for El in ElList:
2202            Info = G2elem.GetAtomInfo(El.strip().upper())
2203            Info.update(subst['Elements'][El])
2204            data['Substances'][name]['Elements'][El] = Info
2205            if 'Volume' in subst:
2206                data['Substances'][name]['Volume'] = subst['Volume']
2207                data['Substances'][name]['Density'] = \
2208                    G2mth.Vol2Den(data['Substances'][name]['Elements'],data['Substances'][name]['Volume'])
2209            elif 'Density' in subst:
2210                data['Substances'][name]['Density'] = subst['Density']
2211                data['Substances'][name]['Volume'] = \
2212                    G2mth.Den2Vol(data['Substances'][name]['Elements'],data['Substances'][name]['Density'])
2213            else:
2214                data['Substances'][name]['Volume'] = G2mth.El2EstVol(data['Substances'][name]['Elements'])
2215                data['Substances'][name]['Density'] = \
2216                    G2mth.Vol2Den(data['Substances'][name]['Elements'],data['Substances'][name]['Volume'])
2217            data['Substances'][name]['Scatt density'] = \
2218                G2mth.XScattDen(data['Substances'][name]['Elements'],data['Substances'][name]['Volume'])[0]
2219            contrst,absorb = G2mth.XScattDen(data['Substances'][name]['Elements'],data['Substances'][name]['Volume'],wave)         
2220            data['Substances'][name]['XAnom density'] = contrst
2221            data['Substances'][name]['XAbsorption'] = absorb
2222                         
2223        UpdateSubstanceGrid(G2frame,data)
2224       
2225    def OnCopySubstance(event):
2226        histList = ['All',]+G2gd.GetPatternTreeDataNames(G2frame,['SASD',])
2227        copyList = []
2228        dlg = wx.MultiChoiceDialog(G2frame, 
2229            'Copy substances to which histograms?', 'Copy substances', 
2230            histList, wx.CHOICEDLG_STYLE)
2231        try:
2232            if dlg.ShowModal() == wx.ID_OK:
2233                result = dlg.GetSelections()
2234                for i in result: 
2235                    copyList.append(histList[i])
2236                if 'All' in copyList: 
2237                    copyList = histList[1:]
2238            for item in copyList:
2239                Id = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,item)
2240                G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,Id,'Substances'),
2241                    copy.copy(data))
2242        finally:
2243            dlg.Destroy()       
2244   
2245    def OnAddSubstance(event):
2246        dlg = wx.TextEntryDialog(None,'Enter a name for this substance','Substance Name Entry','New substance',
2247            style=wx.OK)
2248        if dlg.ShowModal() == wx.ID_OK:
2249            Name = dlg.GetValue()
2250            data['Substances'][Name] = {'Elements':{},'Volume':1.0,'Density':1.0,
2251                'Scatt density':0.0,'XAnom density':0.,'XAbsorption':0.}
2252        dlg.Destroy()
2253        AddElement(Name)
2254        UpdateSubstanceGrid(G2frame,data)
2255       
2256    def OnDeleteSubstance(event):
2257        TextList = []
2258        for name in data['Substances']:
2259            if name != 'vacuum':
2260                TextList += [name,]
2261        if not TextList:
2262            return
2263        dlg = wx.SingleChoiceDialog(G2frame, 'Which substance?', 'Select substance to delete', TextList, wx.CHOICEDLG_STYLE)
2264        try:
2265            if dlg.ShowModal() == wx.ID_OK:
2266                name = TextList[dlg.GetSelection()]
2267            else:
2268                return
2269        finally:
2270            dlg.Destroy()
2271        del(data['Substances'][name])
2272        UpdateSubstanceGrid(G2frame,data)       
2273               
2274    def OnAddElement(event):       
2275        TextList = []
2276        for name in data['Substances']:
2277            if name != 'vacuum':
2278                TextList += [name,]
2279        if not TextList:
2280            return
2281        dlg = wx.SingleChoiceDialog(G2frame, 'Which substance?', 'Select substance', TextList, wx.CHOICEDLG_STYLE)
2282        try:
2283            if dlg.ShowModal() == wx.ID_OK:
2284                name = TextList[dlg.GetSelection()]
2285            else:
2286                return
2287        finally:
2288            dlg.Destroy()
2289        AddElement(name)
2290        UpdateSubstanceGrid(G2frame,data)
2291       
2292    def AddElement(name):
2293        ElList = data['Substances'][name]['Elements'].keys()
2294        dlg = G2elemGUI.PickElements(G2frame,ElList)
2295        if dlg.ShowModal() == wx.ID_OK:
2296            for El in dlg.Elem:
2297                El = El.strip().upper()
2298                Info = G2elem.GetAtomInfo(El)
2299                Info.update({'Num':1})
2300                data['Substances'][name]['Elements'][El] = Info
2301                data['Substances'][name]['Volume'] = G2mth.El2EstVol(data['Substances'][name]['Elements'])
2302                data['Substances'][name]['Density'] = \
2303                    G2mth.Vol2Den(data['Substances'][name]['Elements'],data['Substances'][name]['Volume'])
2304                data['Substances'][name]['Scatt density'] = \
2305                    G2mth.XScattDen(data['Substances'][name]['Elements'],data['Substances'][name]['Volume'])[0]
2306                contrst,absorb = G2mth.XScattDen(data['Substances'][name]['Elements'],data['Substances'][name]['Volume'],wave)         
2307                data['Substances'][name]['XAnom density'] = contrst
2308                data['Substances'][name]['XAbsorption'] = absorb
2309        dlg.Destroy()
2310       
2311       
2312    def OnDeleteElement(event):
2313        TextList = []
2314        for name in data['Substances']:
2315            if name != 'vacuum':
2316                TextList += [name,]
2317        if not TextList:
2318            return
2319        dlg = wx.SingleChoiceDialog(G2frame, 'Which substance?', 'Select substance', TextList, wx.CHOICEDLG_STYLE)
2320        try:
2321            if dlg.ShowModal() == wx.ID_OK:
2322                name = TextList[dlg.GetSelection()]
2323            else:
2324                return
2325        finally:
2326            dlg.Destroy()
2327        ElList = data['Substances'][name]['Elements'].keys()
2328        if len(ElList):
2329            DE = G2elemGUI.DeleteElement(G2frame,ElList)
2330            if DE.ShowModal() == wx.ID_OK:
2331                El = DE.GetDeleteElement().strip().upper()
2332                del(data['Substances'][name]['Elements'][El])
2333                data['Substances'][name]['Volume'] = G2mth.El2EstVol(data['Substances'][name]['Elements'])
2334                data['Substances'][name]['Density'] = \
2335                    G2mth.Vol2Den(data['Substances'][name]['Elements'],data['Substances'][name]['Volume'])
2336                data['Substances'][name]['Scatt density'] = \
2337                    G2mth.XScattDen(data['Substances'][name]['Elements'],data['Substances'][name]['Volume'])[0]
2338                contrst,absorb = G2mth.XScattDen(data['Substances'][name]['Elements'],data['Substances'][name]['Volume'],wave)         
2339                data['Substances'][name]['XAnom density'] = contrst
2340                data['Substances'][name]['XAbsorption'] = absorb
2341        UpdateSubstanceGrid(G2frame,data)
2342               
2343    def SubstSizer():
2344       
2345        def OnValueChange(event):
2346            Obj = event.GetEventObject()
2347            if len(Indx[Obj.GetId()]) == 3:
2348                name,El,keyId = Indx[Obj.GetId()]
2349                try:
2350                    value = max(0,float(Obj.GetValue()))
2351                except ValueError:
2352                    value = 0
2353                    Obj.SetValue('%.2f'%(value))
2354                data['Substances'][name]['Elements'][El][keyId] = value
2355                data['Substances'][name]['Volume'] = G2mth.El2EstVol(data['Substances'][name]['Elements'])
2356                data['Substances'][name]['Density'] = \
2357                    G2mth.Vol2Den(data['Substances'][name]['Elements'],data['Substances'][name]['Volume'])
2358            else:
2359                name,keyId = Indx[Obj.GetId()]
2360                try:
2361                    value = max(0,float(Obj.GetValue()))
2362                except ValueError:
2363                    value = 1.0
2364                data['Substances'][name][keyId] = value
2365                if keyId in 'Volume':
2366                    data['Substances'][name]['Density'] = \
2367                        G2mth.Vol2Den(data['Substances'][name]['Elements'],value)
2368                elif keyId in 'Density':
2369                    data['Substances'][name]['Volume'] = \
2370                        G2mth.Den2Vol(data['Substances'][name]['Elements'],value)
2371            data['Substances'][name]['Scatt density'] = \
2372                G2mth.XScattDen(data['Substances'][name]['Elements'],data['Substances'][name]['Volume'])[0]
2373            contrst,absorb = G2mth.XScattDen(data['Substances'][name]['Elements'],data['Substances'][name]['Volume'],wave)         
2374            data['Substances'][name]['XAnom density'] = contrst
2375            data['Substances'][name]['XAbsorption'] = absorb
2376            UpdateSubstanceGrid(G2frame,data)
2377       
2378        Indx = {}
2379        Pwr10 = unichr(0x0b9)+unichr(0x0b0)
2380        Pwrm2 = unichr(0x207b)+unichr(0x0b2)
2381        Pwrm1 = unichr(0x207b)+unichr(0x0b9)
2382        substSizer = wx.BoxSizer(wx.VERTICAL)
2383        substSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Substance list: wavelength: %.5fA'%(wave)),
2384            0,WACV)
2385        for name in data['Substances']:
2386            G2gd.HorizontalLine(substSizer,G2frame.dataDisplay)   
2387            substSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Data for '+name+':'),
2388                0,WACV)
2389            if name == 'vacuum':
2390                substSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label='        Not applicable'),
2391                    0,WACV)
2392            else:   
2393                elSizer = wx.FlexGridSizer(1,6,5,5)
2394                Substance = data['Substances'][name]
2395                Elems = Substance['Elements']
2396                for El in Elems:
2397                    elSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' '+El+': '),
2398                        0,WACV)
2399                    num = wx.TextCtrl(G2frame.dataDisplay,value='%.2f'%(Elems[El]['Num']),style=wx.TE_PROCESS_ENTER)
2400                    Indx[num.GetId()] = [name,El,'Num']
2401                    num.Bind(wx.EVT_TEXT_ENTER,OnValueChange)       
2402                    num.Bind(wx.EVT_KILL_FOCUS,OnValueChange)
2403                    elSizer.Add(num,0,WACV)
2404                substSizer.Add(elSizer,0)
2405                vdsSizer = wx.FlexGridSizer(1,4,5,5)
2406                vdsSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Volume: '),
2407                    0,WACV)
2408                vol = wx.TextCtrl(G2frame.dataDisplay,value='%.3f'%(Substance['Volume']),style=wx.TE_PROCESS_ENTER)
2409                Indx[vol.GetId()] = [name,'Volume']
2410                vol.Bind(wx.EVT_TEXT_ENTER,OnValueChange)       
2411                vol.Bind(wx.EVT_KILL_FOCUS,OnValueChange)
2412                vdsSizer.Add(vol,0,WACV)               
2413                vdsSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Density: '),
2414                    0,WACV)
2415                den = wx.TextCtrl(G2frame.dataDisplay,value='%.3f'%(Substance['Density']),style=wx.TE_PROCESS_ENTER)
2416                Indx[den.GetId()] = [name,'Density']
2417                den.Bind(wx.EVT_TEXT_ENTER,OnValueChange)       
2418                den.Bind(wx.EVT_KILL_FOCUS,OnValueChange)
2419                vdsSizer.Add(den,0,WACV)
2420                substSizer.Add(vdsSizer,0)
2421                substSizer.Add(wx.StaticText(G2frame.dataDisplay,
2422                    label=' Scattering density  : %.2f *10%scm%s'%(Substance['Scatt density'],Pwr10,Pwrm2)),
2423                    0,WACV)               
2424                substSizer.Add(wx.StaticText(G2frame.dataDisplay,
2425                    label=' Anomalous density : %.2f *10%scm%s'%(Substance['XAnom density'],Pwr10,Pwrm2)),
2426                    0,WACV)               
2427                substSizer.Add(wx.StaticText(G2frame.dataDisplay,
2428                    label=' X-ray absorption   : %.2f cm%s'%(Substance['XAbsorption'],Pwrm1)),
2429                    0,WACV)               
2430        return substSizer
2431           
2432    Inst = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Instrument Parameters'))[0]
2433    wave = G2mth.getWave(Inst)
2434    if G2frame.dataDisplay:
2435        G2frame.dataFrame.DestroyChildren()
2436    G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.SubstanceMenu)
2437    if not G2frame.dataFrame.GetStatusBar():
2438        Status = G2frame.dataFrame.CreateStatusBar()
2439    G2frame.dataDisplay = wxscroll.ScrolledPanel(G2frame.dataFrame)
2440    G2frame.dataFrame.SetLabel('Substances')
2441    G2frame.dataFrame.Bind(wx.EVT_MENU, OnLoadSubstance, id=G2gd.wxID_LOADSUBSTANCE)   
2442    G2frame.dataFrame.Bind(wx.EVT_MENU, OnAddSubstance, id=G2gd.wxID_ADDSUBSTANCE)
2443    G2frame.dataFrame.Bind(wx.EVT_MENU, OnCopySubstance, id=G2gd.wxID_COPYSUBSTANCE)
2444    G2frame.dataFrame.Bind(wx.EVT_MENU, OnDeleteSubstance, id=G2gd.wxID_DELETESUBSTANCE)   
2445    G2frame.dataFrame.Bind(wx.EVT_MENU, OnAddElement, id=G2gd.wxID_ELEMENTADD)
2446    G2frame.dataFrame.Bind(wx.EVT_MENU, OnDeleteElement, id=G2gd.wxID_ELEMENTDELETE)
2447    mainSizer = wx.BoxSizer(wx.VERTICAL)
2448    mainSizer.Add(SubstSizer(),0)
2449
2450    mainSizer.Layout()   
2451    G2frame.dataDisplay.SetSizer(mainSizer)
2452    G2frame.dataDisplay.SetAutoLayout(1)
2453    G2frame.dataDisplay.SetupScrolling()
2454    Size = mainSizer.Fit(G2frame.dataFrame)
2455    Size[0] += 25
2456    G2frame.dataDisplay.SetSize(Size)
2457    G2frame.dataFrame.setSizePosLeft(Size)   
2458       
2459################################################################################
2460#####  SASD Models
2461################################################################################           
2462       
2463def UpdateModelsGrid(G2frame,data):
2464    '''respond to selection of SASD Models data tree item.
2465    '''
2466    #patches
2467    if 'Current' not in data:
2468        data['Current'] = 'Size dist.'
2469    if 'logBins' not in data['Size']:
2470        data['Size']['logBins'] = True
2471    if 'MinMaxDiam' in data['Size']:
2472        data['Size']['MinDiam'] = 50.
2473        data['Size']['MaxDiam'] = 10000.
2474        del data['Size']['MinMaxDiam']
2475    if isinstance(data['Size']['MaxEnt']['Sky'],float):
2476        data['Size']['MaxEnt']['Sky'] = -3
2477    #end patches
2478   
2479    def OnCopyModel(event):
2480        print 'copy model'
2481        print data
2482       
2483    def OnFitModel(event):
2484        print 'fit model for '+data['Current']
2485        if data['Current'] == 'Size dist.':
2486            G2sasd.SizeDistribution(Profile,ProfDict,Limits,Substances,Sample,data)
2487            G2plt.PlotPatterns(G2frame,plotType='SASD',newPlot=True)
2488            G2plt.PlotSASDSizeDist(G2frame)
2489       
2490    def OnSelectFit(event):
2491        data['Current'] = fitSel.GetValue()
2492        wx.CallAfter(UpdateModelsGrid,G2frame,data)
2493       
2494    def OnValueChange(event):
2495        Obj = event.GetEventObject()
2496        itemKey,ind,fmt = Indx[Obj.GetId()]
2497        try:
2498            value = float(Obj.GetValue())
2499        except ValueError:
2500            value = 0.0
2501        Obj.SetValue(fmt%(value))
2502        data[itemKey][ind] = value
2503       
2504    def OnCheckBox(event):
2505        Obj = event.GetEventObject()
2506        item,ind = Indx[Obj.GetId()]
2507        item[ind] = Obj.GetValue()
2508       
2509    def OnIntVal(event):
2510        Obj = event.GetEventObject()
2511        item,ind,minVal = Indx[Obj.GetId()]
2512        try:
2513            value = int(Obj.GetValue())
2514            if value <= minVal:
2515                raise ValueError
2516        except ValueError:
2517            value = item[ind]
2518            Obj.SetValue(str(value))
2519        item[ind] = value
2520
2521    def SizeSizer():
2522       
2523        def OnShape(event):
2524            data['Size']['Shape'][0] = partsh.GetValue()
2525            wx.CallAfter(UpdateModelsGrid,G2frame,data)
2526           
2527        def OnMethod(event):
2528            data['Size']['Method'] = method.GetValue()
2529            wx.CallAfter(UpdateModelsGrid,G2frame,data)
2530           
2531        def OnPartVal(event):
2532            try:
2533                val = max(0.0,float(partprm.GetValue()))
2534            except ValueError:
2535                val = 1
2536            data['Size']['Shape'][1] = val
2537            partprm.SetValue('%.3f'%(val))
2538           
2539        sizeSizer = wx.BoxSizer(wx.VERTICAL)
2540        sizeSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Size distribution parameters: '),0,WACV)
2541        binSizer = wx.FlexGridSizer(1,7,5,5)
2542        binSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' No. size bins: '),0,WACV)
2543        bins = ['50','100','150','200']
2544        nbins = wx.ComboBox(G2frame.dataDisplay,value=str(data['Size']['Nbins']),choices=bins,
2545            style=wx.CB_READONLY|wx.CB_DROPDOWN)
2546        Indx[nbins.GetId()] = [data['Size'],'Nbins',0]
2547        nbins.Bind(wx.EVT_COMBOBOX,OnIntVal)       
2548        binSizer.Add(nbins,0,WACV)
2549        binSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Min diam.: '),0,WACV)
2550        minDias = ['10','25','50','100','150','200']
2551        mindiam = wx.ComboBox(G2frame.dataDisplay,value=str(data['Size']['MinDiam']),choices=minDias,
2552            style=wx.CB_READONLY|wx.CB_DROPDOWN)
2553        mindiam.Bind(wx.EVT_COMBOBOX,OnIntVal)       
2554        Indx[mindiam.GetId()] = [data['Size'],'MinDiam',0]
2555        binSizer.Add(mindiam,0,WACV)
2556        binSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Max diam.: '),0,WACV)
2557        maxDias = [str(1000*(i+1)) for i in range(10)]
2558        maxdiam = wx.ComboBox(G2frame.dataDisplay,value=str(data['Size']['MaxDiam']),choices=maxDias,
2559            style=wx.CB_DROPDOWN)
2560        maxdiam.Bind(wx.EVT_COMBOBOX,OnIntVal)       
2561        Indx[maxdiam.GetId()] = [data['Size'],'MaxDiam',0]
2562        binSizer.Add(maxdiam,0,WACV)
2563        logbins = wx.CheckBox(G2frame.dataDisplay,label='Log bins?')
2564        Indx[logbins.GetId()] = [data['Size'],'logBins']
2565        logbins.SetValue(data['Size']['logBins'])
2566        logbins.Bind(wx.EVT_CHECKBOX, OnCheckBox)
2567        binSizer.Add(logbins,0,WACV)
2568        sizeSizer.Add(binSizer,0)
2569        sizeSizer.Add((5,5),0)
2570        partSizer = wx.BoxSizer(wx.HORIZONTAL)
2571        partSizer.Add(wx.StaticText(G2frame.dataDisplay,label='Particle description: '),0,WACV)
2572        shapes = {'Spheroid':' Aspect ratio: ','Cylinder':' Diameter ','Cylinder AR':' Aspect ratio: ',
2573            'Unified sphere':'','Unified rod':' Diameter: ','Unified rod AR':' Aspect ratio: ',
2574            'Unified disk':' Thickness: '}
2575        partsh = wx.ComboBox(G2frame.dataDisplay,value=str(data['Size']['Shape'][0]),choices=shapes.keys(),
2576            style=wx.CB_READONLY|wx.CB_DROPDOWN)
2577        partsh.Bind(wx.EVT_COMBOBOX,OnShape)       
2578        partSizer.Add(partsh,0,WACV)
2579        if data['Size']['Shape'][0] not in ['Unified sphere',]:
2580            partSizer.Add(wx.StaticText(G2frame.dataDisplay,label=shapes[data['Size']['Shape'][0]]),0,WACV)
2581            partprm = wx.TextCtrl(G2frame.dataDisplay,value='%.3f'%(data['Size']['Shape'][1]),
2582                style=wx.TE_PROCESS_ENTER)
2583            partprm.Bind(wx.EVT_TEXT_ENTER,OnPartVal)       
2584            partprm.Bind(wx.EVT_KILL_FOCUS,OnPartVal)
2585            partSizer.Add(partprm,0,WACV)
2586        sizeSizer.Add(partSizer,0)
2587        sizeSizer.Add((5,5),0)
2588        fitSizer = wx.BoxSizer(wx.HORIZONTAL)
2589        methods = ['MaxEnt','IPG',]
2590        fitSizer.Add(wx.StaticText(G2frame.dataDisplay,label='Fitting method: '),0,WACV)
2591        method = wx.ComboBox(G2frame.dataDisplay,value=data['Size']['Method'],choices=methods,
2592            style=wx.CB_READONLY|wx.CB_DROPDOWN)
2593        method.Bind(wx.EVT_COMBOBOX,OnMethod)
2594        fitSizer.Add(method,0,WACV)
2595        iters = ['10','25','50','100','150','200']       
2596        fitSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' No. iterations: '),0,WACV)
2597        Method = data['Size']['Method']
2598        iter = wx.ComboBox(G2frame.dataDisplay,value=str(data['Size'][Method]['Niter']),choices=iters,
2599            style=wx.CB_READONLY|wx.CB_DROPDOWN)
2600        Indx[iter.GetId()] = [data['Size'][Method],'Niter',0]
2601        iter.Bind(wx.EVT_COMBOBOX,OnIntVal)
2602        fitSizer.Add(iter,0,WACV)
2603        if 'MaxEnt' in data['Size']['Method']:
2604            fitSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Log floor factor: '),0,WACV)
2605            floors = [str(-i) for i in range(9)]
2606            floor = wx.ComboBox(G2frame.dataDisplay,value=str(data['Size']['MaxEnt']['Sky']),choices=floors,
2607                style=wx.CB_READONLY|wx.CB_DROPDOWN)
2608            Indx[floor.GetId()] = [data['Size']['MaxEnt'],'Sky',-10]
2609            floor.Bind(wx.EVT_COMBOBOX,OnIntVal)
2610            fitSizer.Add(floor,0,WACV)
2611        sizeSizer.Add(fitSizer,0)
2612
2613        return sizeSizer
2614       
2615    def PartSizer():
2616        for item in data['Particle']: print item,data['Particle'][item]
2617        partSizer = wx.BoxSizer(wx.VERTICAL)
2618        partSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Particle fit parameters: '),0,WACV)
2619        return partSizer
2620       
2621    def UnifSizer():
2622        for item in data['Unified']: print item,data['Unified'][item]
2623        unifSizer = wx.BoxSizer(wx.VERTICAL)
2624        unifSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Unified fit parameters: '),0,WACV)
2625        return unifSizer
2626       
2627    def OnEsdScale(event):
2628        try:
2629            value = float(esdScale.GetValue())
2630            if value <= 0.:
2631                raise ValueError
2632        except ValueError:
2633            value = 1./np.sqrt(ProfDict['wtFactor'])
2634        ProfDict['wtFactor'] = 1./value**2
2635        esdScale.SetValue('%.3f'%(value))
2636        G2plt.PlotPatterns(G2frame,plotType='SASD',newPlot=True)
2637       
2638    Sample = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Sample Parameters'))
2639    Limits = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Limits'))
2640    Inst = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Instrument Parameters'))
2641    Substances = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Substances'))
2642    ProfDict,Profile = G2frame.PatternTree.GetItemPyData(G2frame.PatternId)[:2]
2643
2644    if G2frame.dataDisplay:
2645        G2frame.dataFrame.DestroyChildren()
2646    G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.ModelMenu)
2647    if not G2frame.dataFrame.GetStatusBar():
2648        Status = G2frame.dataFrame.CreateStatusBar()
2649    G2frame.dataFrame.SetLabel('Modelling')
2650    G2frame.dataDisplay = wxscroll.ScrolledPanel(G2frame.dataFrame)
2651    G2frame.dataFrame.Bind(wx.EVT_MENU, OnCopyModel, id=G2gd.wxID_MODELCOPY)
2652    G2frame.dataFrame.Bind(wx.EVT_MENU, OnFitModel, id=G2gd.wxID_MODELFIT)
2653    Indx = {}
2654    mainSizer = wx.BoxSizer(wx.VERTICAL)
2655    topSizer = wx.BoxSizer(wx.HORIZONTAL)
2656    models = ['Size dist.','Unified fit','Particle fit']
2657    topSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Modeling by: '),0,WACV)
2658    fitSel = wx.ComboBox(G2frame.dataDisplay,value=data['Current'],choices=models,
2659        style=wx.CB_READONLY|wx.CB_DROPDOWN)
2660    fitSel.Bind(wx.EVT_COMBOBOX,OnSelectFit)       
2661    topSizer.Add(fitSel,0,WACV)
2662    topSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Error multiplier: '),0,WACV)
2663    esdScale = wx.TextCtrl(G2frame.dataDisplay,value='%.3f'%(1./np.sqrt(ProfDict['wtFactor'])),style=wx.TE_PROCESS_ENTER)
2664    esdScale.Bind(wx.EVT_TEXT_ENTER,OnEsdScale)       
2665    esdScale.Bind(wx.EVT_KILL_FOCUS,OnEsdScale)
2666    topSizer.Add(esdScale,0,WACV)
2667    mainSizer.Add(topSizer)
2668    G2gd.HorizontalLine(mainSizer,G2frame.dataDisplay)
2669    if 'Size' in data['Current']:
2670        mainSizer.Add(SizeSizer())       
2671    elif 'Particle' in data['Current']:
2672        mainSizer.Add(PartSizer())
2673    elif 'Unified' in data['Current']:
2674        mainSizer.Add(UnifSizer())
2675    G2gd.HorizontalLine(mainSizer,G2frame.dataDisplay)   
2676    backSizer = wx.BoxSizer(wx.HORIZONTAL)
2677    backSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Background:'),0,WACV)
2678    backVal = wx.TextCtrl(G2frame.dataDisplay,value='%.3g'%(data['Back'][0]),style=wx.TE_PROCESS_ENTER)
2679    Indx[backVal.GetId()] = ['Back',0,'%.3g']
2680    backVal.Bind(wx.EVT_TEXT_ENTER,OnValueChange)       
2681    backVal.Bind(wx.EVT_KILL_FOCUS,OnValueChange)
2682    backSizer.Add(backVal,0,WACV)
2683    backVar = wx.CheckBox(G2frame.dataDisplay,label='Apply?')
2684    Indx[backVar.GetId()] = [data['Back'],1]
2685    backVar.SetValue(data['Back'][1])
2686    backVar.Bind(wx.EVT_CHECKBOX, OnCheckBox)
2687    backSizer.Add(backVar,0,WACV)
2688    mainSizer.Add(backSizer)
2689
2690    mainSizer.Layout()   
2691    G2frame.dataDisplay.SetSizer(mainSizer)
2692    G2frame.dataDisplay.SetAutoLayout(1)
2693    G2frame.dataDisplay.SetupScrolling()
2694    Size = mainSizer.Fit(G2frame.dataFrame)
2695    Size[0] += 25
2696    G2frame.dataDisplay.SetSize(Size)
2697    G2frame.dataFrame.setSizePosLeft(Size)   
2698       
2699   
2700################################################################################
2701#####  PDF controls
2702################################################################################           
2703       
2704def UpdatePDFGrid(G2frame,data):
2705    '''respond to selection of PWDR PDF data tree item.
2706    '''
2707    global inst
2708    tth2q = lambda t,w:4.0*math.pi*sind(t/2.0)/w
2709    dataFile = G2frame.PatternTree.GetItemText(G2frame.PatternId)
2710    powName = 'PWDR'+dataFile[4:]
2711    powId = G2gd.GetPatternTreeItemId(G2frame,G2frame.root, powName)
2712    fullLimits,limits = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,powId, 'Limits'))[:2]
2713    inst = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,powId, 'Instrument Parameters'))[0]
2714    if 'Lam' in inst:
2715        keV = 12.397639/inst['Lam'][1]
2716    else:
2717        keV = 12.397639/inst['Lam1'][0]
2718    wave = 12.397639/keV
2719    qLimits = [tth2q(fullLimits[0],wave),tth2q(fullLimits[1],wave)]
2720    data['QScaleLim'][1] = min(qLimits[1],data['QScaleLim'][1])
2721    if data['QScaleLim'][0]:
2722        data['QScaleLim'][0] = max(qLimits[0],data['QScaleLim'][0])
2723    else:                                #initial setting at 90% of max Q
2724        data['QScaleLim'][0] = 0.90*data['QScaleLim'][1]
2725    polariz = inst['Polariz.'][1]
2726    azimuth = inst['Azimuth'][1]
2727    itemDict = {}
2728   
2729    def FillFileSizer(fileSizer,key):
2730        #fileSizer is a FlexGridSizer(3,6)
2731       
2732        def OnSelectFile(event):
2733            Obj = event.GetEventObject()
2734            fileKey,itemKey,fmt = itemDict[Obj.GetId()]
2735            if itemKey == 'Name':
2736                value = Obj.GetValue()
2737            Obj.SetValue(fmt%(value))
2738            data[fileKey][itemKey] = value
2739            UpdatePDFGrid(G2frame,data)
2740       
2741        def OnValueChange(event):
2742            Obj = event.GetEventObject()
2743            fileKey,itemKey,fmt = itemDict[Obj.GetId()]
2744            try:
2745                value = float(Obj.GetValue())
2746            except ValueError:
2747                value = -1.0
2748            Obj.SetValue(fmt%(value))
2749            data[fileKey][itemKey] = value
2750            auxPlot = ComputePDF(data)
2751            G2plt.PlotISFG(G2frame,newPlot=True)
2752                       
2753        item = data[key]
2754        fileList = np.array(GetFileList('PWDR')).T[1]
2755        fileSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' '+key+' file:'),0,WACV)
2756        fileName = wx.ComboBox(G2frame.dataDisplay,value=item['Name'],choices=fileList,
2757            style=wx.CB_READONLY|wx.CB_DROPDOWN)
2758        itemDict[fileName.GetId()] = [key,'Name','%s']
2759        fileName.Bind(wx.EVT_COMBOBOX,OnSelectFile)       
2760        fileSizer.Add(fileName,0,)
2761        fileSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label='Multiplier:'),0,WACV)
2762        mult = wx.TextCtrl(G2frame.dataDisplay,value='%.3f'%(item['Mult']),style=wx.TE_PROCESS_ENTER)
2763        itemDict[mult.GetId()] = [key,'Mult','%.3f']
2764        mult.Bind(wx.EVT_TEXT_ENTER,OnValueChange)       
2765        mult.Bind(wx.EVT_KILL_FOCUS,OnValueChange)
2766        fileSizer.Add(mult,0,)
2767        fileSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label='Add:'),0,WACV)
2768        add = wx.TextCtrl(G2frame.dataDisplay,value='%.0f'%(item['Add']),style=wx.TE_PROCESS_ENTER)
2769        itemDict[add.GetId()] = [key,'Add','%.0f']
2770        add.Bind(wx.EVT_TEXT_ENTER,OnValueChange)       
2771        add.Bind(wx.EVT_KILL_FOCUS,OnValueChange)
2772        fileSizer.Add(add,0,)
2773       
2774    def SumElementVolumes():
2775        sumVol = 0.
2776        ElList = data['ElList']
2777        for El in ElList:
2778            Avol = (4.*math.pi/3.)*ElList[El]['Drad']**3
2779            sumVol += Avol*ElList[El]['FormulaNo']
2780        return sumVol
2781        auxPlot = ComputePDF(data)
2782        G2plt.PlotISFG(G2frame,newPlot=True)       
2783       
2784    def FillElemSizer(elemSizer,ElData):
2785       
2786        def OnFractionChange(event):
2787            try:
2788                value = max(0.0,float(num.GetValue()))
2789            except ValueError:
2790                value = 0.0
2791            num.SetValue('%.3f'%(value))
2792            ElData['FormulaNo'] = value
2793            data['Form Vol'] = max(10.0,SumElementVolumes())
2794            formVol.SetValue('%.2f'%(data['Form Vol']))
2795            wx.CallAfter(UpdatePDFGrid,G2frame,data)
2796            auxPlot = ComputePDF(data)
2797            G2plt.PlotISFG(G2frame,newPlot=True)       
2798       
2799        elemSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,
2800            label=' Element: '+'%2s'%(ElData['Symbol'])+' * '),0,WACV)
2801        num = wx.TextCtrl(G2frame.dataDisplay,value='%.3f'%(ElData['FormulaNo']),style=wx.TE_PROCESS_ENTER)
2802        num.Bind(wx.EVT_TEXT_ENTER,OnFractionChange)       
2803        num.Bind(wx.EVT_KILL_FOCUS,OnFractionChange)
2804        elemSizer.Add(num,0,WACV)
2805        elemSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,
2806            label="f': %.3f"%(ElData['fp'])+' f": %.3f'%(ElData['fpp'])+' mu: %.2f barns'%(ElData['mu']) ),
2807            0,WACV)
2808           
2809    def OnGeometry(event):
2810        data['Geometry'] = geometry.GetValue()
2811        UpdatePDFGrid(G2frame,data)
2812        auxPlot = ComputePDF(data)
2813        G2plt.PlotISFG(G2frame,newPlot=True)       
2814       
2815    def OnDetType(event):
2816        data['DetType'] = detType.GetValue()
2817        UpdatePDFGrid(G2frame,data)
2818        auxPlot = ComputePDF(data)
2819        G2plt.PlotISFG(G2frame,newPlot=True)       
2820       
2821    def OnFormVol(event):
2822        try:
2823            value = float(formVol.GetValue())
2824            if value <= 0.0:
2825                raise ValueError
2826        except ValueError:
2827            value = data['Form Vol']
2828        data['Form Vol'] = value
2829        UpdatePDFGrid(G2frame,data)
2830        auxPlot = ComputePDF(data)
2831        G2plt.PlotISFG(G2frame,newPlot=False)       
2832       
2833    def OnDiameter(event):
2834        try:
2835            value = float(diam.GetValue())
2836            if value <= 0.0:
2837                raise ValueError
2838        except ValueError:
2839            value = data['Diam']
2840        data['Diam'] = value
2841        UpdatePDFGrid(G2frame,data)
2842        auxPlot = ComputePDF(data)
2843        G2plt.PlotISFG(G2frame,newPlot=False)
2844       
2845    def OnPolaVal(event):
2846        try:
2847            value = float(polaVal.GetValue())
2848            if not (0.0 <= value <= 1.0):
2849                raise ValueError
2850        except ValueError:
2851            value = inst['Polariz.'][1]
2852        inst['Polariz.'][1] = value
2853        polaVal.SetValue('%.2f'%(inst['Polariz.'][1]))
2854        UpdatePDFGrid(G2frame,data)
2855        auxPlot = ComputePDF(data)
2856        G2plt.PlotISFG(G2frame,newPlot=False)
2857               
2858    def OnAzimVal(event):
2859        try:
2860            value = float(azimVal.GetValue())
2861            if not (0. <= value <= 360.):
2862                raise ValueError
2863        except ValueError:
2864            value = inst['Azimuth'][1]
2865        inst['Azimuth'][1] = value
2866        azimVal.SetValue('%.1f'%(inst['Azimuth'][1]))
2867        UpdatePDFGrid(G2frame,data)
2868        auxPlot = ComputePDF(data)
2869        G2plt.PlotISFG(G2frame,newPlot=False)
2870                       
2871    def OnObliqCoeff(event):
2872        try:
2873            value = float(obliqCoeff.GetValue())
2874            if value < 0.0:
2875                raise ValueError
2876            elif value > 1.0:
2877                value = 1.0
2878        except ValueError:
2879            value = data['ObliqCoeff']
2880        data['ObliqCoeff'] = value
2881        obliqCoeff.SetValue('%.3f'%(value))
2882        auxPlot = ComputePDF(data)
2883        G2plt.PlotISFG(G2frame,newPlot=False)
2884       
2885    def OnRulandWdt(event):
2886        try:
2887            value = float(rulandWdt.GetValue())
2888            if value <= 0.001:
2889                raise ValueError
2890            elif value > 1.0:
2891                value = 1.0
2892        except ValueError:
2893            value = data['Ruland']
2894        data['Ruland'] = value
2895        rulandWdt.SetValue('%.3f'%(value))
2896        auxPlot = ComputePDF(data)
2897        G2plt.PlotISFG(G2frame,newPlot=False)
2898       
2899    def OnRulSlider(event):
2900        value = int(rulandSldr.GetValue())/1000.
2901        data['Ruland'] = max(0.001,value)
2902        rulandWdt.SetValue('%.3f'%(data['Ruland']))
2903        auxPlot = ComputePDF(data)
2904        G2plt.PlotISFG(G2frame,newPlot=False)
2905       
2906    def OnLorch(event):
2907        data['Lorch'] = lorch.GetValue()
2908        auxPlot = ComputePDF(data)
2909        G2plt.PlotISFG(G2frame,newPlot=False)       
2910                       
2911    def OnPacking(event):
2912        try:
2913            value = float(pack.GetValue())
2914            if value <= 0.0:
2915                raise ValueError
2916        except ValueError:
2917            value = data['Pack']
2918        data['Pack'] = value
2919        UpdatePDFGrid(G2frame,data)
2920        auxPlot = ComputePDF(data)
2921        G2plt.PlotISFG(G2frame,newPlot=False)       
2922               
2923    def OnSQmin(event):
2924        try:
2925            value = float(SQmin.GetValue())
2926            if value < qLimits[0]:
2927                raise ValueError
2928        except ValueError:
2929            value = max(qLimits[0],data['QScaleLim'][0])
2930        data['QScaleLim'][0] = value
2931        SQmin.SetValue('%.1f'%(value))
2932        auxPlot = ComputePDF(data)
2933        G2plt.PlotISFG(G2frame,newPlot=True)       
2934       
2935    def OnSQmax(event):
2936        try:
2937            value = float(SQmax.GetValue())
2938            if value > qLimits[1]:
2939                raise ValueError
2940        except ValueError:
2941            value = min(qLimits[1],data['QScaleLim'][1])
2942        data['QScaleLim'][1] = value
2943        if value < data['QScaleLim'][0]:
2944            data['QScaleLim'][0] = 0.90*value
2945            SQmin.SetValue('%.1f'%(data['QScaleLim'][0]))
2946        SQmax.SetValue('%.1f'%(value))
2947        auxPlot = ComputePDF(data)
2948        G2plt.PlotISFG(G2frame,newPlot=True)
2949       
2950    def OnResetQ(event):
2951        resetQ.SetValue(False)
2952        data['QScaleLim'][1] = qLimits[1]
2953        SQmax.SetValue('%.1f'%(data['QScaleLim'][1]))
2954        data['QScaleLim'][0] = 0.9*qLimits[1]
2955        SQmin.SetValue('%.1f'%(data['QScaleLim'][0]))
2956        auxPlot = ComputePDF(data)
2957        G2plt.PlotISFG(G2frame,newPlot=True)       
2958
2959    def GetFileList(fileType,skip=None):
2960        fileList = [[False,'',0]]
2961        Source = ''
2962        id, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root)
2963        while id:
2964            name = G2frame.PatternTree.GetItemText(id)
2965            if fileType in name:
2966                if id == skip:
2967                    Source = name
2968                else:
2969                    fileList.append([False,name,id])
2970            id, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie)
2971        if skip:
2972            return fileList,Source
2973        else:
2974            return fileList
2975       
2976    def OnCopyPDFControls(event):
2977        import copy
2978        TextList,Source = GetFileList('PDF',skip=G2frame.PatternId)
2979        TextList[0] = [False,'All PDF',0]
2980        if len(TextList) == 1:
2981            G2frame.ErrorDialog('Nothing to copy controls to','There must be more than one "PDF" pattern')
2982            return
2983        dlg = G2frame.CopyDialog(G2frame,'Copy PDF controls','Copy controls from '+Source+' to:',TextList)
2984        try:
2985            if dlg.ShowModal() == wx.ID_OK:
2986                result = dlg.GetData()
2987                if result[0][0]:
2988                    result = TextList[1:]
2989                    for item in result: item[0] = True
2990                for i,item in enumerate(result):
2991                    ifcopy,name,id = item
2992                    if ifcopy:
2993                        olddata = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,id, 'PDF Controls'))
2994                        sample = olddata['Sample']
2995                        olddata.update(copy.deepcopy(data))
2996                        olddata['Sample'] = sample
2997                        G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,id, 'PDF Controls'),olddata)
2998                Status.SetStatusText('PDF controls copied')
2999        finally:
3000            dlg.Destroy()
3001               
3002    def OnSavePDFControls(event):
3003        print 'save PDF controls?'
3004       
3005    def OnLoadPDFControls(event):
3006        print 'Load PDF controls?'
3007       
3008    def OnAddElement(event):
3009        ElList = data['ElList']
3010        PE = G2elemGUI.PickElement(G2frame,oneOnly=True)
3011        if PE.ShowModal() == wx.ID_OK:
3012            El = PE.Elem
3013            if El not in ElList and El != 'None':
3014                ElemSym = El.strip().upper()               
3015                FpMu = G2elem.FPcalc(G2elem.GetXsectionCoeff(ElemSym), keV)
3016                ElData = G2elem.GetFormFactorCoeff(ElemSym)[0]
3017                ElData['FormulaNo'] = 0.0
3018                ElData.update(G2elem.GetAtomInfo(ElemSym))
3019                ElData.update(dict(zip(['fp','fpp','mu'],FpMu)))
3020                ElData.update(G2elem.GetFFC5(El))
3021                data['ElList'][El] = ElData
3022            data['Form Vol'] = max(10.0,SumElementVolumes())
3023        PE.Destroy()
3024        UpdatePDFGrid(G2frame,data)
3025       
3026    def OnDeleteElement(event):
3027        ElList = data['ElList']
3028        choice = ElList.keys()
3029        dlg = G2elemGUI.DeleteElement(G2frame,choice=choice)
3030        if dlg.ShowModal() == wx.ID_OK:
3031            del ElList[dlg.GetDeleteElement()]
3032        dlg.Destroy()
3033        UpdatePDFGrid(G2frame,data)
3034               
3035    def ComputePDF(Data):
3036        xydata = {}
3037        for key in ['Sample','Sample Bkg.','Container','Container Bkg.']:
3038            name = Data[key]['Name']
3039            if name:
3040                xydata[key] = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.root,name))
3041                PDFname = name
3042        powName = xydata['Sample'][2]
3043        powId = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,powName)
3044        inst = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,powId,'Instrument Parameters'))[0]
3045        auxPlot = G2pwd.CalcPDF(Data,inst,xydata)
3046        PDFId = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,'PDF '+powName[4:])
3047        G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PDFId,'I(Q)'+powName[4:]),xydata['IofQ'])
3048        G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PDFId,'S(Q)'+powName[4:]),xydata['SofQ'])
3049        G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PDFId,'F(Q)'+powName[4:]),xydata['FofQ'])
3050        G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PDFId,'G(R)'+powName[4:]),xydata['GofR'])
3051        return auxPlot
3052       
3053    def OnComputePDF(event):
3054        print 'Calculating PDF:'
3055        auxPlot = ComputePDF(data)
3056        print 'Done calculating PDF:'
3057        Status.SetStatusText('PDF computed')
3058        for plot in auxPlot:
3059            G2plt.PlotXY(G2frame,plot[:2],type=plot[2])
3060       
3061        G2plt.PlotISFG(G2frame,newPlot=True,type='I(Q)')
3062        G2plt.PlotISFG(G2frame,newPlot=True,type='S(Q)')
3063        G2plt.PlotISFG(G2frame,newPlot=True,type='F(Q)')
3064        G2plt.PlotISFG(G2frame,newPlot=True,type='G(R)')
3065       
3066    def OnComputeAllPDF(event):
3067        print 'Calculating PDFs:'
3068        if G2frame.PatternTree.GetCount():
3069            id, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root)
3070            while id:
3071                Name = G2frame.PatternTree.GetItemText(id)
3072                if 'PDF' in Name:
3073                    Data = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,id,'PDF Controls'))
3074                    auxPlot = ComputePDF(Data)                   
3075                id, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie)
3076            Status.SetStatusText('All PDFs computed')
3077            G2plt.PlotISFG(G2frame,newPlot=True,type='G(R)')
3078            print ' Done calculating PDFs:'
3079       
3080    def OnShowTip(G2frame,tip):
3081        print tip   
3082               
3083    if G2frame.dataDisplay:
3084        G2frame.dataFrame.Clear()
3085    G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.PDFMenu)
3086    if not G2frame.dataFrame.GetStatusBar():
3087        Status = G2frame.dataFrame.CreateStatusBar()   
3088    G2frame.dataDisplay = wx.Panel(G2frame.dataFrame)
3089    G2frame.dataFrame.Bind(wx.EVT_MENU, OnCopyPDFControls, id=G2gd.wxID_PDFCOPYCONTROLS)
3090    G2frame.dataFrame.Bind(wx.EVT_MENU, OnSavePDFControls, id=G2gd.wxID_PDFSAVECONTROLS)
3091    G2frame.dataFrame.Bind(wx.EVT_MENU, OnLoadPDFControls, id=G2gd.wxID_PDFLOADCONTROLS)
3092    G2frame.dataFrame.Bind(wx.EVT_MENU, OnAddElement, id=G2gd.wxID_PDFADDELEMENT)
3093    G2frame.dataFrame.Bind(wx.EVT_MENU, OnDeleteElement, id=G2gd.wxID_PDFDELELEMENT)
3094    G2frame.dataFrame.Bind(wx.EVT_MENU, OnComputePDF, id=G2gd.wxID_PDFCOMPUTE)
3095    G2frame.dataFrame.Bind(wx.EVT_MENU, OnComputeAllPDF, id=G2gd.wxID_PDFCOMPUTEALL)
3096    mainSizer = wx.BoxSizer(wx.VERTICAL)
3097    mainSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' PDF data files: '),0,WACV)
3098    mainSizer.Add((5,5),0)
3099    str = ' Sample file: PWDR %s   Wavelength, A: %.5f  Energy, keV: %.3f  Polariz.: %.2f '%(dataFile[3:],wave,keV,polariz)
3100    mainSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=str),0,WACV)
3101#    dataSizer = wx.BoxSizer(wx.HORIZONTAL)
3102#    dataSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label='Azimuth'),0,WACV)
3103#    azimVal = wx.TextCtrl(G2frame.dataDisplay,value='%.2f'%(inst['Azimuth']))
3104#    azimVal.Bind(wx.EVT_TEXT_ENTER,OnAzimVal)       
3105#    azimVal.Bind(wx.EVT_KILL_FOCUS,OnAzimVal)
3106#    dataSizer.Add(azimVal,0)   
3107#    dataSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label='Polarization'),0,WACV)
3108#    polaVal = wx.TextCtrl(G2frame.dataDisplay,value='%.2f'%(inst['Polariz.']))
3109#    polaVal.Bind(wx.EVT_TEXT_ENTER,OnPolaVal)       
3110#    polaVal.Bind(wx.EVT_KILL_FOCUS,OnPolaVal)
3111#    dataSizer.Add(polaVal,0)   
3112#    mainSizer.Add(dataSizer,0)
3113    mainSizer.Add((5,5),0)
3114    fileSizer = wx.FlexGridSizer(3,6,5,1)
3115    select = ['Sample Bkg.','Container']
3116    if data['Container']['Name']:
3117        select.append('Container Bkg.')
3118    for key in select:
3119        FillFileSizer(fileSizer,key)
3120    mainSizer.Add(fileSizer,0)
3121    mainSizer.Add((5,5),0)
3122    mainSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Sample information: '),0,WACV)
3123    mainSizer.Add((5,5),0)   
3124
3125    ElList = data['ElList']
3126    Abs = G2lat.CellAbsorption(ElList,data['Form Vol'])
3127    Trans = G2pwd.Transmission(data['Geometry'],Abs*data['Pack'],data['Diam'])
3128    elemSizer = wx.FlexGridSizer(3,3,5,1)
3129    for El in ElList:
3130        FillElemSizer(elemSizer,ElList[El])
3131    mainSizer.Add(elemSizer,0)
3132    mainSizer.Add((5,5),0)   
3133    midSizer = wx.BoxSizer(wx.HORIZONTAL)
3134    midSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Formula volume: '),0,WACV)
3135    formVol = wx.TextCtrl(G2frame.dataDisplay,value='%.2f'%(data['Form Vol']))
3136    formVol.Bind(wx.EVT_TEXT_ENTER,OnFormVol)       
3137    formVol.Bind(wx.EVT_KILL_FOCUS,OnFormVol)
3138    midSizer.Add(formVol,0)
3139    midSizer.Add(wx.StaticText(G2frame.dataDisplay,
3140        label=' Theoretical absorption: %.4f cm-1 Sample absorption: %.4f cm-1'%(Abs,Abs*data['Pack'])),
3141        0,WACV)
3142    mainSizer.Add(midSizer,0)
3143    mainSizer.Add((5,5),0)   
3144
3145    geoBox = wx.BoxSizer(wx.HORIZONTAL)
3146    geoBox.Add(wx.StaticText(G2frame.dataDisplay,label=' Sample geometry: '),0,WACV)
3147    choice = ['Cylinder','Bragg-Brentano','Tilting flat plate in transmission','Fixed flat plate']
3148    geometry = wx.ComboBox(G2frame.dataDisplay,value=data['Geometry'],choices=choice,
3149            style=wx.CB_READONLY|wx.CB_DROPDOWN)
3150    geometry.Bind(wx.EVT_COMBOBOX, OnGeometry)
3151    geoBox.Add(geometry,0)
3152    geoBox.Add(wx.StaticText(G2frame.dataDisplay,label=' Sample diameter/thickness, mm: '),0,WACV)
3153    diam = wx.TextCtrl(G2frame.dataDisplay,value='%.3f'%(data['Diam']))
3154    diam.Bind(wx.EVT_TEXT_ENTER,OnDiameter)       
3155    diam.Bind(wx.EVT_KILL_FOCUS,OnDiameter)
3156#    diam.Bind(wx.EVT_SET_FOCUS,OnShowTip(G2frame,'tip')) #this doesn't work - what would????
3157    geoBox.Add(diam,0)
3158    mainSizer.Add(geoBox,0)
3159    mainSizer.Add((5,5),0)   
3160    geoBox = wx.BoxSizer(wx.HORIZONTAL)
3161    geoBox.Add(wx.StaticText(G2frame.dataDisplay,label=' Packing: '),0,WACV)
3162    pack = wx.TextCtrl(G2frame.dataDisplay,value='%.2f'%(data['Pack']))
3163    pack.Bind(wx.EVT_TEXT_ENTER,OnPacking)       
3164    pack.Bind(wx.EVT_KILL_FOCUS,OnPacking)
3165    geoBox.Add(pack,0)
3166    geoBox.Add(wx.StaticText(G2frame.dataDisplay,label=' Sample transmission: %.3f %%'%(Trans)),0,WACV)   
3167    mainSizer.Add(geoBox,0)
3168    mainSizer.Add((5,5),0)   
3169       
3170    mainSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' S(Q)->F(Q)->G(R) controls: '),0,WACV)
3171    mainSizer.Add((5,5),0)
3172    sqBox = wx.BoxSizer(wx.HORIZONTAL)
3173    sqBox.Add(wx.StaticText(G2frame.dataDisplay,label=' Detector type: '),0,WACV)
3174    choice = ['Image plate','Point detector']
3175    detType = wx.ComboBox(G2frame.dataDisplay,value=data['DetType'],choices=choice,
3176            style=wx.CB_READONLY|wx.CB_DROPDOWN)
3177    detType.Bind(wx.EVT_COMBOBOX, OnDetType)
3178    sqBox.Add(detType,0)
3179    if data['DetType'] == 'Image plate':
3180        sqBox.Add(wx.StaticText(G2frame.dataDisplay,label=' IP transmission coeff.: '),0,WACV)
3181        obliqCoeff = wx.TextCtrl(G2frame.dataDisplay,value='%.3f'%(data['ObliqCoeff']))
3182        obliqCoeff.Bind(wx.EVT_TEXT_ENTER,OnObliqCoeff)       
3183        obliqCoeff.Bind(wx.EVT_KILL_FOCUS,OnObliqCoeff)
3184        sqBox.Add(obliqCoeff,0)
3185    mainSizer.Add(sqBox,0)
3186       
3187    sqBox = wx.BoxSizer(wx.HORIZONTAL)
3188    sqBox.Add(wx.StaticText(G2frame.dataDisplay,label=' Ruland width: '),0,WACV)   
3189    rulandSldr = wx.Slider(parent=G2frame.dataDisplay,style=wx.SL_HORIZONTAL,
3190        value=int(1000*data['Ruland']))
3191    sqBox.Add(rulandSldr,1,wx.EXPAND)
3192    rulandSldr.Bind(wx.EVT_SLIDER, OnRulSlider)
3193    rulandWdt = wx.TextCtrl(G2frame.dataDisplay,value='%.3f'%(data['Ruland']))
3194    rulandWdt.Bind(wx.EVT_TEXT_ENTER,OnRulandWdt)       
3195    rulandWdt.Bind(wx.EVT_KILL_FOCUS,OnRulandWdt)
3196    sqBox.Add(rulandWdt,0,WACV)   
3197    mainSizer.Add(sqBox,0,wx.ALIGN_LEFT|wx.EXPAND)
3198   
3199    sqBox = wx.BoxSizer(wx.HORIZONTAL)
3200    lorch = wx.CheckBox(parent=G2frame.dataDisplay,label='Lorch damping?')
3201    lorch.SetValue(data['Lorch'])
3202    lorch.Bind(wx.EVT_CHECKBOX, OnLorch)
3203    sqBox.Add(lorch,0,WACV)
3204    sqBox.Add(wx.StaticText(G2frame.dataDisplay,label=' Scaling q-range: '),0,WACV)
3205    SQmin = wx.TextCtrl(G2frame.dataDisplay,value='%.1f'%(data['QScaleLim'][0]))
3206    SQmin.Bind(wx.EVT_TEXT_ENTER,OnSQmin)       
3207    SQmin.Bind(wx.EVT_KILL_FOCUS,OnSQmin)   
3208    sqBox.Add(SQmin,0)
3209    sqBox.Add(wx.StaticText(G2frame.dataDisplay,label=' to '),0,WACV)
3210    SQmax = wx.TextCtrl(G2frame.dataDisplay,value='%.1f'%(data['QScaleLim'][1]))
3211    SQmax.Bind(wx.EVT_TEXT_ENTER,OnSQmax)       
3212    SQmax.Bind(wx.EVT_KILL_FOCUS,OnSQmax)
3213    sqBox.Add(SQmax,0)
3214    resetQ = wx.CheckBox(parent=G2frame.dataDisplay,label='Reset?')
3215    sqBox.Add(resetQ,0)
3216    resetQ.Bind(wx.EVT_CHECKBOX, OnResetQ)
3217   
3218    mainSizer.Add(sqBox,0)
3219
3220    mainSizer.Layout()   
3221    G2frame.dataDisplay.SetSizer(mainSizer)
3222    Size = mainSizer.Fit(G2frame.dataFrame)
3223    G2frame.dataDisplay.SetSize(Size)
3224    G2frame.dataFrame.setSizePosLeft(Size)
3225   
Note: See TracBrowser for help on using the repository browser.