source: trunk/GSASIIimgGUI.py @ 1944

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

add G2HistDataDialog for editing e.g. orientation angles over all images - could be used elsewhere
fix problem of bad RefList? key on plotting new histograms
fix failure (file busy!) in GPXBackup

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