source: trunk/GSASIIimgGUI.py @ 1583

Last change on this file since 1583 was 1583, checked in by toby, 8 years ago

cleanup masks before integration; add zoom buttons to mpl window; wx2.9+ fix for seq ref window

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