source: trunk/GSASIIimgGUI.py @ 1644

Last change on this file since 1644 was 1644, checked in by vondreele, 7 years ago

setting up image calibration to allow more control over refined parameters

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Author Revision URL Id
File size: 84.4 KB
Line 
1# -*- coding: utf-8 -*-
2#GSASII - image data display routines
3########### SVN repository information ###################
4# $Date: 2015-02-10 19:24:18 +0000 (Tue, 10 Feb 2015) $
5# $Author: vondreele $
6# $Revision: 1644 $
7# $URL: trunk/GSASIIimgGUI.py $
8# $Id: GSASIIimgGUI.py 1644 2015-02-10 19:24:18Z vondreele $
9########### SVN repository information ###################
10'''
11*GSASIIimgGUI: Image GUI*
12-------------------------
13
14Control image display and processing
15
16'''
17import os.path
18import wx
19import wx.lib.scrolledpanel as wxscroll
20import matplotlib as mpl
21import math
22import time
23import copy
24import GSASIIpath
25GSASIIpath.SetVersionNumber("$Revision: 1644 $")
26import GSASIIimage as G2img
27import GSASIImath as G2mth
28import GSASIIplot as G2plt
29import GSASIIIO as G2IO
30import GSASIIgrid as G2gd
31import GSASIIctrls as G2G
32import numpy as np
33
34VERY_LIGHT_GREY = wx.Colour(235,235,235)
35WACV = wx.ALIGN_CENTER_VERTICAL
36
37# trig functions in degrees
38sind = lambda x: math.sin(x*math.pi/180.)
39tand = lambda x: math.tan(x*math.pi/180.)
40cosd = lambda x: math.cos(x*math.pi/180.)
41asind = lambda x: 180.*math.asin(x)/math.pi
42   
43################################################################################
44##### Image Data
45################################################################################
46
47def UpdateImageData(G2frame,data):
48   
49    def OnPixVal(event):
50        Obj = event.GetEventObject()
51        id = Indx[Obj.GetId()]
52        try:
53            data['pixelSize'][id] = min(500,max(10,float(Obj.GetValue())))
54        except ValueError:
55            pass
56        Obj.SetValue('%.3f'%(data['pixelSize'][id]))
57        G2plt.PlotExposedImage(G2frame,newPlot=True,event=event)
58       
59       
60       
61    if G2frame.dataDisplay:
62        G2frame.dataDisplay.Destroy()
63    if not G2frame.dataFrame.GetStatusBar():
64        G2frame.dataFrame.CreateStatusBar()
65    G2frame.dataDisplay = wx.Panel(G2frame.dataFrame)
66    mainSizer = wx.BoxSizer(wx.VERTICAL)
67    mainSizer.Add(wx.StaticText(G2frame.dataDisplay,
68        label='Do not change anything here unless you are absolutely sure!'),0,WACV)
69    mainSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Image size: %d by %d'%(data['size'][0],data['size'][1])),0,WACV)
70    pixSize = wx.FlexGridSizer(0,4,5,5)
71    pixLabels = [u' Pixel X-dimension (\xb5m)',u' Pixel Y-dimension (\xb5m)']
72    Indx = {}
73    for i,[pixLabel,pix] in enumerate(zip(pixLabels,data['pixelSize'])):
74        pixSize.Add(wx.StaticText(G2frame.dataDisplay,label=pixLabel),0,WACV)
75        pixVal = wx.TextCtrl(G2frame.dataDisplay,value='%.3f'%(pix),style=wx.TE_PROCESS_ENTER)
76        Indx[pixVal.GetId()] = i
77        pixVal.Bind(wx.EVT_TEXT_ENTER,OnPixVal)
78        pixVal.Bind(wx.EVT_KILL_FOCUS,OnPixVal)
79        pixSize.Add(pixVal,0,WACV)
80    mainSizer.Add(pixSize,0)
81   
82    mainSizer.Layout()   
83    G2frame.dataDisplay.SetSizer(mainSizer)
84    fitSize = mainSizer.Fit(G2frame.dataFrame)
85    G2frame.dataFrame.setSizePosLeft(fitSize)
86    G2frame.dataDisplay.SetSize(fitSize)
87
88################################################################################
89##### Image Controls
90################################################################################                   
91def UpdateImageControls(G2frame,data,masks):
92    '''Shows and handles the controls on the "Image Controls"
93    data tree entry
94    '''
95    import ImageCalibrants as calFile
96#patch
97    if 'GonioAngles' not in data:
98        data['GonioAngles'] = [0.,0.,0.]
99    if 'DetDepth' not in data:
100        data['DetDepth'] = 0.
101    if 'SampleAbs' not in data:
102        data['SampleShape'] = 'Cylinder'
103        data['SampleAbs'] = [0.0,False]
104    if 'binType' not in data:
105        if 'PWDR' in data['type']:
106            data['binType'] = '2-theta'
107        elif 'SASD' in data['type']:
108            data['binType'] = 'log(q)'
109    if 'varyList' not in data:
110        data['varyList'] = {'dist':True,'det-X':True,'det-Y':True,'tilt':True,'phi':True,'dep':False,'wave':False}
111#end patch
112   
113# Menu items
114           
115    def OnCalibrate(event):       
116        G2frame.dataFrame.ImageEdit.Enable(id=G2gd.wxID_IMRECALIBRATE,enable=True)   
117        G2frame.dataFrame.GetStatusBar().SetStatusText('Select > 4 points on 1st used ring; LB to pick, RB on point to delete else RB to finish')
118        G2frame.ifGetRing = True
119       
120    def OnRecalibrate(event):
121        G2img.ImageRecalibrate(G2frame,data,masks)
122        wx.CallAfter(UpdateImageControls,G2frame,data,masks)
123       
124    def OnClearCalib(event):
125        data['ring'] = []
126        data['rings'] = []
127        data['ellipses'] = []
128#        G2frame.dataFrame.ImageEdit.Enable(id=G2gd.wxID_IMRECALIBRATE,enable=False)   
129        G2plt.PlotExposedImage(G2frame,event=event)
130           
131    def OnIntegrate(event):
132        CleanupMasks(masks)
133        blkSize = 128   #this seems to be optimal; will break in polymask if >1024
134        Nx,Ny = data['size']
135        nXBlks = (Nx-1)/blkSize+1
136        nYBlks = (Ny-1)/blkSize+1
137        Nup = nXBlks*nYBlks*3+3
138        dlg = wx.ProgressDialog("Elapsed time","2D image integration",Nup,
139            style = wx.PD_ELAPSED_TIME|wx.PD_AUTO_HIDE)
140        try:
141            sumImg = G2frame.ImageZ
142            darkImg,darkScale = data['dark image']
143            if darkImg:
144                Did = G2gd.GetPatternTreeItemId(G2frame, G2frame.root, darkImg)
145                Npix,imagefile = G2frame.PatternTree.GetItemPyData(Did)
146                darkImage = G2IO.GetImageData(G2frame,imagefile,True)
147                sumImg += darkImage*darkScale
148            backImg,backScale = data['background image']           
149            if backImg:     #ignores any transmission effect in the background image
150                Bid = G2gd.GetPatternTreeItemId(G2frame, G2frame.root, backImg)
151                Npix,imagefile = G2frame.PatternTree.GetItemPyData(Bid)
152                backImage = G2IO.GetImageData(G2frame,imagefile,True)
153                Bdata = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,Bid,'Image Controls'))
154                BdarkImg,BdarkScale = Bdata['dark image']
155                if BdarkImg:
156                    BDid = G2gd.GetPatternTreeItemId(G2frame, G2frame.root,BdarkImg)
157                    Npix,imagefile = G2frame.PatternTree.GetItemPyData(BDid)
158                    BdarkImage = G2IO.GetImageData(G2frame,imagefile,True)
159                    backImage += BdarkImage*BdarkScale               
160                sumImg += backImage*backScale
161            G2frame.Integrate = G2img.ImageIntegrate(sumImg,data,masks,blkSize,dlg)
162#            G2plt.PlotIntegration(G2frame,newPlot=True)
163            Id = G2IO.SaveIntegration(G2frame,G2frame.PickId,data)
164            G2frame.PatternId = Id
165            G2frame.PatternTree.SelectItem(Id)
166            G2frame.PatternTree.Expand(Id)
167        finally:
168            dlg.Destroy()
169        for item in G2frame.MakePDF: item.Enable(True)
170       
171    def OnIntegrateAll(event):
172        print 'integrate all'
173        TextList = [[False,'All IMG',0]]
174        Names = []
175        if G2frame.PatternTree.GetCount():
176            id, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root)
177            while id:
178                name = G2frame.PatternTree.GetItemText(id)
179                Names.append(name)
180                if 'IMG' in name:
181                    TextList.append([False,name,id])
182                id, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie)
183            if len(TextList) == 1:
184                G2frame.ErrorDialog('Nothing to integrate','There must some "IMG" patterns')
185                return
186            dlg = G2frame.CopyDialog(G2frame,'Image integration controls','Select images to integrate:',TextList)
187            try:
188                if dlg.ShowModal() == wx.ID_OK:
189                    result = dlg.GetData()
190                    if result[0][0]:                    #the 'All IMG' is True
191                        result = TextList[1:]
192                        for item in result: item[0] = True
193                    G2frame.EnablePlot = False
194                    for item in result:
195                        ifintegrate,name,id = item
196                        if ifintegrate:
197                            Id = G2gd.GetPatternTreeItemId(G2frame,id, 'Image Controls')
198                            Data = G2frame.PatternTree.GetItemPyData(Id)
199                            blkSize = 128   #this seems to be optimal; will break in polymask if >1024
200                            Nx,Ny = Data['size']
201                            nXBlks = (Nx-1)/blkSize+1
202                            nYBlks = (Ny-1)/blkSize+1
203                            Nup = nXBlks*nYBlks*3+3
204                            dlgp = wx.ProgressDialog("Elapsed time","2D image integration",Nup,
205                                style = wx.PD_ELAPSED_TIME|wx.PD_AUTO_HIDE)
206                            try:
207                                id = G2gd.GetPatternTreeItemId(G2frame, G2frame.root, name)
208                                Npix,imagefile = G2frame.PatternTree.GetItemPyData(id)
209                                image = G2IO.GetImageData(G2frame,imagefile,True)
210                                backImage = []
211                                if Data['background image'][0]:
212                                    backImg = Data['background image'][0]
213                                    backScale = Data['background image'][1]
214                                    id = G2gd.GetPatternTreeItemId(G2frame, G2frame.root, backImg)
215                                    Npix,imagefile = G2frame.PatternTree.GetItemPyData(id)
216                                    backImage = G2IO.GetImageData(G2frame,imagefile,True)*backScale
217                                try:
218                                    Masks = G2frame.PatternTree.GetItemPyData(
219                                        G2gd.GetPatternTreeItemId(G2frame,G2frame.Image, 'Masks'))
220                                except TypeError:       #missing Masks
221                                    Imin,Imax = Data['Range']
222                                    Masks = {'Points':[],'Rings':[],'Arcs':[],'Polygons':[],'Frames':[],'Thresholds':[(Imin,Imax),[Imin,Imax]]}
223                                    G2frame.PatternTree.SetItemPyData(
224                                        G2gd.GetPatternTreeItemId(G2frame,G2frame.Image, 'Masks'),Masks)
225                                CleanupMasks(Masks)
226                                if len(backImage):                               
227                                    G2frame.Integrate = G2img.ImageIntegrate(image+backImage,Data,Masks,blkSize,dlgp)
228                                else:
229                                    G2frame.Integrate = G2img.ImageIntegrate(image,Data,Masks,blkSize,dlgp)
230                                pId = G2IO.SaveIntegration(G2frame,Id,Data)
231                            finally:
232                                dlgp.Destroy()
233                    else:
234                        G2frame.EnablePlot = True
235                        G2frame.PatternTree.SelectItem(pId)
236                        G2frame.PatternTree.Expand(pId)
237                        G2frame.PatternId = pId
238                       
239            finally:
240                dlg.Destroy()
241       
242    def OnCopyControls(event):
243        TextList = [[False,'All IMG',0]]
244        Names = []
245        if G2frame.PatternTree.GetCount():
246            id, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root)
247            while id:
248                name = G2frame.PatternTree.GetItemText(id)
249                Names.append(name)
250                if 'IMG' in name:
251                    if id == G2frame.Image:
252                        Source = name
253                        Data = copy.deepcopy(data)
254#                        Data = copy.deepcopy(G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,id, 'Image Controls')))
255                        Data['showLines'] = True
256                        Data['ring'] = []
257                        Data['rings'] = []
258                        Data['ellipses'] = []
259                        Data['setDefault'] = False
260                    else:
261                        TextList.append([False,name,id])
262                id, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie)
263            if len(TextList) == 1:
264                G2frame.ErrorDialog('Nothing to copy controls to','There must be more than one "IMG" pattern')
265                return
266            dlg = G2frame.CopyDialog(G2frame,'Copy image controls','Copy controls from '+Source+' to:',TextList)
267            try:
268                if dlg.ShowModal() == wx.ID_OK:
269                    result = dlg.GetData()
270                    if result[0][0]:
271                        result = TextList[1:]
272                        for item in result: item[0] = True
273                    for i,item in enumerate(result):
274                        ifcopy,name,id = item
275                        if ifcopy:
276                            oldData = copy.deepcopy(G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,id, 'Image Controls')))
277                            Data['range'] = oldData['range']
278                            Data['size'] = oldData['size']
279                            Data['GonioAngles'] = oldData.get('GonioAngles', [0.,0.,0.])
280                            Data['ring'] = []
281                            Data['rings'] = []
282                            Data['ellipses'] = []
283                            G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,id, 'Image Controls'),copy.deepcopy(Data))
284            finally:
285                dlg.Destroy()
286                G2frame.PatternTree.SelectItem(G2frame.PickId)
287               
288    def OnSaveControls(event):
289        dlg = wx.FileDialog(G2frame, 'Choose image controls file', '.', '', 
290            'image control files (*.imctrl)|*.imctrl',wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT|wx.CHANGE_DIR)
291        try:
292            if dlg.ShowModal() == wx.ID_OK:
293                filename = dlg.GetPath()
294                # make sure extension is .imctrl
295                filename = os.path.splitext(filename)[0]+'.imctrl'
296                File = open(filename,'w')
297                save = {}
298                keys = ['type','wavelength','calibrant','distance','center',
299                    'tilt','rotation','azmthOff','fullIntegrate','LRazimuth',
300                    'IOtth','outChannels','outAzimuths','invert_x','invert_y','DetDepth',
301                    'calibskip','pixLimit','cutoff','calibdmin','chisq',
302                    'binType','SampleShape','PolaVal','SampleAbs','dark image','background image']
303                for key in keys:
304                    if key not in data:     #uncalibrated!
305                        continue
306                    File.write(key+':'+str(data[key])+'\n')
307                File.close()
308        finally:
309            dlg.Destroy()
310       
311    def OnLoadControls(event):
312        cntlList = ['wavelength','distance','tilt','invert_x','invert_y','type',
313            'fullIntegrate','outChannels','outAzimuths','LRazimuth','IOtth','azmthOff','DetDepth',
314            'calibskip','pixLimit','cutoff','calibdmin','chisq',
315            'PolaVal','SampleAbs','dark image','background image']
316        dlg = wx.FileDialog(G2frame, 'Choose image controls file', '.', '', 
317            'image control files (*.imctrl)|*.imctrl',wx.OPEN|wx.CHANGE_DIR)
318        try:
319            if dlg.ShowModal() == wx.ID_OK:
320                filename = dlg.GetPath()
321                File = open(filename,'r')
322                save = {}
323                S = File.readline()
324                while S:
325                    if S[0] == '#':
326                        S = File.readline()
327                        continue
328                    [key,val] = S[:-1].split(':')
329                    if key in ['type','calibrant','binType','SampleShape',]:    #strings
330                        save[key] = val
331                    elif key in ['rotation']:
332                        save[key] = float(val)
333                    elif key in ['center',]:
334                        if ',' in val:
335                            save[key] = eval(val)
336                        else:
337                            vals = val.strip('[] ').split()
338                            save[key] = [float(vals[0]),float(vals[1])] 
339                    elif key in cntlList:
340                        save[key] = eval(val)
341                    S = File.readline()
342                data.update(save)
343                G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.Image, 'Image Controls'),copy.deepcopy(data))
344                wx.CallAfter(UpdateImageControls,G2frame,data,masks)
345                G2plt.PlotExposedImage(G2frame,event=event)
346               
347                File.close()
348        finally:
349            dlg.Destroy()
350           
351# Sizers
352                                       
353    def ComboSizer():
354
355        def OnDataType(event):
356            data['type'] = typeSel.GetValue()[:4]
357            if 'SASD' in data['type']:
358                data['SampleAbs'][0] = np.exp(-data['SampleAbs'][0]) #switch from muT to trans!
359                if data['binType'] == '2-theta': data['binType'] = 'log(q)'  #switch default bin type
360            elif 'PWDR' in data['type']:
361                data['SampleAbs'][0] = -np.log(data['SampleAbs'][0])  #switch from trans to muT!
362                if data['binType'] == 'log(q)': data['binType'] = '2-theta'  #switch default bin type                 
363            wx.CallAfter(UpdateImageControls,G2frame,data,masks)
364   
365        def OnNewColorBar(event):
366            data['color'] = colSel.GetValue()
367            G2plt.PlotExposedImage(G2frame,event=event)
368       
369        def OnAzmthOff(event):
370            try:
371                azmthoff = float(azmthOff.GetValue())
372                data['azmthOff'] = azmthoff
373            except ValueError:
374                pass
375            azmthOff.SetValue("%.2f"%(data['azmthOff']))          #reset in case of error 
376            G2plt.PlotExposedImage(G2frame,event=event)
377       
378        comboSizer = wx.BoxSizer(wx.HORIZONTAL)
379        comboSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Type of image data: '),0,WACV)
380        typeSel = wx.ComboBox(parent=G2frame.dataDisplay,value=typeDict[data['type']],choices=typeList,
381            style=wx.CB_READONLY|wx.CB_DROPDOWN)
382        typeSel.SetValue(data['type'])
383        typeSel.Bind(wx.EVT_COMBOBOX, OnDataType)
384        comboSizer.Add(typeSel,0,WACV)
385        comboSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Color bar '),0,WACV)
386        colSel = wx.ComboBox(parent=G2frame.dataDisplay,value=data['color'],choices=colorList,
387            style=wx.CB_READONLY|wx.CB_DROPDOWN)
388        colSel.Bind(wx.EVT_COMBOBOX, OnNewColorBar)
389        comboSizer.Add(colSel,0,WACV)
390        comboSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Azimuth offset '),0,WACV)
391        azmthOff = wx.TextCtrl(parent=G2frame.dataDisplay,value=("%.2f" % (data['azmthOff'])),
392            style=wx.TE_PROCESS_ENTER)
393        azmthOff.Bind(wx.EVT_TEXT_ENTER,OnAzmthOff)
394        azmthOff.Bind(wx.EVT_KILL_FOCUS,OnAzmthOff)
395        comboSizer.Add(azmthOff,0,WACV)
396        return comboSizer
397       
398    def MaxSizer():
399               
400        def OnMaxVal(event):
401            try:
402                value = min(data['range'][0][1],int(maxVal.GetValue()))
403                if value < data['range'][1][0]+1:
404                    raise ValueError
405                data['range'][1][1] = value
406            except ValueError:
407                pass
408            maxVal.SetValue('%.0f'%(data['range'][1][1]))
409            DeltOne = data['range'][1][1]-max(0.0,data['range'][0][0])
410            sqrtDeltOne = math.sqrt(DeltOne)
411            maxSel.SetValue(int(100*sqrtDeltOne/sqrtDeltZero))
412            minSel.SetValue(int(100*(data['range'][1][0]/DeltOne)))
413            G2plt.PlotExposedImage(G2frame,event=event)
414           
415        def OnMinVal(event):
416            try:
417                value = int(minVal.GetValue())
418                if value > data['range'][1][1]-1:
419                    raise ValueError
420                data['range'][1][0] = value
421            except ValueError:
422                pass
423            minVal.SetValue('%.0f'%(data['range'][1][0]))
424            minSel.SetValue(int(100*(data['range'][1][0]-max(0.0,data['range'][0][0]))/DeltOne))
425            G2plt.PlotExposedImage(G2frame,event=event)
426           
427        def OnMaxSlider(event):
428            sqrtDeltZero = math.sqrt(data['range'][0][1])
429            imax = int(maxSel.GetValue())*sqrtDeltZero/100.
430            data['range'][1][1] = imax**2
431            data['range'][1][0] = max(0.0,min(data['range'][1][1]-1,data['range'][1][0]))
432            DeltOne = max(1.0,data['range'][1][1]-data['range'][1][0])
433            minSel.SetValue(int(100*(data['range'][1][0]/DeltOne)))
434            maxVal.SetValue('%.0f'%(data['range'][1][1]))
435            G2plt.PlotExposedImage(G2frame,event=event)
436           
437        def OnMinSlider(event):
438            DeltOne = data['range'][1][1]-data['range'][1][0]
439            imin = int(minSel.GetValue())*DeltOne/100.
440            data['range'][1][0] = max(0.0,min(data['range'][1][1]-1,imin))
441            minVal.SetValue('%.0f'%(data['range'][1][0]))
442            G2plt.PlotExposedImage(G2frame,event=event)
443           
444        maxSizer = wx.FlexGridSizer(0,3,0,5)
445        maxSizer.AddGrowableCol(1,1)
446        maxSizer.SetFlexibleDirection(wx.HORIZONTAL)
447        sqrtDeltZero = math.sqrt(data['range'][0][1]-max(0.0,data['range'][0][0]))
448        DeltOne = data['range'][1][1]-max(0.0,data['range'][0][0])
449        sqrtDeltOne = math.sqrt(DeltOne)
450        maxSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Max intensity'),0,WACV)
451        maxSel = wx.Slider(parent=G2frame.dataDisplay,style=wx.SL_HORIZONTAL,
452            value=int(100*sqrtDeltOne/sqrtDeltZero))
453        maxSizer.Add(maxSel,1,wx.EXPAND)
454        maxSel.Bind(wx.EVT_SLIDER, OnMaxSlider)
455        maxVal = wx.TextCtrl(parent=G2frame.dataDisplay,value='%.0f'%(data['range'][1][1]))
456        maxVal.Bind(wx.EVT_TEXT_ENTER,OnMaxVal)   
457        maxVal.Bind(wx.EVT_KILL_FOCUS,OnMaxVal)
458        maxSizer.Add(maxVal,0,WACV)   
459        maxSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Min intensity'),0,WACV)
460        minSel = wx.Slider(parent=G2frame.dataDisplay,style=wx.SL_HORIZONTAL,
461            value=int(100*(data['range'][1][0]-max(0.0,data['range'][0][0]))/DeltOne))
462        maxSizer.Add(minSel,1,wx.EXPAND)
463        minSel.Bind(wx.EVT_SLIDER, OnMinSlider)
464        minVal = wx.TextCtrl(parent=G2frame.dataDisplay,value='%.0f'%(data['range'][1][0]))
465        minVal.Bind(wx.EVT_TEXT_ENTER,OnMinVal)   
466        minVal.Bind(wx.EVT_KILL_FOCUS,OnMinVal)
467        maxSizer.Add(minVal,0,WACV)
468        return maxSizer
469       
470    def CalibCoeffSizer():
471       
472        def OnWavelength(event):
473            try:
474                wave = float(waveSel.GetValue())
475                if wave < .01:
476                    raise ValueError
477                data['wavelength'] = wave
478            except ValueError:
479                pass
480            waveSel.SetValue("%7.5f" % (data['wavelength']))          #reset in case of error
481           
482        def OnDetDepthRef(event):
483            data['varyList']['dep'] = penSel.GetValue()
484           
485        def OnDetDepth(event):
486            try:
487                data['DetDepth'] = float(penVal.GetValue())
488            except ValueError:
489                pass
490            penVal.SetValue("%6.3f" % (data['DetDepth']))          #reset in case of error                     
491           
492        calibSizer = wx.FlexGridSizer(0,2,5,5)
493        calibSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Calibration coefficients'),0,WACV)   
494        calibSizer.Add((5,0),0)
495        cent = data['center']
496        for axis,cnt in zip(['X','Y'],cent):
497            calibSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Beam center '+axis),0,WACV)
498            centText = wx.TextCtrl(parent=G2frame.dataDisplay,value=("%7.2f" % (cnt)),style=wx.TE_READONLY)
499            centText.SetBackgroundColour(VERY_LIGHT_GREY)
500            calibSizer.Add(centText,0,WACV)       
501        calibSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Wavelength'),0,WACV)
502        waveSel = wx.TextCtrl(parent=G2frame.dataDisplay,value=("%7.5f" % (data['wavelength'])),
503            style=wx.TE_PROCESS_ENTER)
504        waveSel.Bind(wx.EVT_TEXT_ENTER,OnWavelength)
505        waveSel.Bind(wx.EVT_KILL_FOCUS,OnWavelength)
506        calibSizer.Add(waveSel,0,WACV)             
507        calibSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Distance'),0,WACV)
508#        distVary = wx.CheckBox(G2frame.dataDisplay,label=' Distance')
509        distSel = wx.TextCtrl(parent=G2frame.dataDisplay,value=("%8.2f"%(data['distance'])),style=wx.TE_READONLY)
510        distSel.SetBackgroundColour(VERY_LIGHT_GREY)
511        calibSizer.Add(distSel,0,WACV)
512        calibSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Tilt angle'),0,WACV)
513        tiltSel = wx.TextCtrl(parent=G2frame.dataDisplay,value=("%9.3f"%(data['tilt'])),style=wx.TE_READONLY)
514        tiltSel.SetBackgroundColour(VERY_LIGHT_GREY)
515        calibSizer.Add(tiltSel,0,WACV)
516        calibSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Tilt rotation'),0,WACV)
517        rotSel = wx.TextCtrl(parent=G2frame.dataDisplay,value=("%9.3f"%(data['rotation'])),style=wx.TE_READONLY)
518        rotSel.SetBackgroundColour(VERY_LIGHT_GREY)
519        calibSizer.Add(rotSel,0,WACV)
520        if 'PWDR' in data['type']:
521            penSel = wx.CheckBox(parent=G2frame.dataDisplay,label='Penetration?')
522            calibSizer.Add(penSel,0,WACV)
523            penSel.Bind(wx.EVT_CHECKBOX, OnDetDepthRef)
524            penSel.SetValue(data['varyList']['dep'])
525            penVal = wx.TextCtrl(parent=G2frame.dataDisplay,value=("%6.5f" % (data['DetDepth'])),
526                style=wx.TE_PROCESS_ENTER)
527            penVal.Bind(wx.EVT_TEXT_ENTER,OnDetDepth)
528            penVal.Bind(wx.EVT_KILL_FOCUS,OnDetDepth)
529            calibSizer.Add(penVal,0,WACV)             
530       
531        return calibSizer
532   
533    def IntegrateSizer():
534       
535        def OnNewBinType(event):
536            data['binType'] = binSel.GetValue()
537       
538        def OnIOtth(event):
539            Ltth = max(float(G2frame.InnerTth.GetValue()),0.001)
540            Utth = float(G2frame.OuterTth.GetValue())
541            if Ltth > Utth:
542                Ltth,Utth = Utth,Ltth
543            data['IOtth'] = [Ltth,Utth]
544            G2frame.InnerTth.SetValue("%8.3f" % (Ltth))
545            G2frame.OuterTth.SetValue("%8.2f" % (Utth))
546            G2plt.PlotExposedImage(G2frame,event=event)
547       
548        def OnLRazim(event):
549            Lazm = int(G2frame.Lazim.GetValue())%360
550            Razm = int(G2frame.Razim.GetValue())%360
551            if Lazm > Razm:
552                Razm += 360
553            if data['fullIntegrate']:
554                Razm = Lazm+360
555            G2frame.Lazim.SetValue("%6d" % (Lazm))
556            G2frame.Razim.SetValue("%6d" % (Razm))
557            data['LRazimuth'] = [Lazm,Razm]
558            G2plt.PlotExposedImage(G2frame,event=event)
559       
560        def OnNumOutChans(event):
561            try:
562                numChans = int(outChan.GetValue())
563                if numChans < 10:
564                    raise ValueError
565                data['outChannels'] = numChans
566            except ValueError:
567                pass
568            outChan.SetValue(str(data['outChannels']))          #reset in case of error       
569       
570        def OnNumOutAzms(event):
571            try:
572                numAzms = int(outAzim.GetValue())
573                if numAzms < 1:
574                    raise ValueError
575                data['outAzimuths'] = numAzms           
576            except ValueError:
577                pass
578            outAzim.SetValue(str(data['outAzimuths']))          #reset in case of error       
579            G2plt.PlotExposedImage(G2frame,event=event)
580       
581        def OnOblique(event):
582            if data['Oblique'][1]:
583                data['Oblique'][1] = False
584            else:
585                data['Oblique'][1] = True
586               
587        def OnObliqVal(event):
588            try:
589                value = float(obliqVal.GetValue())
590                if 0.01 <= value <= 0.99:
591                    data['Oblique'][0] = value
592                else:
593                    raise ValueError
594            except ValueError:
595                pass
596            obliqVal.SetValue('%.3f'%(data['Oblique'][0]))
597                           
598        def OnSamAbs(event):
599            if data['SampleAbs'][1]:
600                data['SampleAbs'][1] = False
601            else:
602                data['SampleAbs'][1] = True
603               
604        def OnSamAbsVal(event):
605            try:
606                value = float(samabsVal.GetValue())
607                minmax = [0.,2.]
608                if 'SASD' in data['type']:
609                    minmax = [.05,1.0]
610                if minmax[0] <= value <= minmax[1]:
611                    data['SampleAbs'][0] = value
612                else:
613                    raise ValueError
614            except ValueError:
615                pass
616            samabsVal.SetValue('%.3f'%(data['SampleAbs'][0]))
617                           
618        def OnShowLines(event):
619            if data['showLines']:
620                data['showLines'] = False
621            else:
622                data['showLines'] = True
623            G2plt.PlotExposedImage(G2frame,event=event)
624           
625        def OnFullIntegrate(event):
626            Lazm =int(G2frame.Lazim.GetValue())
627            if data['fullIntegrate']:
628                data['fullIntegrate'] = False
629                data['LRazimuth'] = [Lazm,Lazm+20]
630            else:
631                data['fullIntegrate'] = True
632                data['LRazimuth'] = [Lazm,Lazm+360]
633            wx.CallAfter(UpdateImageControls,G2frame,data,masks)
634            G2plt.PlotExposedImage(G2frame,event=event)
635           
636        def OnSetDefault(event):
637            if data['setDefault']:
638                G2frame.imageDefault = {}
639                data['setDefault'] = False
640            else:
641                G2frame.imageDefault = copy.copy(data)
642                data['setDefault'] = True
643               
644        def OnCenterAzm(event):
645            if data['centerAzm']:
646                data['centerAzm'] = False
647            else:
648                data['centerAzm'] = True
649            G2plt.PlotExposedImage(G2frame,event=event)
650               
651        def OnApplyPola(event):
652            if data['PolaVal'][1]:
653                data['PolaVal'][1] = False
654            else:
655                data['PolaVal'][1] = True
656               
657        def OnPolaVal(event):
658            try:
659                value = float(polaVal.GetValue())
660                if 0.001 <= value <= 0.999:
661                    data['PolaVal'][0] = value
662                else:
663                    raise ValueError
664            except ValueError:
665                pass
666            polaVal.SetValue('%.3f'%(data['PolaVal'][0]))
667                           
668        dataSizer = wx.FlexGridSizer(0,2,5,3)
669        dataSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Integration coefficients'),0,WACV)   
670        dataSizer.Add((5,0),0)
671        if 'PWDR' in data['type']:
672            binChoice = ['2-theta','q']
673        elif 'SASD' in data['type']:
674            binChoice = ['q','log(q)']
675        dataSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Bin style: Constant step bins in'),0,WACV)           
676        binSel = wx.ComboBox(parent=G2frame.dataDisplay,value=data['binType'],choices=binChoice,
677            style=wx.CB_READONLY|wx.CB_DROPDOWN)
678        binSel.Bind(wx.EVT_COMBOBOX, OnNewBinType)
679        dataSizer.Add(binSel,0,WACV)
680        dataSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Inner/Outer 2-theta'),0,WACV)           
681        IOtth = data['IOtth']
682        littleSizer = wx.BoxSizer(wx.HORIZONTAL)
683        G2frame.InnerTth = wx.TextCtrl(parent=G2frame.dataDisplay,
684            value=("%8.3f" % (IOtth[0])),style=wx.TE_PROCESS_ENTER)
685        G2frame.InnerTth.Bind(wx.EVT_TEXT_ENTER,OnIOtth)
686        G2frame.InnerTth.Bind(wx.EVT_KILL_FOCUS,OnIOtth)
687        littleSizer.Add(G2frame.InnerTth,0,WACV)
688        G2frame.OuterTth = wx.TextCtrl(parent=G2frame.dataDisplay,
689            value=("%8.2f" % (IOtth[1])),style=wx.TE_PROCESS_ENTER)
690        G2frame.OuterTth.Bind(wx.EVT_TEXT_ENTER,OnIOtth)
691        G2frame.OuterTth.Bind(wx.EVT_KILL_FOCUS,OnIOtth)
692        littleSizer.Add(G2frame.OuterTth,0,WACV)
693        dataSizer.Add(littleSizer,0,)
694        dataSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Start/End azimuth'),0,WACV)
695        LRazim = data['LRazimuth']
696        littleSizer = wx.BoxSizer(wx.HORIZONTAL)
697        G2frame.Lazim = wx.TextCtrl(parent=G2frame.dataDisplay,
698            value=("%6d" % (LRazim[0])),style=wx.TE_PROCESS_ENTER)
699        G2frame.Lazim.Bind(wx.EVT_TEXT_ENTER,OnLRazim)
700        G2frame.Lazim.Bind(wx.EVT_KILL_FOCUS,OnLRazim)
701        littleSizer.Add(G2frame.Lazim,0,WACV)
702        G2frame.Razim = wx.TextCtrl(parent=G2frame.dataDisplay,
703            value=("%6d" % (LRazim[1])),style=wx.TE_PROCESS_ENTER)
704        G2frame.Razim.Bind(wx.EVT_TEXT_ENTER,OnLRazim)
705        G2frame.Razim.Bind(wx.EVT_KILL_FOCUS,OnLRazim)
706        if data['fullIntegrate']:
707            G2frame.Razim.Enable(False)
708            G2frame.Razim.SetBackgroundColour(VERY_LIGHT_GREY)
709            G2frame.Razim.SetValue("%6d" % (LRazim[0]+360))
710        littleSizer.Add(G2frame.Razim,0,WACV)
711        dataSizer.Add(littleSizer,0,)
712        dataSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' No. 2-theta/azimuth bins'),0,WACV)
713        littleSizer = wx.BoxSizer(wx.HORIZONTAL)
714        outChan = wx.TextCtrl(parent=G2frame.dataDisplay,value=str(data['outChannels']),style=wx.TE_PROCESS_ENTER)
715        outChan.Bind(wx.EVT_TEXT_ENTER,OnNumOutChans)
716        outChan.Bind(wx.EVT_KILL_FOCUS,OnNumOutChans)
717        littleSizer.Add(outChan,0,WACV)
718        outAzim = wx.TextCtrl(parent=G2frame.dataDisplay,value=str(data['outAzimuths']),style=wx.TE_PROCESS_ENTER)
719        outAzim.Bind(wx.EVT_TEXT_ENTER,OnNumOutAzms)
720        outAzim.Bind(wx.EVT_KILL_FOCUS,OnNumOutAzms)
721        littleSizer.Add(outAzim,0,WACV)
722        dataSizer.Add(littleSizer,0,)
723        littleSizer = wx.BoxSizer(wx.HORIZONTAL)
724        samabs = wx.CheckBox(parent=G2frame.dataDisplay,label='Apply sample absorption?')
725        dataSizer.Add(samabs,0,WACV)
726        samabs.Bind(wx.EVT_CHECKBOX, OnSamAbs)
727        samabs.SetValue(data['SampleAbs'][1])
728        if 'PWDR' in data['type']:
729            littleSizer.Add(wx.StaticText(G2frame.dataDisplay,label='mu/R (0.00-2.0) '),0,WACV)
730        elif 'SASD' in data['type']:
731            littleSizer.Add(wx.StaticText(G2frame.dataDisplay,label='transmission '),0,WACV)
732        samabsVal = wx.TextCtrl(parent=G2frame.dataDisplay,value='%.3f'%(data['SampleAbs'][0]),style=wx.TE_PROCESS_ENTER)           
733        samabsVal.Bind(wx.EVT_TEXT_ENTER,OnSamAbsVal)
734        samabsVal.Bind(wx.EVT_KILL_FOCUS,OnSamAbsVal)
735        littleSizer.Add(samabsVal,0,WACV)
736        dataSizer.Add(littleSizer,0,)
737        if 'PWDR' in data['type']:
738            littleSizer = wx.BoxSizer(wx.HORIZONTAL)
739            oblique = wx.CheckBox(parent=G2frame.dataDisplay,label='Apply detector absorption?')
740            dataSizer.Add(oblique,0,WACV)
741            oblique.Bind(wx.EVT_CHECKBOX, OnOblique)
742            oblique.SetValue(data['Oblique'][1])
743            littleSizer.Add(wx.StaticText(G2frame.dataDisplay,label='Value (0.01-0.99)  '),0,WACV)
744            obliqVal = wx.TextCtrl(parent=G2frame.dataDisplay,value='%.3f'%(data['Oblique'][0]),style=wx.TE_PROCESS_ENTER)
745            obliqVal.Bind(wx.EVT_TEXT_ENTER,OnObliqVal)
746            obliqVal.Bind(wx.EVT_KILL_FOCUS,OnObliqVal)
747            littleSizer.Add(obliqVal,0,WACV)
748            dataSizer.Add(littleSizer,0,)
749        if 'SASD' in data['type']:
750            littleSizer = wx.BoxSizer(wx.HORIZONTAL)
751            setPolariz = wx.CheckBox(parent=G2frame.dataDisplay,label='Apply polarization?')
752            dataSizer.Add(setPolariz,0,WACV)
753            setPolariz.Bind(wx.EVT_CHECKBOX, OnApplyPola)
754            setPolariz.SetValue(data['PolaVal'][1])
755            littleSizer.Add(wx.StaticText(G2frame.dataDisplay,label='Value (0.001-0.999)  '),0,WACV)
756            polaVal = wx.TextCtrl(parent=G2frame.dataDisplay,value='%.3f'%(data['PolaVal'][0]),
757                style=wx.TE_PROCESS_ENTER)
758            polaVal.Bind(wx.EVT_TEXT_ENTER,OnPolaVal)
759            polaVal.Bind(wx.EVT_KILL_FOCUS,OnPolaVal)
760            littleSizer.Add(polaVal,0,WACV)
761            dataSizer.Add(littleSizer,0,)
762       
763        showLines = wx.CheckBox(parent=G2frame.dataDisplay,label='Show integration limits?')
764        dataSizer.Add(showLines,0,WACV)
765        showLines.Bind(wx.EVT_CHECKBOX, OnShowLines)
766        showLines.SetValue(data['showLines'])
767        fullIntegrate = wx.CheckBox(parent=G2frame.dataDisplay,label='Do full integration?')
768        dataSizer.Add(fullIntegrate,0,WACV)
769        fullIntegrate.Bind(wx.EVT_CHECKBOX, OnFullIntegrate)
770        fullIntegrate.SetValue(data['fullIntegrate'])
771        setDefault = wx.CheckBox(parent=G2frame.dataDisplay,label='Use as default for all images?')
772        dataSizer.Add(setDefault,0,WACV)
773        setDefault.Bind(wx.EVT_CHECKBOX, OnSetDefault)
774        setDefault.SetValue(data['setDefault'])
775        centerAzm = wx.CheckBox(parent=G2frame.dataDisplay,label='Azimuth at bin center?')
776        dataSizer.Add(centerAzm,0,WACV)
777        centerAzm.Bind(wx.EVT_CHECKBOX, OnCenterAzm)
778        centerAzm.SetValue(data['centerAzm'])
779        return dataSizer
780       
781    def BackSizer():
782       
783        def OnBackImage(event):
784            data['background image'][0] = backImage.GetValue()
785           
786        def OnDarkImage(event):
787            data['dark image'][0] = darkImage.GetValue()
788            G2plt.PlotExposedImage(G2frame,event=event)
789
790        def OnBackMult(event):
791            try:
792                mult = float(backMult.GetValue())
793                data['background image'][1] = mult
794            except ValueError:
795                pass
796            backMult.SetValue("%.3f" % (data['background image'][1]))          #reset in case of error
797       
798        def OnDarkMult(event):
799            try:
800                mult = float(darkMult.GetValue())
801                data['dark image'][1] = mult
802            except ValueError:
803                pass
804            darkMult.SetValue("%.3f" % (data['dark image'][1]))          #reset in case of error
805            G2plt.PlotExposedImage(G2frame,event=event)
806       
807        backSizer = wx.FlexGridSizer(0,4,5,5)
808
809        backSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' Dark image'),0,WACV)
810        Choices = ['',]+G2gd.GetPatternTreeDataNames(G2frame,['IMG ',])
811        darkImage = wx.ComboBox(parent=G2frame.dataDisplay,value=data['dark image'][0],choices=Choices,
812            style=wx.CB_READONLY|wx.CB_DROPDOWN)
813        darkImage.Bind(wx.EVT_COMBOBOX,OnDarkImage)
814        backSizer.Add(darkImage)
815        backSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' multiplier'),0,WACV)
816        darkMult =  wx.TextCtrl(parent=G2frame.dataDisplay,value=("%.3f" % (data['dark image'][1])),
817            style=wx.TE_PROCESS_ENTER)
818        darkMult.Bind(wx.EVT_TEXT_ENTER,OnDarkMult)
819        darkMult.Bind(wx.EVT_KILL_FOCUS,OnDarkMult)
820        backSizer.Add(darkMult,0,WACV)
821
822        backSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' Background image'),0,WACV)
823        Choices = ['',]+G2gd.GetPatternTreeDataNames(G2frame,['IMG ',])
824        backImage = wx.ComboBox(parent=G2frame.dataDisplay,value=data['background image'][0],choices=Choices,
825            style=wx.CB_READONLY|wx.CB_DROPDOWN)
826        backImage.Bind(wx.EVT_COMBOBOX,OnBackImage)
827        backSizer.Add(backImage)
828        backSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' multiplier'),0,WACV)
829        backMult =  wx.TextCtrl(parent=G2frame.dataDisplay,value=("%.3f" % (data['background image'][1])),
830            style=wx.TE_PROCESS_ENTER)
831        backMult.Bind(wx.EVT_TEXT_ENTER,OnBackMult)
832        backMult.Bind(wx.EVT_KILL_FOCUS,OnBackMult)
833        backSizer.Add(backMult,0,WACV)
834        return backSizer
835                       
836    def CalibSizer():
837               
838        def OnNewCalibrant(event):
839            data['calibrant'] = calSel.GetValue()
840            data['calibskip'] = calFile.Calibrants[data['calibrant']][3]
841            limits = calFile.Calibrants[data['calibrant']][4]
842            data['calibdmin'],data['pixLimit'],data['cutoff'] = limits
843            pixLimit.SetValue(str(limits[1]))
844            cutOff.SetValue('%.1f'%(limits[2]))
845            calibSkip.SetValue(str(data['calibskip']))
846            calibDmin.SetValue('%.1f'%(limits[0]))
847           
848        def OnCalibSkip(event):
849            data['calibskip'] = int(calibSkip.GetValue())
850           
851        def OnCalibDmin(event):
852            try:
853                dmin = float(calibDmin.GetValue())
854                if dmin < 0.25:
855                    raise ValueError
856                data['calibdmin'] = dmin
857            except ValueError:
858                pass
859            calibDmin.SetValue("%.2f"%(data['calibdmin']))          #reset in case of error 
860                   
861        def OnCutOff(event):
862            try:
863                cutoff = float(cutOff.GetValue())
864                if cutoff < 0.1:
865                    raise ValueError
866                data['cutoff'] = cutoff
867            except ValueError:
868                pass
869            cutOff.SetValue("%.1f"%(data['cutoff']))          #reset in case of error 
870       
871        def OnPixLimit(event):
872            data['pixLimit'] = int(pixLimit.GetValue())
873           
874        def OnSetRings(event):
875            if data['setRings']:
876                data['setRings'] = False
877            else:
878                data['setRings'] = True
879            G2plt.PlotExposedImage(G2frame,event=event)
880   
881        calibSizer = wx.FlexGridSizer(0,3,5,5)
882        comboSizer = wx.BoxSizer(wx.HORIZONTAL)   
883        comboSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Calibrant '),0,WACV)
884        calSel = wx.ComboBox(parent=G2frame.dataDisplay,value=data['calibrant'],choices=calList,
885            style=wx.CB_READONLY|wx.CB_DROPDOWN)
886        calSel.Bind(wx.EVT_COMBOBOX, OnNewCalibrant)
887        comboSizer.Add(calSel,0,WACV)
888        calibSizer.Add(comboSizer,0)
889       
890        comboSizer = wx.BoxSizer(wx.HORIZONTAL)   
891        comboSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Calib lines to skip   '),0,WACV)
892        calibSkip  = wx.ComboBox(parent=G2frame.dataDisplay,value=str(data['calibskip']),choices=[str(i) for i in range(25)],
893            style=wx.CB_READONLY|wx.CB_DROPDOWN)
894        calibSkip.Bind(wx.EVT_COMBOBOX, OnCalibSkip)
895        comboSizer.Add(calibSkip,0,WACV)
896        calibSizer.Add(comboSizer,0)
897       
898        comboSizer = wx.BoxSizer(wx.HORIZONTAL)       
899        comboSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Min calib d-spacing '),0,WACV)
900        calibDmin = wx.TextCtrl(parent=G2frame.dataDisplay,value=("%.2f" % (data['calibdmin'])),
901            style=wx.TE_PROCESS_ENTER)
902        calibDmin.Bind(wx.EVT_TEXT_ENTER,OnCalibDmin)
903        calibDmin.Bind(wx.EVT_KILL_FOCUS,OnCalibDmin)
904        comboSizer.Add(calibDmin,0,WACV)
905        calibSizer.Add(comboSizer,0)
906       
907        comboSizer = wx.BoxSizer(wx.HORIZONTAL)
908        comboSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Min ring I/Ib '),0,WACV)
909        cutOff = wx.TextCtrl(parent=G2frame.dataDisplay,value=("%.1f" % (data['cutoff'])),
910            style=wx.TE_PROCESS_ENTER)
911        cutOff.Bind(wx.EVT_TEXT_ENTER,OnCutOff)
912        cutOff.Bind(wx.EVT_KILL_FOCUS,OnCutOff)
913        comboSizer.Add(cutOff,0,WACV)
914        calibSizer.Add(comboSizer,0)
915       
916        comboSizer = wx.BoxSizer(wx.HORIZONTAL)
917        comboSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Pixel search range '),0,WACV)
918        pixLimit = wx.ComboBox(parent=G2frame.dataDisplay,value=str(data['pixLimit']),choices=['1','2','5','10','15','20'],
919            style=wx.CB_READONLY|wx.CB_DROPDOWN)
920        pixLimit.Bind(wx.EVT_COMBOBOX, OnPixLimit)
921        comboSizer.Add(pixLimit,0,WACV)
922        calibSizer.Add(comboSizer,0)
923       
924        comboSizer = wx.BoxSizer(wx.HORIZONTAL)
925        setRings = wx.CheckBox(parent=G2frame.dataDisplay,label='Show ring picks?')
926        comboSizer.Add(setRings,0)
927        setRings.Bind(wx.EVT_CHECKBOX, OnSetRings)
928        setRings.SetValue(data['setRings'])
929        calibSizer.Add(comboSizer,0)
930        return calibSizer
931       
932    def GonioSizer():
933       
934        ValObj = {}
935       
936        def OnGonioAngle(event):
937            Obj = event.GetEventObject()
938            item = ValObj[Obj.GetId()]
939            try:
940                value = float(Obj.GetValue())
941            except ValueError:
942                value = data['GonioAngles'][item]
943            data['GonioAngles'][item] = value
944            Obj.SetValue('%8.2f'%(value))
945       
946        gonioSizer = wx.BoxSizer(wx.HORIZONTAL)
947        names = ['Omega','Chi','Phi']
948        gonioSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,'Sample goniometer angles: '),0,WACV)
949        for i,name in enumerate(names):
950            gonioSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,name),0,WACV)
951            angle = wx.TextCtrl(G2frame.dataDisplay,-1,value='%8.2f'%(data['GonioAngles'][i]),
952                style=wx.TE_PROCESS_ENTER)
953            angle.Bind(wx.EVT_TEXT_ENTER,OnGonioAngle)
954            angle.Bind(wx.EVT_KILL_FOCUS,OnGonioAngle)
955            ValObj[angle.GetId()] = i
956            gonioSizer.Add(angle,0,WACV)
957        return gonioSizer
958       
959# Image Controls main code             
960                           
961    #fix for old files:
962    if 'azmthOff' not in data:
963        data['azmthOff'] = 0.0
964    if 'background image' not in data:
965        data['background image'] = ['',-1.0]
966    if 'dark image' not in data:
967        data['dark image'] = ['',-1.0]
968    if 'centerAzm' not in data:
969        data['centerAzm'] = False
970    if 'Oblique' not in data:
971        data['Oblique'] = [0.5,False]
972    if 'PolaVal' not in data:
973        data['PolaVal'] = [0.99,False]
974    #end fix
975   
976    colorList = sorted([m for m in mpl.cm.datad.keys() if not m.endswith("_r")],key=lambda s: s.lower())
977    calList = sorted([m for m in calFile.Calibrants.keys()],key=lambda s: s.lower())
978    typeList = ['PWDR - powder diffraction data','SASD - small angle scattering data',
979        'REFL - reflectometry data']
980    if not data.get('type'):                        #patch for old project files
981        data['type'] = 'PWDR'
982    typeDict = {'PWDR':typeList[0],'SASD':typeList[1],'REFL':typeList[2]}
983    if G2frame.dataDisplay:
984        G2frame.dataDisplay.Destroy()
985    G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.ImageMenu)
986    if not G2frame.dataFrame.GetStatusBar():
987        G2frame.dataFrame.CreateStatusBar()
988    G2frame.dataFrame.Bind(wx.EVT_MENU, OnCalibrate, id=G2gd.wxID_IMCALIBRATE)
989    G2frame.dataFrame.Bind(wx.EVT_MENU, OnRecalibrate, id=G2gd.wxID_IMRECALIBRATE)
990    G2frame.dataFrame.Bind(wx.EVT_MENU, OnClearCalib, id=G2gd.wxID_IMCLEARCALIB)
991    if 'chisq' not in data:
992        G2frame.dataFrame.ImageEdit.Enable(id=G2gd.wxID_IMRECALIBRATE,enable=False)   
993    G2frame.dataFrame.Bind(wx.EVT_MENU, OnIntegrate, id=G2gd.wxID_IMINTEGRATE)
994    G2frame.dataFrame.Bind(wx.EVT_MENU, OnIntegrateAll, id=G2gd.wxID_INTEGRATEALL)
995    G2frame.dataFrame.Bind(wx.EVT_MENU, OnCopyControls, id=G2gd.wxID_IMCOPYCONTROLS)
996    G2frame.dataFrame.Bind(wx.EVT_MENU, OnSaveControls, id=G2gd.wxID_IMSAVECONTROLS)
997    G2frame.dataFrame.Bind(wx.EVT_MENU, OnLoadControls, id=G2gd.wxID_IMLOADCONTROLS)
998    G2frame.dataDisplay = wx.Panel(G2frame.dataFrame)
999
1000    mainSizer = wx.BoxSizer(wx.VERTICAL)
1001    mainSizer.Add((5,10),0)   
1002    mainSizer.Add(ComboSizer(),0,wx.ALIGN_LEFT)
1003    mainSizer.Add((5,5),0)           
1004    mainSizer.Add(MaxSizer(),0,wx.ALIGN_LEFT|wx.EXPAND)
1005   
1006    mainSizer.Add((5,5),0)
1007    DataSizer = wx.FlexGridSizer(0,2,5,5)
1008    DataSizer.Add(CalibCoeffSizer(),0)
1009    DataSizer.Add(IntegrateSizer(),0)       
1010    mainSizer.Add(DataSizer,0)
1011    mainSizer.Add((5,5),0)           
1012    mainSizer.Add(BackSizer(),0)
1013    mainSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Calibration controls:'),0,WACV)
1014    mainSizer.Add((5,5),0)
1015    mainSizer.Add(CalibSizer(),0,WACV)
1016    mainSizer.Add((5,5),0)
1017    mainSizer.Add(GonioSizer(),0,WACV)   
1018       
1019    mainSizer.Layout()   
1020    G2frame.dataDisplay.SetSizer(mainSizer)
1021    fitSize = mainSizer.Fit(G2frame.dataFrame)
1022    G2frame.dataFrame.setSizePosLeft(fitSize)
1023    G2frame.dataDisplay.SetSize(fitSize)
1024   
1025################################################################################
1026##### Masks
1027################################################################################
1028def CleanupMasks(data):
1029    '''If a mask creation is not completed, an empty mask entry is created in the
1030    masks array. This cleans them out. It is called when the masks page is first loaded
1031    and before saving them or after reading them in. This should also probably be done
1032    before they are used for integration.
1033    '''
1034    for key in ['Points','Rings','Arcs','Polygons']:
1035        data[key] = data.get(key,[])
1036        l1 = len(data[key])
1037        data[key] = [i for i in data[key] if i]
1038        l2 = len(data[key])
1039        if GSASIIpath.GetConfigValue('debug') and l1 != l2:
1040            print 'Mask Cleanup:',key,'was',l1,'entries','now',l2
1041   
1042def UpdateMasks(G2frame,data):
1043    '''Shows and handles the controls on the "Masks" data tree entry
1044    '''
1045   
1046    def OnTextMsg(event):
1047        Obj = event.GetEventObject()
1048        Obj.SetToolTipString('Drag this mask on 2D Powder Image with mouse to change ')
1049
1050    def Replot(*args,**kwargs):
1051        G2plt.PlotExposedImage(G2frame)       
1052
1053    def onDeleteMask(event):
1054        Obj = event.GetEventObject()
1055        typ = Obj.locationcode.split('+')[1]
1056        num = int(Obj.locationcode.split('+')[2])
1057        del(data[typ][num])
1058        wx.CallAfter(UpdateMasks,G2frame,data)
1059        G2plt.PlotExposedImage(G2frame,event=event)
1060
1061    def onDeleteFrame(event):
1062        data['Frames'] = []
1063        wx.CallAfter(UpdateMasks,G2frame,data)
1064        G2plt.PlotExposedImage(G2frame,event=event)
1065
1066    def OnCopyMask(event):
1067        TextList = [[False,'All IMG',0]]
1068        Names = []
1069        if G2frame.PatternTree.GetCount():
1070            id, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root)
1071            while id:
1072                name = G2frame.PatternTree.GetItemText(id)
1073                Names.append(name)
1074                if 'IMG' in name:
1075                    if id == G2frame.Image:
1076                        Source = name
1077                        Mask = copy.deepcopy(G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,id, 'Masks')))
1078                        Thresh = Mask.pop('Thresholds')  #remove Thresholds from source mask & save it for later
1079                    else:
1080                        TextList.append([False,name,id])
1081                id, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie)
1082            if len(TextList) == 1:
1083                G2frame.ErrorDialog('Nothing to copy mask to','There must be more than one "IMG" pattern')
1084                return
1085            dlg = G2frame.CopyDialog(G2frame,'Copy mask information','Copy mask from '+Source+' to:',TextList)
1086            try:
1087                if dlg.ShowModal() == wx.ID_OK:
1088                    result = dlg.GetData()
1089                    if result[0][0]:
1090                        result = TextList[1:]
1091                        for item in result: item[0] = True
1092                    for i,item in enumerate(result):
1093                        ifcopy,name,id = item
1094                        if ifcopy:
1095                            mask = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,id, 'Masks'))
1096#                            Mask['Thresholds'][0] = mask['Thresholds'][0]
1097#                            Mask['Thresholds'][1][1] = min(mask['Thresholds'][1][1],Mask['Thresholds'][1][1])
1098                            mask.update(Mask)
1099                            mask['Thresholds'][1][0] = Thresh[1][0]  #copy only lower threshold                             
1100                            G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,id, 'Masks'),copy.deepcopy(mask))
1101            finally:
1102                dlg.Destroy()
1103               
1104    def OnSaveMask(event):
1105        CleanupMasks(data)
1106        dlg = wx.FileDialog(G2frame, 'Choose image mask file', '.', '', 
1107            'image mask files (*.immask)|*.immask',wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT|wx.CHANGE_DIR)
1108        try:
1109            if dlg.ShowModal() == wx.ID_OK:
1110                filename = dlg.GetPath()
1111                File = open(filename,'w')
1112                save = {}
1113                keys = ['Points','Rings','Arcs','Polygons','Frames','Thresholds']
1114                for key in keys:
1115                    File.write(key+':'+str(data[key])+'\n')
1116                File.close()
1117        finally:
1118            dlg.Destroy()
1119       
1120    def OnLoadMask(event):
1121        if event.Id == G2gd.wxID_MASKLOADNOT:
1122            ignoreThreshold = True
1123        else:
1124            ignoreThreshold = False
1125        dlg = wx.FileDialog(G2frame, 'Choose image mask file', '.', '', 
1126            'image mask files (*.immask)|*.immask',wx.OPEN|wx.CHANGE_DIR)
1127        try:
1128            if dlg.ShowModal() == wx.ID_OK:
1129                filename = dlg.GetPath()
1130                File = open(filename,'r')
1131                save = {}
1132                oldThreshold = data['Thresholds'][0]
1133                S = File.readline()
1134                while S:
1135                    if S[0] == '#':
1136                        S = File.readline()
1137                        continue
1138                    [key,val] = S[:-1].split(':')
1139                    if key in ['Points','Rings','Arcs','Polygons','Frames','Thresholds']:
1140                        if ignoreThreshold and key == 'Thresholds': continue
1141                        save[key] = eval(val)
1142                        if key == 'Thresholds':
1143                            save[key][0] = oldThreshold
1144                            save[key][1][1] = min(oldThreshold[1],save[key][1][1])
1145                    S = File.readline()
1146                File.close()
1147                data.update(save)
1148                CleanupMasks(data)
1149                wx.CallAfter(UpdateMasks,G2frame,data)
1150                G2plt.PlotExposedImage(G2frame,event=event)               
1151        finally:
1152            dlg.Destroy()
1153           
1154    def OnNewSpotMask(event):
1155        'Start a new spot mask'
1156        G2frame.MaskKey = 's'
1157        G2plt.OnStartMask(G2frame)
1158       
1159    def OnNewArcMask(event):
1160        'Start a new arc mask'
1161        G2frame.MaskKey = 'a'
1162        G2plt.OnStartMask(G2frame)
1163       
1164    def OnNewRingMask(event):
1165        'Start a new ring mask'
1166        G2frame.MaskKey = 'r'
1167        G2plt.OnStartMask(G2frame)
1168       
1169    def OnNewPolyMask(event):
1170        'Start a new polygon mask'
1171        G2frame.MaskKey = 'p'
1172        G2plt.OnStartMask(G2frame)
1173       
1174    def OnNewFrameMask(event):
1175        'Start a new Frame mask'
1176        G2frame.MaskKey = 'f'
1177        G2plt.OnStartMask(G2frame)
1178
1179    startScroll = None
1180    if G2frame.dataDisplay:
1181        startScroll = G2frame.dataDisplay.GetScrollPos(wx.VERTICAL) # save scroll position
1182        G2frame.dataDisplay.Destroy()
1183    else:
1184        CleanupMasks(data) # posting page for 1st time; clean out anything unfinished
1185    G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.MaskMenu)
1186    G2frame.dataFrame.Bind(wx.EVT_MENU, OnCopyMask, id=G2gd.wxID_MASKCOPY)
1187    G2frame.dataFrame.Bind(wx.EVT_MENU, OnLoadMask, id=G2gd.wxID_MASKLOAD)
1188    G2frame.dataFrame.Bind(wx.EVT_MENU, OnLoadMask, id=G2gd.wxID_MASKLOADNOT)
1189    G2frame.dataFrame.Bind(wx.EVT_MENU, OnSaveMask, id=G2gd.wxID_MASKSAVE)
1190    G2frame.dataFrame.Bind(wx.EVT_MENU, OnNewSpotMask, id=G2gd.wxID_NEWMASKSPOT)
1191    G2frame.dataFrame.Bind(wx.EVT_MENU, OnNewArcMask, id=G2gd.wxID_NEWMASKARC)
1192    G2frame.dataFrame.Bind(wx.EVT_MENU, OnNewRingMask, id=G2gd.wxID_NEWMASKRING)
1193    G2frame.dataFrame.Bind(wx.EVT_MENU, OnNewPolyMask, id=G2gd.wxID_NEWMASKPOLY)
1194    G2frame.dataFrame.Bind(wx.EVT_MENU, OnNewFrameMask, id=G2gd.wxID_NEWMASKFRAME)
1195    if not G2frame.dataFrame.GetStatusBar():
1196        Status = G2frame.dataFrame.CreateStatusBar()
1197    if G2frame.MaskKey == 'f':
1198        G2frame.dataFrame.GetStatusBar().SetStatusText('Frame mask active - LB pick next point, RB close polygon')
1199    elif G2frame.MaskKey == 'p':
1200        G2frame.dataFrame.GetStatusBar().SetStatusText('Polygon mask active - LB pick next point, RB close polygon')
1201    elif G2frame.MaskKey == 's':
1202        G2frame.dataFrame.GetStatusBar().SetStatusText('Spot mask active - LB pick spot location')
1203    elif G2frame.MaskKey == 'a':
1204        G2frame.dataFrame.GetStatusBar().SetStatusText('Arc mask active - LB pick arc location')
1205    elif G2frame.MaskKey == 'r':
1206        G2frame.dataFrame.GetStatusBar().SetStatusText('Ring mask active - LB pick ring location')
1207    else:
1208        G2frame.dataFrame.GetStatusBar().SetStatusText("To add mask: press a,r,s,p or f on 2D image for arc/ring/spot/polygon/frame")
1209    G2frame.dataDisplay = wxscroll.ScrolledPanel(G2frame.dataFrame)
1210    mainSizer = wx.BoxSizer(wx.VERTICAL)
1211    mainSizer.Add((5,10),0)
1212
1213    thresh = data['Thresholds']         #min/max intensity range
1214    Spots = data['Points']               #x,y,radius in mm
1215    Rings = data['Rings']               #radius, thickness
1216    Polygons = data['Polygons']         #3+ x,y pairs
1217    if 'Frames' not in data:
1218        data['Frames'] = []
1219    frame = data['Frames']             #3+ x,y pairs
1220    Arcs = data['Arcs']                 #radius, start/end azimuth, thickness
1221   
1222    littleSizer = wx.FlexGridSizer(0,3,0,5)
1223    littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Lower/Upper limits '),0,WACV)
1224    Text = wx.TextCtrl(G2frame.dataDisplay,value=str(thresh[0][0]),style=wx.TE_READONLY)
1225    littleSizer.Add(Text,0,WACV)
1226    Text.SetBackgroundColour(VERY_LIGHT_GREY)
1227    Text = wx.TextCtrl(G2frame.dataDisplay,value=str(thresh[0][1]),style=wx.TE_READONLY)
1228    littleSizer.Add(Text,0,WACV)
1229    Text.SetBackgroundColour(VERY_LIGHT_GREY)
1230    littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Lower/Upper thresholds '),0,WACV)
1231    lowerThreshold = G2G.ValidatedTxtCtrl(G2frame.dataDisplay,loc=thresh[1],key=0,
1232                                           min=thresh[0][0],OnLeave=Replot,typeHint=int)
1233    littleSizer.Add(lowerThreshold,0,WACV)
1234    upperThreshold = G2G.ValidatedTxtCtrl(G2frame.dataDisplay,loc=thresh[1],key=1,
1235                                           max=thresh[0][1],OnLeave=Replot,typeHint=int)
1236    littleSizer.Add(upperThreshold,0,WACV)
1237    mainSizer.Add(littleSizer,0,)
1238    if Spots:
1239        lbl = wx.StaticText(parent=G2frame.dataDisplay,label=' Spot masks')
1240        lbl.SetBackgroundColour(wx.Colour(200,200,210))
1241        mainSizer.Add(lbl,0,wx.EXPAND|wx.ALIGN_CENTER,0)
1242        littleSizer = wx.FlexGridSizer(0,3,0,5)
1243        littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' position, mm'),0,WACV)
1244        littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' diameter, mm'),0,WACV)
1245        littleSizer.Add((5,0),0)
1246        for i in range(len(Spots)):
1247            if Spots[i]:
1248                x,y,d = Spots[i]
1249                spotText = wx.TextCtrl(parent=G2frame.dataDisplay,value=("%.2f,%.2f" % (x,y)),
1250                    style=wx.TE_READONLY)
1251                spotText.SetBackgroundColour(VERY_LIGHT_GREY)
1252                littleSizer.Add(spotText,0,WACV)
1253                spotText.Bind(wx.EVT_ENTER_WINDOW,OnTextMsg)
1254                spotDiameter = G2G.ValidatedTxtCtrl(G2frame.dataDisplay,loc=Spots[i],key=2,
1255                                           max=100.,OnLeave=Replot,nDig=[8,2])
1256                littleSizer.Add(spotDiameter,0,WACV)
1257                spotDelete = G2gd.G2LoggedButton(G2frame.dataDisplay,label='delete?',
1258                                            locationcode='Delete+Points+'+str(i),
1259                                            handler=onDeleteMask)
1260                littleSizer.Add(spotDelete,0,WACV)
1261        mainSizer.Add(littleSizer,0,)
1262    if Rings:
1263        lbl = wx.StaticText(parent=G2frame.dataDisplay,label=' Ring masks')
1264        lbl.SetBackgroundColour(wx.Colour(200,200,210))
1265        mainSizer.Add(lbl,0,wx.EXPAND|wx.ALIGN_CENTER,0)
1266        littleSizer = wx.FlexGridSizer(0,3,0,5)
1267        littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' 2-theta,deg'),0,WACV)
1268        littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' thickness, deg'),0,WACV)
1269        littleSizer.Add((5,0),0)
1270        for i in range(len(Rings)):
1271            if Rings[i]:
1272                ringText = wx.TextCtrl(parent=G2frame.dataDisplay,value=("%.3f" % (Rings[i][0])),
1273                    style=wx.TE_READONLY)
1274                ringText.SetBackgroundColour(VERY_LIGHT_GREY)
1275                ringText.Bind(wx.EVT_ENTER_WINDOW,OnTextMsg)
1276                littleSizer.Add(ringText,0,WACV)
1277                ringThick = G2G.ValidatedTxtCtrl(G2frame.dataDisplay,loc=Rings[i],key=1,
1278                                           min=0.001,max=1.,OnLeave=Replot,nDig=[8,3])
1279                littleSizer.Add(ringThick,0,WACV)
1280                ringDelete = G2gd.G2LoggedButton(G2frame.dataDisplay,label='delete?',
1281                                            locationcode='Delete+Rings+'+str(i),
1282                                            handler=onDeleteMask)
1283                littleSizer.Add(ringDelete,0,WACV)
1284        mainSizer.Add(littleSizer,0,)
1285    if Arcs:
1286        lbl = wx.StaticText(parent=G2frame.dataDisplay,label=' Arc masks')
1287        lbl.SetBackgroundColour(wx.Colour(200,200,210))
1288        mainSizer.Add(lbl,0,wx.EXPAND|wx.ALIGN_CENTER,0)
1289        littleSizer = wx.FlexGridSizer(0,4,0,5)
1290        littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' 2-theta,deg'),0,WACV)
1291        littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' azimuth, deg'),0,WACV)
1292        littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' thickness, deg'),0,WACV)
1293        littleSizer.Add((5,0),0)
1294        for i in range(len(Arcs)):
1295            if Arcs[i]:
1296                tth,azimuth,thick = Arcs[i]
1297                arcText = wx.TextCtrl(parent=G2frame.dataDisplay,value=("%.3f" % (tth)),
1298                    style=wx.TE_READONLY)
1299                arcText.SetBackgroundColour(VERY_LIGHT_GREY)
1300                arcText.Bind(wx.EVT_ENTER_WINDOW,OnTextMsg)
1301                littleSizer.Add(arcText,0,WACV)
1302                azmText = wx.TextCtrl(parent=G2frame.dataDisplay,value=("%d,%d" % (azimuth[0],azimuth[1])),
1303                    style=wx.TE_READONLY)
1304                azmText.SetBackgroundColour(VERY_LIGHT_GREY)
1305                azmText.Bind(wx.EVT_ENTER_WINDOW,OnTextMsg)
1306                littleSizer.Add(azmText,0,WACV)
1307                arcThick = G2G.ValidatedTxtCtrl(G2frame.dataDisplay,loc=Arcs[i],key=2,
1308                                           min=0.001,max=20.,OnLeave=Replot,nDig=[8,3])
1309                littleSizer.Add(arcThick,0,WACV)
1310                arcDelete = G2gd.G2LoggedButton(G2frame.dataDisplay,label='delete?',
1311                                            locationcode='Delete+Arcs+'+str(i),
1312                                            handler=onDeleteMask)
1313                littleSizer.Add(arcDelete,0,WACV)
1314        mainSizer.Add(littleSizer,0,)
1315    if Polygons:
1316        lbl = wx.StaticText(parent=G2frame.dataDisplay,
1317            label=' Polygon masks (on plot RB vertex drag to move,\nLB vertex drag to insert)')
1318        lbl.SetBackgroundColour(wx.Colour(200,200,210))
1319        mainSizer.Add(lbl,0,wx.EXPAND|wx.ALIGN_CENTER,0)
1320        littleSizer = wx.FlexGridSizer(0,2,0,5)
1321        for i in range(len(Polygons)):
1322            if Polygons[i]:
1323                polyList = []
1324                for x,y in Polygons[i]:
1325                    polyList.append("%.2f, %.2f"%(x,y))
1326                polyText = wx.ComboBox(G2frame.dataDisplay,value=polyList[0],choices=polyList,style=wx.CB_READONLY)
1327                littleSizer.Add(polyText,0,WACV)
1328                polyDelete = G2gd.G2LoggedButton(G2frame.dataDisplay,label='delete?',
1329                                            locationcode='Delete+Polygons+'+str(i),
1330                                            handler=onDeleteMask)
1331                littleSizer.Add(polyDelete,0,WACV)
1332        mainSizer.Add(littleSizer,0,)
1333    if frame:
1334        lbl = wx.StaticText(parent=G2frame.dataDisplay,
1335            label=' Frame mask (on plot RB vertex drag to move,\nLB vertex drag to insert)')
1336        lbl.SetBackgroundColour(wx.Colour(200,200,210))
1337        mainSizer.Add(lbl,0,wx.EXPAND|wx.ALIGN_CENTER,0)
1338        littleSizer = wx.FlexGridSizer(0,2,0,5)
1339        frameList = []
1340        for x,y in frame:
1341            frameList.append("%.2f, %.2f"%(x,y))
1342        frameText = wx.ComboBox(G2frame.dataDisplay,value=frameList[0],choices=frameList,style=wx.CB_READONLY)
1343        littleSizer.Add(frameText,0,WACV)
1344        frameDelete = G2gd.G2LoggedButton(G2frame.dataDisplay,label='delete?',
1345                                            locationcode='Delete+Frame',
1346                                            handler=onDeleteFrame)
1347        littleSizer.Add(frameDelete,0,WACV)
1348        mainSizer.Add(littleSizer,0,)
1349    mainSizer.Layout()   
1350    G2frame.dataDisplay.SetSizer(mainSizer)
1351    G2frame.dataDisplay.SetSize(mainSizer.Fit(G2frame.dataFrame))
1352    G2frame.dataDisplay.SetupScrolling()
1353    Size = mainSizer.Fit(G2frame.dataFrame)
1354    Size[0] += 50 # room for scrollbar & status msg
1355    Size[1] = min(Size[1],500)
1356    G2frame.dataDisplay.SetSize(Size)
1357    G2frame.dataFrame.setSizePosLeft(Size)   
1358    wx.Yield()
1359    if startScroll: # reset scroll to saved position
1360        G2frame.dataDisplay.Scroll(0,startScroll) # set to saved scroll position
1361        wx.Yield()
1362
1363################################################################################
1364##### Stress/Strain
1365################################################################################
1366
1367def UpdateStressStrain(G2frame,data):
1368    '''Shows and handles the controls on the "Stress/Strain"
1369    data tree entry
1370    '''
1371   
1372    def OnAppendDzero(event):
1373        data['d-zero'].append({'Dset':1.0,'Dcalc':0.0,'pixLimit':10,'cutoff':1.0,
1374            'ImxyObs':[[],[]],'ImtaObs':[[],[]],'ImtaCalc':[[],[]],'Emat':[1.0,1.0,1.0]})
1375        UpdateStressStrain(G2frame,data)
1376       
1377    def OnUpdateDzero(event):
1378        for item in data['d-zero']:
1379            if item['Dcalc']:   #skip unrefined ones
1380                item['Dset'] = item['Dcalc']
1381        UpdateStressStrain(G2frame,data)
1382           
1383    def OnCopyStrSta(event):
1384        TextList = [[False,'All IMG',0,0]]
1385        Names = []
1386        if G2frame.PatternTree.GetCount():
1387            id, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root)
1388            while id:
1389                name = G2frame.PatternTree.GetItemText(id)
1390                Names.append(name)
1391                if 'IMG' in name:
1392                    Data = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,id, 'Stress/Strain'))
1393                    if id == G2frame.Image:
1394                        Source = name
1395                    else:
1396                        TextList.append([False,name,id,Data.get('Sample load',0.0)])
1397                id, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie)
1398            if len(TextList) == 1:
1399                G2frame.ErrorDialog('Nothing to copy controls to','There must be more than one "IMG" pattern')
1400                return
1401            dlg = G2frame.CopyDialog(G2frame,'Copy stress/strain controls','Copy controls from '+Source+' to:',TextList)
1402            try:
1403                if dlg.ShowModal() == wx.ID_OK:
1404                    result = dlg.GetData()
1405                    if result[0][0]:
1406                        result = TextList[1:]
1407                        for item in result: item[0] = True
1408                    for i,item in enumerate(result):
1409                        ifcopy,name,id,load = item
1410                        if ifcopy:
1411                            Data = copy.deepcopy(data)
1412                            Data['Sample load'] = load
1413                            G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,id, 'Stress/Strain'),Data)
1414            finally:
1415                dlg.Destroy()
1416
1417    def OnLoadStrSta(event):
1418        dlg = wx.FileDialog(G2frame, 'Choose stress/strain file', '.', '', 
1419            'image control files (*.strsta)|*.strsta',wx.OPEN|wx.CHANGE_DIR)
1420        try:
1421            if dlg.ShowModal() == wx.ID_OK:
1422                filename = dlg.GetPath()
1423                File = open(filename,'r')
1424                S = File.read()
1425                data = eval(S)
1426                Controls = G2frame.PatternTree.GetItemPyData(
1427                    G2gd.GetPatternTreeItemId(G2frame,G2frame.Image, 'Image Controls'))
1428                G2img.FitStrSta(G2frame.ImageZ,data,Controls)
1429                UpdateStressStrain(G2frame,data)
1430                G2plt.PlotExposedImage(G2frame,event=event)
1431                G2plt.PlotStrain(G2frame,data,newPlot=True)
1432                File.close()
1433        finally:
1434            dlg.Destroy()
1435
1436    def OnSaveStrSta(event):
1437        dlg = wx.FileDialog(G2frame, 'Choose stress/strain file', '.', '', 
1438            'image control files (*.strsta)|*.strsta',wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT|wx.CHANGE_DIR)
1439        try:
1440            if dlg.ShowModal() == wx.ID_OK:
1441                filename = dlg.GetPath()
1442                File = open(filename,'w')
1443                save = {}
1444                keys = ['Type','Sample phi','Sample z','Sample load']
1445                keys2 = ['Dset','Dcalc','pixLimit','cutoff','Emat']
1446                File.write('{\n\t')
1447                for key in keys:
1448                    if key in 'Type':
1449                        File.write("'"+key+"':'"+data[key]+"',")
1450                    else:
1451                        File.write("'"+key+"':"+str(data[key])+',')
1452                File.write('\n\t'+"'d-zero':[\n")
1453                for data2 in data['d-zero']:
1454                    File.write('\t\t{')
1455                    for key in keys2:
1456                        File.write("'"+key+"':"+str(data2[key])+',')
1457                    File.write("'ImxyObs':[[],[]],'ImtaObs':[[],[]],'ImtaCalc':[[],[]]},\n")
1458                File.write('\t]\n}')
1459                File.close()
1460        finally:
1461            dlg.Destroy()
1462           
1463    def OnStrStaSample(event):
1464        filename = ''
1465        dlg = wx.FileDialog(G2frame, 'Choose multihistogram metadata text file', '.', '', 
1466            'metadata file (*.*)|*.*',wx.OPEN|wx.CHANGE_DIR)
1467        try:
1468            if dlg.ShowModal() == wx.ID_OK:
1469                filename = dlg.GetPath()
1470                File = open(filename,'r')
1471                S = File.readline()
1472                newItems = []
1473                itemNames = []
1474                Comments = []
1475                while S:
1476                    if S[0] == '#':
1477                        Comments.append(S)
1478                        S = File.readline()
1479                        continue
1480                    S = S.replace(',',' ').replace('\t',' ')
1481                    Stuff = S[:-1].split()
1482                    itemNames.append(Stuff[0])
1483                    newItems.append(Stuff[1:])
1484                    S = File.readline()               
1485                File.close()
1486        finally:
1487            dlg.Destroy()
1488        if not filename:
1489            G2frame.ErrorDialog('Nothing to do','No file selected')
1490            return
1491        dataDict = dict(zip(itemNames,newItems))
1492        ifany = False
1493        Names = [' ','Sample phi','Sample z','Sample load']
1494        dlg = G2gd.G2ColumnIDDialog( G2frame,' Choose multihistogram metadata columns:',
1495            'Select columns',Comments,Names,np.array(newItems).T)
1496        try:
1497            if dlg.ShowModal() == wx.ID_OK:
1498                colNames,newData = dlg.GetSelection()
1499                dataDict = dict(zip(itemNames,newData.T))
1500                for item in colNames:
1501                    if item != ' ':
1502                        ifany = True
1503        finally:
1504            dlg.Destroy()
1505        if not ifany:
1506            G2frame.ErrorDialog('Nothing to do','No columns identified')
1507            return
1508        histList = []
1509        item, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root)       
1510        while item:
1511            name = G2frame.PatternTree.GetItemText(item)
1512            if name.startswith('IMG'):
1513                histList.append(name)
1514            item, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie)
1515        colIds = {}
1516        for i,name in enumerate(colNames):
1517            if name != ' ':
1518                colIds[name] = i
1519        for hist in histList:
1520            name = hist.split()[1]  #this is file name
1521            if name in dataDict:
1522                newItems = {}
1523                for item in colIds:
1524                    newItems[item] = float(dataDict[name][colIds[item]])
1525                Id = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,hist)
1526                stsrData = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,Id,'Stress/Strain'))
1527                stsrData.update(newItems)       
1528        UpdateStressStrain(G2frame,data)       
1529   
1530    def OnFitStrSta(event):
1531        Controls = G2frame.PatternTree.GetItemPyData(
1532            G2gd.GetPatternTreeItemId(G2frame,G2frame.Image, 'Image Controls'))
1533        G2img.FitStrSta(G2frame.ImageZ,data,Controls)
1534        print 'Strain fitting finished'
1535        UpdateStressStrain(G2frame,data)
1536        G2plt.PlotExposedImage(G2frame,event=event)
1537        G2plt.PlotStrain(G2frame,data,newPlot=True)
1538       
1539    def OnFitAllStrSta(event):
1540        TextList = [[False,'All IMG',0]]
1541        Names = []
1542        if G2frame.PatternTree.GetCount():
1543            choices = G2gd.GetPatternTreeDataNames(G2frame,['IMG ',])
1544            if len(choices) == 1:
1545                G2frame.ErrorDialog('Nothing to fit','There must some "IMG" patterns')
1546                return
1547            sel = []
1548            dlg = G2gd.G2MultiChoiceDialog(G2frame,'Stress/Strain fitting','Select images to fit:',choices)
1549            dlg.SetSelections(sel)
1550            names = []
1551            if dlg.ShowModal() == wx.ID_OK:
1552                for sel in dlg.GetSelections():
1553                    names.append(choices[sel])
1554            dlg.Destroy()
1555            SeqResult = {}
1556            dlg = wx.ProgressDialog('Sequential IMG Strain fit','Data set name = '+names[0],len(names), 
1557                style = wx.PD_ELAPSED_TIME|wx.PD_AUTO_HIDE|wx.PD_REMAINING_TIME|wx.PD_CAN_ABORT)         
1558            wx.BeginBusyCursor()
1559            goodnames = []
1560            try:
1561                for i,name in enumerate(names):
1562                    print ' Sequential strain fit for ',name
1563                    GoOn = dlg.Update(i,newmsg='Data set name = '+name)[0]
1564                    if not GoOn:
1565                        break
1566                    Id =  G2gd.GetPatternTreeItemId(G2frame,G2frame.root,name)
1567                    Controls = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,Id, 'Image Controls'))
1568                    StaCtrls = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,Id, 'Stress/Strain'))
1569                    if not len(StaCtrls['d-zero']):
1570                        continue
1571                    goodnames.append(name)
1572                    id = G2gd.GetPatternTreeItemId(G2frame, G2frame.root, name)
1573                    Npix,imagefile = G2frame.PatternTree.GetItemPyData(Id)
1574                    image = G2IO.GetImageData(G2frame,imagefile,True)
1575                    dark = Controls['dark image']
1576                    if dark[0]:
1577                        darkfile = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame, 
1578                            G2frame.root,dark[0]))[1]
1579                        darkImg = G2IO.GetImageData(G2frame,darkfile,imageOnly=True)
1580                        image += dark[1]*darkImg
1581                    G2img.FitStrSta(image,StaCtrls,Controls)
1582                    G2plt.PlotStrain(G2frame,StaCtrls,newPlot=True)
1583                    parmDict = {'Sample load':StaCtrls['Sample load'],}
1584                    varyNames = ['e11','e12','e22']
1585                    sig = []
1586                    varyList = []
1587                    variables = []
1588                    for i,item in enumerate(StaCtrls['d-zero']):
1589                        variables += item['Emat']
1590                        sig += item['Esig']
1591                        varylist = ['%d%s%s'%(i,':',Name) for Name in varyNames]
1592                        varyList += varylist
1593                        parmDict.update(dict(zip(varylist,item['Emat'])))
1594                        parmDict['%d:Dcalc'%(i)] = item['Dcalc']
1595                    SeqResult[name] = {'variables':variables,'varyList':varyList,'sig':sig,'Rvals':[],
1596                        'covMatrix':np.eye(len(variables)),'title':name,'parmDict':parmDict}
1597                else:
1598                    SeqResult['histNames'] = goodnames
1599                    dlg.Destroy()
1600                    print ' ***** Sequential strain refinement successful *****'
1601            finally:
1602                wx.EndBusyCursor()   
1603            Id =  G2gd.GetPatternTreeItemId(G2frame,G2frame.root,'Sequential results')
1604            if Id:
1605                G2frame.PatternTree.SetItemPyData(Id,SeqResult)
1606            else:
1607                Id = G2frame.PatternTree.AppendItem(parent=G2frame.root,text='Sequential results')
1608                G2frame.PatternTree.SetItemPyData(Id,SeqResult)
1609            G2frame.PatternTree.SelectItem(Id)
1610            print 'All images fitted'
1611       
1612    def SamSizer():
1613       
1614        def OnStrainType(event):
1615            data['Type'] = strType.GetValue()
1616       
1617        def OnSamPhi(event):
1618            try:
1619                value = float(samPhi.GetValue())
1620            except ValueError:
1621                value = data['Sample phi']
1622            data['Sample phi'] = value
1623            samPhi.SetValue("%.3f" % (data['Sample phi']))
1624               
1625        def OnSamZ(event):
1626            try:
1627                value = float(samZ.GetValue())
1628            except ValueError:
1629                value = data['Sample z']
1630            data['Sample z'] = value
1631            samZ.SetValue("%.3f" % (data['Sample z']))
1632               
1633        def OnSamLoad(event):
1634            try:
1635                value = float(samLoad.GetValue())
1636            except ValueError:
1637                value = data['Sample load']
1638            data['Sample load'] = value
1639            samLoad.SetValue("%.3f" % (data['Sample load']))
1640               
1641        samSizer = wx.BoxSizer(wx.HORIZONTAL)
1642        samSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,label=' Strain type: '),0,WACV)
1643        strType = wx.ComboBox(G2frame.dataDisplay,value=data['Type'],choices=['True','Conventional'],
1644            style=wx.CB_READONLY|wx.CB_DROPDOWN)
1645        strType.SetValue(data['Type'])
1646        strType.Bind(wx.EVT_COMBOBOX, OnStrainType)
1647        samSizer.Add(strType,0,WACV)
1648       
1649        samSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,label=' Sample phi: '),0,WACV)
1650        samPhi = wx.TextCtrl(G2frame.dataDisplay,-1,value=("%.3f" % (data['Sample phi'])),
1651            style=wx.TE_PROCESS_ENTER)
1652        samSizer.Add(samPhi,0,WACV)
1653        samPhi.Bind(wx.EVT_TEXT_ENTER,OnSamPhi)
1654        samPhi.Bind(wx.EVT_KILL_FOCUS,OnSamPhi)
1655        samSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,label=' Sample delta-z(mm): '),0,WACV)
1656        samZ = wx.TextCtrl(G2frame.dataDisplay,-1,value=("%.3f" % (data['Sample z'])),
1657            style=wx.TE_PROCESS_ENTER)
1658        samSizer.Add(samZ,0,WACV)
1659        samZ.Bind(wx.EVT_TEXT_ENTER,OnSamZ)
1660        samZ.Bind(wx.EVT_KILL_FOCUS,OnSamZ)
1661        samSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,label=' Sample load(MPa): '),0,WACV)
1662        samLoad = G2G.ValidatedTxtCtrl(G2frame.dataDisplay,data,'Sample load',
1663                nDig=[8,3],typeHint=float,)
1664        samSizer.Add(samLoad,0,WACV)
1665
1666        return samSizer
1667       
1668    def DzeroSizer():
1669   
1670        def OnDzero(event):
1671            Obj = event.GetEventObject()
1672            try:
1673                value = min(20.0,max(0.25,float(Obj.GetValue())))
1674            except ValueError:
1675                value = 1.0
1676            Obj.SetValue("%.5f"%(value))
1677            data['d-zero'][Indx[Obj.GetId()]]['Dset'] = value
1678            data['d-zero'] = G2mth.sortArray(data['d-zero'],'Dset',reverse=True)
1679            Ring,R = G2img.MakeStrStaRing(data['d-zero'][Indx[Obj.GetId()]],G2frame.ImageZ,Controls)
1680            if len(Ring):
1681                data['d-zero'][Indx[Obj.GetId()]].update(R)
1682            else:
1683                G2frame.ErrorDialog('Strain peak selection','WARNING - No points found for this ring selection')
1684               
1685            UpdateStressStrain(G2frame,data)
1686            G2plt.PlotExposedImage(G2frame,event=event,newPlot=False)
1687            G2plt.PlotStrain(G2frame,data,newPlot=True)
1688           
1689        def OnDeleteDzero(event):
1690            Obj = event.GetEventObject()
1691            del(data['d-zero'][delIndx.index(Obj)])
1692            UpdateStressStrain(G2frame,data)
1693            G2plt.PlotExposedImage(G2frame,event=event,newPlot=True)
1694            G2plt.PlotStrain(G2frame,data,newPlot=True)
1695       
1696        def OnCutOff(event):
1697            Obj = event.GetEventObject()
1698            try:
1699                value = min(10.0,max(0.5,float(Obj.GetValue())))
1700            except ValueError:
1701                value = 1.0
1702            Obj.SetValue("%.1f"%(value))
1703            data['d-zero'][Indx[Obj.GetId()]]['cutoff'] = value
1704            Ring,R = G2img.MakeStrStaRing(data['d-zero'][Indx[Obj.GetId()]],G2frame.ImageZ,Controls)
1705            G2plt.PlotExposedImage(G2frame,event=event)
1706            G2plt.PlotStrain(G2frame,data,newPlot=True)
1707       
1708        def OnPixLimit(event):
1709            Obj = event.GetEventObject()
1710            data['d-zero'][Indx[Obj.GetId()]]['pixLimit'] = int(Obj.GetValue())
1711            Ring,R = G2img.MakeStrStaRing(data['d-zero'][Indx[Obj.GetId()]],G2frame.ImageZ,Controls)
1712            G2plt.PlotExposedImage(G2frame,event=event)
1713            G2plt.PlotStrain(G2frame,data,newPlot=True)
1714           
1715        Indx = {}
1716        delIndx = []   
1717        dzeroSizer = wx.FlexGridSizer(0,8,5,5)
1718        for id,dzero in enumerate(data['d-zero']):
1719            dzeroSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,label=(' d-zero #%d: '%(id))),0,WACV)
1720            dZero = wx.TextCtrl(G2frame.dataDisplay,-1,value=('%.5f'%(dzero['Dset'])),
1721                style=wx.TE_PROCESS_ENTER)
1722            dzeroSizer.Add(dZero,0,WACV)
1723            dZero.Bind(wx.EVT_TEXT_ENTER,OnDzero)
1724            dZero.Bind(wx.EVT_KILL_FOCUS,OnDzero)
1725            Indx[dZero.GetId()] = id
1726            dzeroSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,label=(' d-zero ave: %.5f'%(dzero['Dcalc']))),0,WACV)
1727               
1728            dzeroSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Min ring I/Ib '),0,WACV)
1729            cutOff = wx.TextCtrl(parent=G2frame.dataDisplay,value=("%.1f" % (dzero['cutoff'])),
1730                style=wx.TE_PROCESS_ENTER)
1731            cutOff.Bind(wx.EVT_TEXT_ENTER,OnCutOff)
1732            cutOff.Bind(wx.EVT_KILL_FOCUS,OnCutOff)
1733            Indx[cutOff.GetId()] = id
1734            dzeroSizer.Add(cutOff,0,WACV)
1735       
1736            dzeroSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Pixel search range '),0,WACV)
1737            pixLimit = wx.ComboBox(parent=G2frame.dataDisplay,value=str(dzero['pixLimit']),choices=['1','2','5','10','15','20'],
1738                style=wx.CB_READONLY|wx.CB_DROPDOWN)
1739            pixLimit.Bind(wx.EVT_COMBOBOX, OnPixLimit)
1740            Indx[pixLimit.GetId()] = id
1741            dzeroSizer.Add(pixLimit,0,WACV)               
1742               
1743            dzeroDelete = wx.CheckBox(parent=G2frame.dataDisplay,label='delete?')
1744            dzeroDelete.Bind(wx.EVT_CHECKBOX,OnDeleteDzero)
1745            delIndx.append(dzeroDelete)
1746            dzeroSizer.Add(dzeroDelete,0,WACV)
1747           
1748            dzeroSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,label=(' Strain tensor:')),WACV)
1749            names = ['e11','e12','e22']
1750            for i in range(3):
1751                dzeroSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,label=names[i]),0,WACV)
1752                tensorElem = wx.TextCtrl(G2frame.dataDisplay,-1,value='%.2f'%(dzero['Emat'][i]),style=wx.TE_READONLY)
1753                tensorElem.SetBackgroundColour(VERY_LIGHT_GREY)
1754                dzeroSizer.Add(tensorElem,0,WACV)
1755            dzeroSizer.Add((5,5),0)             
1756        return dzeroSizer
1757       
1758# patches
1759    if 'Sample load' not in data:
1760        data['Sample load'] = 0.0
1761# end patches
1762   
1763    if G2frame.dataDisplay:
1764        G2frame.dataDisplay.Destroy()
1765    Controls = G2frame.PatternTree.GetItemPyData(
1766        G2gd.GetPatternTreeItemId(G2frame,G2frame.Image, 'Image Controls'))       
1767    G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.StrStaMenu)
1768    G2frame.dataFrame.Bind(wx.EVT_MENU, OnAppendDzero, id=G2gd.wxID_APPENDDZERO)
1769    G2frame.dataFrame.Bind(wx.EVT_MENU, OnUpdateDzero, id=G2gd.wxID_UPDATEDZERO)
1770    G2frame.dataFrame.Bind(wx.EVT_MENU, OnFitStrSta, id=G2gd.wxID_STRSTAFIT)
1771    G2frame.dataFrame.Bind(wx.EVT_MENU, OnFitAllStrSta, id=G2gd.wxID_STRSTAALLFIT)
1772    G2frame.dataFrame.Bind(wx.EVT_MENU, OnCopyStrSta, id=G2gd.wxID_STRSTACOPY)
1773    G2frame.dataFrame.Bind(wx.EVT_MENU, OnLoadStrSta, id=G2gd.wxID_STRSTALOAD)
1774    G2frame.dataFrame.Bind(wx.EVT_MENU, OnSaveStrSta, id=G2gd.wxID_STRSTASAVE)
1775    G2frame.dataFrame.Bind(wx.EVT_MENU, OnStrStaSample, id=G2gd.wxID_STRSTSAMPLE)       
1776    if not G2frame.dataFrame.GetStatusBar():
1777        Status = G2frame.dataFrame.CreateStatusBar()
1778    if G2frame.StrainKey == 'a':    #probably doesn't happen
1779        G2frame.dataFrame.GetStatusBar().SetStatusText('Add strain ring active - LB pick d-zero value')
1780    else:
1781        G2frame.dataFrame.GetStatusBar().SetStatusText("To add strain data: On 2D Powder Image, key a:add ring")
1782       
1783    G2frame.dataDisplay = wxscroll.ScrolledPanel(G2frame.dataFrame)
1784    mainSizer = wx.BoxSizer(wx.VERTICAL)
1785    mainSizer.Add((5,10),0)
1786    mainSizer.Add(SamSizer())
1787    mainSizer.Add((5,10),0)
1788    mainSizer.Add(DzeroSizer())
1789   
1790    mainSizer.Layout()   
1791    G2frame.dataDisplay.SetSizer(mainSizer)
1792    G2frame.dataDisplay.SetAutoLayout(1)
1793    G2frame.dataDisplay.SetupScrolling()
1794    Size = mainSizer.Fit(G2frame.dataFrame)
1795    Size[0] += 25
1796    G2frame.dataDisplay.SetSize(Size)
1797    G2frame.dataFrame.setSizePosLeft(Size)   
Note: See TracBrowser for help on using the repository browser.