source: trunk/GSASIIpwdGUI.py @ 1265

Last change on this file since 1265 was 1265, checked in by toby, 9 years ago

reorg histogram copy routines to only offer appropriate histogram choices; add a global copy that does all sections

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