source: trunk/GSASIIpwdGUI.py @ 1367

Last change on this file since 1367 was 1367, checked in by vondreele, 9 years ago

add Dsp2pos & Pos2dsp for conversions to G2lattice
remove wave from DoIndexPeaks? - wasn't needed
use Pos2dsp & Dsp2pos in various places in G2pwdGUI
set sort order for TOF peaks - makes indexing work!

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