source: trunk/GSASIIimgGUI.py @ 2051

Last change on this file since 2051 was 2051, checked in by toby, 10 years ago

address crash on selecting Q steps (now capitalized): change all CallAfter? to CallLater? for UpdateImageControls? calls

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Author Revision URL Id
File size: 87.7 KB
Line 
1# -*- coding: utf-8 -*-
2#GSASII - image data display routines
3########### SVN repository information ###################
4# $Date: 2015-11-13 22:36:21 +0000 (Fri, 13 Nov 2015) $
5# $Author: toby $
6# $Revision: 2051 $
7# $URL: trunk/GSASIIimgGUI.py $
8# $Id: GSASIIimgGUI.py 2051 2015-11-13 22:36:21Z toby $
9########### SVN repository information ###################
10'''
11*GSASIIimgGUI: Image GUI*
12-------------------------
13
14Control image display and processing
15
16'''
17import os.path
18import wx
19import wx.lib.scrolledpanel as wxscroll
20import matplotlib as mpl
21import math
22import time
23import copy
24import GSASIIpath
25GSASIIpath.SetVersionNumber("$Revision: 2051 $")
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,IntegrateOnly=False):
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.CallLater(100,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.CallLater(100,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.CallLater(100,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.CallLater(100,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.CallLater(100,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'].lower():
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    if IntegrateOnly:
1034        OnIntegrate(None)
1035        return
1036   
1037    colorList = sorted([m for m in mpl.cm.datad.keys() if not m.endswith("_r")],key=lambda s: s.lower())
1038    calList = sorted([m for m in calFile.Calibrants.keys()],key=lambda s: s.lower())
1039    typeList = ['PWDR - powder diffraction data','SASD - small angle scattering data',
1040        'REFL - reflectometry data']
1041    if not data.get('type'):                        #patch for old project files
1042        data['type'] = 'PWDR'
1043    typeDict = {'PWDR':typeList[0],'SASD':typeList[1],'REFL':typeList[2]}
1044    if G2frame.dataDisplay:
1045        G2frame.dataDisplay.Destroy()
1046    G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.ImageMenu)
1047    if not G2frame.dataFrame.GetStatusBar():
1048        G2frame.dataFrame.CreateStatusBar()
1049    G2frame.dataFrame.Bind(wx.EVT_MENU, OnCalibrate, id=G2gd.wxID_IMCALIBRATE)
1050    G2frame.dataFrame.Bind(wx.EVT_MENU, OnRecalibrate, id=G2gd.wxID_IMRECALIBRATE)
1051    G2frame.dataFrame.Bind(wx.EVT_MENU, OnClearCalib, id=G2gd.wxID_IMCLEARCALIB)
1052    if 'chisq' not in data:
1053        G2frame.dataFrame.ImageEdit.Enable(id=G2gd.wxID_IMRECALIBRATE,enable=False)   
1054    G2frame.dataFrame.Bind(wx.EVT_MENU, OnIntegrate, id=G2gd.wxID_IMINTEGRATE)
1055    G2frame.dataFrame.Bind(wx.EVT_MENU, OnIntegrateAll, id=G2gd.wxID_INTEGRATEALL)
1056    G2frame.dataFrame.Bind(wx.EVT_MENU, OnCopyControls, id=G2gd.wxID_IMCOPYCONTROLS)
1057    G2frame.dataFrame.Bind(wx.EVT_MENU, OnSaveControls, id=G2gd.wxID_IMSAVECONTROLS)
1058    G2frame.dataFrame.Bind(wx.EVT_MENU, OnLoadControls, id=G2gd.wxID_IMLOADCONTROLS)
1059    if GSASIIpath.GetConfigValue('debug'):
1060        import autoint
1061        def OnDestroy(event):
1062            G2frame.autoIntFrame = None
1063        def OnAutoInt(event):
1064            reload(autoint)
1065            if G2frame.autoIntFrame: # ensure only one open at a time
1066                G2frame.autoIntFrame.Raise()
1067                return
1068            G2frame.autoIntFrame = autoint.AutoIntFrame(G2frame,PollTime=5.0)
1069            G2frame.autoIntFrame.Bind(wx.EVT_WINDOW_DESTROY,OnDestroy) # clean up name on window close
1070        G2frame.dataFrame.Bind(wx.EVT_MENU, OnAutoInt, id=G2gd.wxID_IMAUTOINTEG)
1071    G2frame.dataDisplay = wx.Panel(G2frame.dataFrame)
1072
1073    mainSizer = wx.BoxSizer(wx.VERTICAL)
1074    mainSizer.Add((5,10),0)   
1075    mainSizer.Add(ComboSizer(),0,wx.ALIGN_LEFT)
1076    mainSizer.Add((5,5),0)           
1077    mainSizer.Add(MaxSizer(),0,wx.ALIGN_LEFT|wx.EXPAND)
1078   
1079    mainSizer.Add((5,5),0)
1080    DataSizer = wx.FlexGridSizer(0,2,5,5)
1081    DataSizer.Add(CalibCoeffSizer(),0)
1082    DataSizer.Add(IntegrateSizer(),0)       
1083    mainSizer.Add(DataSizer,0)
1084    mainSizer.Add((5,5),0)           
1085    mainSizer.Add(BackSizer(),0)
1086    mainSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Calibration controls:'),0,WACV)
1087    mainSizer.Add((5,5),0)
1088    mainSizer.Add(CalibSizer(),0,WACV)
1089    mainSizer.Add((5,5),0)
1090    mainSizer.Add(GonioSizer(),0,WACV)   
1091       
1092    mainSizer.Layout()   
1093    G2frame.dataDisplay.SetSizer(mainSizer)
1094    fitSize = mainSizer.Fit(G2frame.dataFrame)
1095    G2frame.dataFrame.setSizePosLeft(fitSize)
1096    G2frame.dataDisplay.SetSize(fitSize)
1097   
1098################################################################################
1099##### Masks
1100################################################################################
1101def CleanupMasks(data):
1102    '''If a mask creation is not completed, an empty mask entry is created in the
1103    masks array. This cleans them out. It is called when the masks page is first loaded
1104    and before saving them or after reading them in. This should also probably be done
1105    before they are used for integration.
1106    '''
1107    for key in ['Points','Rings','Arcs','Polygons']:
1108        data[key] = data.get(key,[])
1109        l1 = len(data[key])
1110        data[key] = [i for i in data[key] if i]
1111        l2 = len(data[key])
1112        if GSASIIpath.GetConfigValue('debug') and l1 != l2:
1113            print 'Mask Cleanup:',key,'was',l1,'entries','now',l2
1114   
1115def UpdateMasks(G2frame,data):
1116    '''Shows and handles the controls on the "Masks" data tree entry
1117    '''
1118   
1119    def OnTextMsg(event):
1120        Obj = event.GetEventObject()
1121        Obj.SetToolTipString('Drag this mask on 2D Powder Image with mouse to change ')
1122
1123    def Replot(*args,**kwargs):
1124        G2plt.PlotExposedImage(G2frame,newPlot=True)       
1125
1126    def onDeleteMask(event):
1127        Obj = event.GetEventObject()
1128        typ = Obj.locationcode.split('+')[1]
1129        num = int(Obj.locationcode.split('+')[2])
1130        del(data[typ][num])
1131        wx.CallAfter(UpdateMasks,G2frame,data)
1132        G2plt.PlotExposedImage(G2frame,event=event)
1133
1134    def onDeleteFrame(event):
1135        data['Frames'] = []
1136        wx.CallAfter(UpdateMasks,G2frame,data)
1137        G2plt.PlotExposedImage(G2frame,event=event)
1138
1139    def OnCopyMask(event):
1140        TextList = [[False,'All IMG',0]]
1141        Names = []
1142        if G2frame.PatternTree.GetCount():
1143            id, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root)
1144            while id:
1145                name = G2frame.PatternTree.GetItemText(id)
1146                Names.append(name)
1147                if 'IMG' in name:
1148                    if id == G2frame.Image:
1149                        Source = name
1150                        Mask = copy.deepcopy(G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,id, 'Masks')))
1151                        Thresh = Mask.pop('Thresholds')  #remove Thresholds from source mask & save it for later
1152                    else:
1153                        TextList.append([False,name,id])
1154                id, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie)
1155            if len(TextList) == 1:
1156                G2frame.ErrorDialog('Nothing to copy mask to','There must be more than one "IMG" pattern')
1157                return
1158            dlg = G2frame.CopyDialog(G2frame,'Copy mask information','Copy mask from '+Source+' to:',TextList)
1159            try:
1160                if dlg.ShowModal() == wx.ID_OK:
1161                    result = dlg.GetData()
1162                    if result[0][0]:
1163                        result = TextList[1:]
1164                        for item in result: item[0] = True
1165                    for i,item in enumerate(result):
1166                        ifcopy,name,id = item
1167                        if ifcopy:
1168                            mask = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,id, 'Masks'))
1169#                            Mask['Thresholds'][0] = mask['Thresholds'][0]
1170#                            Mask['Thresholds'][1][1] = min(mask['Thresholds'][1][1],Mask['Thresholds'][1][1])
1171                            mask.update(Mask)
1172                            mask['Thresholds'][1][0] = Thresh[1][0]  #copy only lower threshold                             
1173                            G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,id, 'Masks'),copy.deepcopy(mask))
1174            finally:
1175                dlg.Destroy()
1176               
1177    def OnSaveMask(event):
1178        CleanupMasks(data)
1179        dlg = wx.FileDialog(G2frame, 'Choose image mask file', '.', '', 
1180            'image mask files (*.immask)|*.immask',wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT|wx.CHANGE_DIR)
1181        try:
1182            if dlg.ShowModal() == wx.ID_OK:
1183                filename = dlg.GetPath()
1184                File = open(filename,'w')
1185                save = {}
1186                keys = ['Points','Rings','Arcs','Polygons','Frames','Thresholds']
1187                for key in keys:
1188                    File.write(key+':'+str(data[key])+'\n')
1189                File.close()
1190        finally:
1191            dlg.Destroy()
1192       
1193    def OnLoadMask(event):
1194        if event.Id == G2gd.wxID_MASKLOADNOT:
1195            ignoreThreshold = True
1196        else:
1197            ignoreThreshold = False
1198        dlg = wx.FileDialog(G2frame, 'Choose image mask file', '.', '', 
1199            'image mask files (*.immask)|*.immask',wx.OPEN|wx.CHANGE_DIR)
1200        try:
1201            if dlg.ShowModal() == wx.ID_OK:
1202                filename = dlg.GetPath()
1203                File = open(filename,'r')
1204                save = {}
1205                oldThreshold = data['Thresholds'][0]
1206                S = File.readline()
1207                while S:
1208                    if S[0] == '#':
1209                        S = File.readline()
1210                        continue
1211                    [key,val] = S[:-1].split(':')
1212                    if key in ['Points','Rings','Arcs','Polygons','Frames','Thresholds']:
1213                        if ignoreThreshold and key == 'Thresholds':
1214                            S = File.readline() 
1215                            continue
1216                        save[key] = eval(val)
1217                        if key == 'Thresholds':
1218                            save[key][0] = oldThreshold
1219                            save[key][1][1] = min(oldThreshold[1],save[key][1][1])
1220                    S = File.readline()
1221                File.close()
1222                data.update(save)
1223                CleanupMasks(data)
1224                wx.CallAfter(UpdateMasks,G2frame,data)
1225                G2plt.PlotExposedImage(G2frame,event=event)               
1226        finally:
1227            dlg.Destroy()
1228           
1229    def OnNewSpotMask(event):
1230        'Start a new spot mask'
1231        G2frame.MaskKey = 's'
1232        G2plt.OnStartMask(G2frame)
1233       
1234    def OnNewArcMask(event):
1235        'Start a new arc mask'
1236        G2frame.MaskKey = 'a'
1237        G2plt.OnStartMask(G2frame)
1238       
1239    def OnNewRingMask(event):
1240        'Start a new ring mask'
1241        G2frame.MaskKey = 'r'
1242        G2plt.OnStartMask(G2frame)
1243       
1244    def OnNewPolyMask(event):
1245        'Start a new polygon mask'
1246        G2frame.MaskKey = 'p'
1247        G2plt.OnStartMask(G2frame)
1248       
1249    def OnNewFrameMask(event):
1250        'Start a new Frame mask'
1251        G2frame.MaskKey = 'f'
1252        G2plt.OnStartMask(G2frame)
1253
1254    startScroll = None
1255    if G2frame.dataDisplay:
1256        startScroll = G2frame.dataDisplay.GetScrollPos(wx.VERTICAL) # save scroll position
1257        G2frame.dataDisplay.Destroy()
1258    else:
1259        CleanupMasks(data) # posting page for 1st time; clean out anything unfinished
1260    G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.MaskMenu)
1261    G2frame.dataFrame.Bind(wx.EVT_MENU, OnCopyMask, id=G2gd.wxID_MASKCOPY)
1262    G2frame.dataFrame.Bind(wx.EVT_MENU, OnLoadMask, id=G2gd.wxID_MASKLOAD)
1263    G2frame.dataFrame.Bind(wx.EVT_MENU, OnLoadMask, id=G2gd.wxID_MASKLOADNOT)
1264    G2frame.dataFrame.Bind(wx.EVT_MENU, OnSaveMask, id=G2gd.wxID_MASKSAVE)
1265    G2frame.dataFrame.Bind(wx.EVT_MENU, OnNewSpotMask, id=G2gd.wxID_NEWMASKSPOT)
1266    G2frame.dataFrame.Bind(wx.EVT_MENU, OnNewArcMask, id=G2gd.wxID_NEWMASKARC)
1267    G2frame.dataFrame.Bind(wx.EVT_MENU, OnNewRingMask, id=G2gd.wxID_NEWMASKRING)
1268    G2frame.dataFrame.Bind(wx.EVT_MENU, OnNewPolyMask, id=G2gd.wxID_NEWMASKPOLY)
1269    G2frame.dataFrame.Bind(wx.EVT_MENU, OnNewFrameMask, id=G2gd.wxID_NEWMASKFRAME)
1270    if not G2frame.dataFrame.GetStatusBar():
1271        Status = G2frame.dataFrame.CreateStatusBar()
1272    if G2frame.MaskKey == 'f':
1273        G2frame.dataFrame.GetStatusBar().SetStatusText('Frame mask active - LB pick next point, RB close polygon')
1274    elif G2frame.MaskKey == 'p':
1275        G2frame.dataFrame.GetStatusBar().SetStatusText('Polygon mask active - LB pick next point, RB close polygon')
1276    elif G2frame.MaskKey == 's':
1277        G2frame.dataFrame.GetStatusBar().SetStatusText('Spot mask active - LB pick spot location')
1278    elif G2frame.MaskKey == 'a':
1279        G2frame.dataFrame.GetStatusBar().SetStatusText('Arc mask active - LB pick arc location')
1280    elif G2frame.MaskKey == 'r':
1281        G2frame.dataFrame.GetStatusBar().SetStatusText('Ring mask active - LB pick ring location')
1282    else:
1283        G2frame.dataFrame.GetStatusBar().SetStatusText("To add mask: press a,r,s,p or f on 2D image for arc/ring/spot/polygon/frame")
1284    G2frame.dataDisplay = wxscroll.ScrolledPanel(G2frame.dataFrame)
1285    mainSizer = wx.BoxSizer(wx.VERTICAL)
1286    mainSizer.Add((5,10),0)
1287
1288    thresh = data['Thresholds']         #min/max intensity range
1289    Spots = data['Points']               #x,y,radius in mm
1290    Rings = data['Rings']               #radius, thickness
1291    Polygons = data['Polygons']         #3+ x,y pairs
1292    if 'Frames' not in data:
1293        data['Frames'] = []
1294    frame = data['Frames']             #3+ x,y pairs
1295    Arcs = data['Arcs']                 #radius, start/end azimuth, thickness
1296   
1297    littleSizer = wx.FlexGridSizer(0,3,0,5)
1298    littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Lower/Upper limits '),0,WACV)
1299    Text = wx.TextCtrl(G2frame.dataDisplay,value=str(thresh[0][0]),style=wx.TE_READONLY)
1300    littleSizer.Add(Text,0,WACV)
1301    Text.SetBackgroundColour(VERY_LIGHT_GREY)
1302    Text = wx.TextCtrl(G2frame.dataDisplay,value=str(thresh[0][1]),style=wx.TE_READONLY)
1303    littleSizer.Add(Text,0,WACV)
1304    Text.SetBackgroundColour(VERY_LIGHT_GREY)
1305    littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Lower/Upper thresholds '),0,WACV)
1306    lowerThreshold = G2G.ValidatedTxtCtrl(G2frame.dataDisplay,loc=thresh[1],key=0,
1307                                           min=thresh[0][0],OnLeave=Replot,typeHint=int)
1308    littleSizer.Add(lowerThreshold,0,WACV)
1309    upperThreshold = G2G.ValidatedTxtCtrl(G2frame.dataDisplay,loc=thresh[1],key=1,
1310                                           max=thresh[0][1],OnLeave=Replot,typeHint=int)
1311    littleSizer.Add(upperThreshold,0,WACV)
1312    mainSizer.Add(littleSizer,0,)
1313    if Spots:
1314        lbl = wx.StaticText(parent=G2frame.dataDisplay,label=' Spot masks')
1315        lbl.SetBackgroundColour(wx.Colour(200,200,210))
1316        mainSizer.Add(lbl,0,wx.EXPAND|wx.ALIGN_CENTER,0)
1317        littleSizer = wx.FlexGridSizer(0,3,0,5)
1318        littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' position, mm'),0,WACV)
1319        littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' diameter, mm'),0,WACV)
1320        littleSizer.Add((5,0),0)
1321        for i in range(len(Spots)):
1322            if Spots[i]:
1323                x,y,d = Spots[i]
1324                spotText = wx.TextCtrl(parent=G2frame.dataDisplay,value=("%.2f,%.2f" % (x,y)),
1325                    style=wx.TE_READONLY)
1326                spotText.SetBackgroundColour(VERY_LIGHT_GREY)
1327                littleSizer.Add(spotText,0,WACV)
1328                spotText.Bind(wx.EVT_ENTER_WINDOW,OnTextMsg)
1329                spotDiameter = G2G.ValidatedTxtCtrl(G2frame.dataDisplay,loc=Spots[i],key=2,
1330                                           max=100.,OnLeave=Replot,nDig=[8,2])
1331                littleSizer.Add(spotDiameter,0,WACV)
1332                spotDelete = G2G.G2LoggedButton(G2frame.dataDisplay,label='delete?',
1333                                            locationcode='Delete+Points+'+str(i),
1334                                            handler=onDeleteMask)
1335                littleSizer.Add(spotDelete,0,WACV)
1336        mainSizer.Add(littleSizer,0,)
1337    if Rings:
1338        lbl = wx.StaticText(parent=G2frame.dataDisplay,label=' Ring masks')
1339        lbl.SetBackgroundColour(wx.Colour(200,200,210))
1340        mainSizer.Add(lbl,0,wx.EXPAND|wx.ALIGN_CENTER,0)
1341        littleSizer = wx.FlexGridSizer(0,3,0,5)
1342        littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' 2-theta,deg'),0,WACV)
1343        littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' thickness, deg'),0,WACV)
1344        littleSizer.Add((5,0),0)
1345        for i in range(len(Rings)):
1346            if Rings[i]:
1347                ringText = wx.TextCtrl(parent=G2frame.dataDisplay,value=("%.3f" % (Rings[i][0])),
1348                    style=wx.TE_READONLY)
1349                ringText.SetBackgroundColour(VERY_LIGHT_GREY)
1350                ringText.Bind(wx.EVT_ENTER_WINDOW,OnTextMsg)
1351                littleSizer.Add(ringText,0,WACV)
1352                ringThick = G2G.ValidatedTxtCtrl(G2frame.dataDisplay,loc=Rings[i],key=1,
1353                                           min=0.001,max=1.,OnLeave=Replot,nDig=[8,3])
1354                littleSizer.Add(ringThick,0,WACV)
1355                ringDelete = G2G.G2LoggedButton(G2frame.dataDisplay,label='delete?',
1356                                            locationcode='Delete+Rings+'+str(i),
1357                                            handler=onDeleteMask)
1358                littleSizer.Add(ringDelete,0,WACV)
1359        mainSizer.Add(littleSizer,0,)
1360    if Arcs:
1361        lbl = wx.StaticText(parent=G2frame.dataDisplay,label=' Arc masks')
1362        lbl.SetBackgroundColour(wx.Colour(200,200,210))
1363        mainSizer.Add(lbl,0,wx.EXPAND|wx.ALIGN_CENTER,0)
1364        littleSizer = wx.FlexGridSizer(0,4,0,5)
1365        littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' 2-theta,deg'),0,WACV)
1366        littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' azimuth, deg'),0,WACV)
1367        littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' thickness, deg'),0,WACV)
1368        littleSizer.Add((5,0),0)
1369        for i in range(len(Arcs)):
1370            if Arcs[i]:
1371                tth,azimuth,thick = Arcs[i]
1372                arcText = wx.TextCtrl(parent=G2frame.dataDisplay,value=("%.3f" % (tth)),
1373                    style=wx.TE_READONLY)
1374                arcText.SetBackgroundColour(VERY_LIGHT_GREY)
1375                arcText.Bind(wx.EVT_ENTER_WINDOW,OnTextMsg)
1376                littleSizer.Add(arcText,0,WACV)
1377                azmText = wx.TextCtrl(parent=G2frame.dataDisplay,value=("%d,%d" % (azimuth[0],azimuth[1])),
1378                    style=wx.TE_READONLY)
1379                azmText.SetBackgroundColour(VERY_LIGHT_GREY)
1380                azmText.Bind(wx.EVT_ENTER_WINDOW,OnTextMsg)
1381                littleSizer.Add(azmText,0,WACV)
1382                arcThick = G2G.ValidatedTxtCtrl(G2frame.dataDisplay,loc=Arcs[i],key=2,
1383                                           min=0.001,max=20.,OnLeave=Replot,nDig=[8,3])
1384                littleSizer.Add(arcThick,0,WACV)
1385                arcDelete = G2G.G2LoggedButton(G2frame.dataDisplay,label='delete?',
1386                                            locationcode='Delete+Arcs+'+str(i),
1387                                            handler=onDeleteMask)
1388                littleSizer.Add(arcDelete,0,WACV)
1389        mainSizer.Add(littleSizer,0,)
1390    if Polygons:
1391        lbl = wx.StaticText(parent=G2frame.dataDisplay,
1392            label=' Polygon masks (on plot RB vertex drag to move,\nLB vertex drag to insert)')
1393        lbl.SetBackgroundColour(wx.Colour(200,200,210))
1394        mainSizer.Add(lbl,0,wx.EXPAND|wx.ALIGN_CENTER,0)
1395        littleSizer = wx.FlexGridSizer(0,2,0,5)
1396        for i in range(len(Polygons)):
1397            if Polygons[i]:
1398                polyList = []
1399                for x,y in Polygons[i]:
1400                    polyList.append("%.2f, %.2f"%(x,y))
1401                polyText = wx.ComboBox(G2frame.dataDisplay,value=polyList[0],choices=polyList,style=wx.CB_READONLY)
1402                littleSizer.Add(polyText,0,WACV)
1403                polyDelete = G2G.G2LoggedButton(G2frame.dataDisplay,label='delete?',
1404                                            locationcode='Delete+Polygons+'+str(i),
1405                                            handler=onDeleteMask)
1406                littleSizer.Add(polyDelete,0,WACV)
1407        mainSizer.Add(littleSizer,0,)
1408    if frame:
1409        lbl = wx.StaticText(parent=G2frame.dataDisplay,
1410            label=' Frame mask (on plot RB vertex drag to move,LB vertex drag to insert)')
1411        lbl.SetBackgroundColour(wx.Colour(200,200,210))
1412        mainSizer.Add(lbl,0,wx.EXPAND|wx.ALIGN_CENTER,0)
1413        littleSizer = wx.FlexGridSizer(0,2,0,5)
1414        frameList = []
1415        for x,y in frame:
1416            frameList.append("%.2f, %.2f"%(x,y))
1417        frameText = wx.ComboBox(G2frame.dataDisplay,value=frameList[0],choices=frameList,style=wx.CB_READONLY)
1418        littleSizer.Add(frameText,0,WACV)
1419        frameDelete = G2G.G2LoggedButton(G2frame.dataDisplay,label='delete?',
1420                                            locationcode='Delete+Frame',
1421                                            handler=onDeleteFrame)
1422        littleSizer.Add(frameDelete,0,WACV)
1423        mainSizer.Add(littleSizer,0,)
1424    mainSizer.Layout()   
1425    G2frame.dataDisplay.SetSizer(mainSizer)
1426    G2frame.dataDisplay.SetSize(mainSizer.Fit(G2frame.dataFrame))
1427    G2frame.dataDisplay.SetupScrolling()
1428    Size = mainSizer.Fit(G2frame.dataFrame)
1429    Size[0] += 50 # room for scrollbar & status msg
1430    Size[1] = min(Size[1],500)
1431    G2frame.dataDisplay.SetSize(Size)
1432    G2frame.dataFrame.setSizePosLeft(Size)   
1433    wx.Yield()
1434    if startScroll: # reset scroll to saved position
1435        G2frame.dataDisplay.Scroll(0,startScroll) # set to saved scroll position
1436        wx.Yield()
1437
1438################################################################################
1439##### Stress/Strain
1440################################################################################
1441
1442def UpdateStressStrain(G2frame,data):
1443    '''Shows and handles the controls on the "Stress/Strain"
1444    data tree entry
1445    '''
1446   
1447    def OnAppendDzero(event):
1448        data['d-zero'].append({'Dset':1.0,'Dcalc':0.0,'pixLimit':10,'cutoff':1.0,
1449            'ImxyObs':[[],[]],'ImtaObs':[[],[]],'ImtaCalc':[[],[]],'Emat':[1.0,1.0,1.0]})
1450        UpdateStressStrain(G2frame,data)
1451       
1452    def OnUpdateDzero(event):
1453        for item in data['d-zero']:
1454            if item['Dcalc']:   #skip unrefined ones
1455                item['Dset'] = item['Dcalc']
1456        UpdateStressStrain(G2frame,data)
1457           
1458    def OnCopyStrSta(event):
1459        TextList = [[False,'All IMG',0,0]]
1460        Names = []
1461        if G2frame.PatternTree.GetCount():
1462            id, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root)
1463            while id:
1464                name = G2frame.PatternTree.GetItemText(id)
1465                Names.append(name)
1466                if 'IMG' in name:
1467                    Data = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,id, 'Stress/Strain'))
1468                    if id == G2frame.Image:
1469                        Source = name
1470                    else:
1471                        TextList.append([False,name,id,Data.get('Sample load',0.0)])
1472                id, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie)
1473            if len(TextList) == 1:
1474                G2frame.ErrorDialog('Nothing to copy controls to','There must be more than one "IMG" pattern')
1475                return
1476            dlg = G2frame.CopyDialog(G2frame,'Copy stress/strain controls','Copy controls from '+Source+' to:',TextList)
1477            try:
1478                if dlg.ShowModal() == wx.ID_OK:
1479                    result = dlg.GetData()
1480                    if result[0][0]:
1481                        result = TextList[1:]
1482                        for item in result: item[0] = True
1483                    for i,item in enumerate(result):
1484                        ifcopy,name,id,load = item
1485                        if ifcopy:
1486                            Data = copy.deepcopy(data)
1487                            Data['Sample load'] = load
1488                            G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,id, 'Stress/Strain'),Data)
1489            finally:
1490                dlg.Destroy()
1491
1492    def OnLoadStrSta(event):
1493        dlg = wx.FileDialog(G2frame, 'Choose stress/strain file', '.', '', 
1494            'image control files (*.strsta)|*.strsta',wx.OPEN|wx.CHANGE_DIR)
1495        try:
1496            if dlg.ShowModal() == wx.ID_OK:
1497                filename = dlg.GetPath()
1498                File = open(filename,'r')
1499                S = File.read()
1500                data = eval(S)
1501                Controls = G2frame.PatternTree.GetItemPyData(
1502                    G2gd.GetPatternTreeItemId(G2frame,G2frame.Image, 'Image Controls'))
1503                G2img.FitStrSta(G2frame.ImageZ,data,Controls)
1504                UpdateStressStrain(G2frame,data)
1505                G2plt.PlotExposedImage(G2frame,event=event)
1506                G2plt.PlotStrain(G2frame,data,newPlot=True)
1507                File.close()
1508        finally:
1509            dlg.Destroy()
1510
1511    def OnSaveStrSta(event):
1512        dlg = wx.FileDialog(G2frame, 'Choose stress/strain file', '.', '', 
1513            'image control files (*.strsta)|*.strsta',wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT|wx.CHANGE_DIR)
1514        try:
1515            if dlg.ShowModal() == wx.ID_OK:
1516                filename = dlg.GetPath()
1517                File = open(filename,'w')
1518                save = {}
1519                keys = ['Type','Sample phi','Sample z','Sample load']
1520                keys2 = ['Dset','Dcalc','pixLimit','cutoff','Emat']
1521                File.write('{\n\t')
1522                for key in keys:
1523                    if key in 'Type':
1524                        File.write("'"+key+"':'"+data[key]+"',")
1525                    else:
1526                        File.write("'"+key+"':"+str(data[key])+',')
1527                File.write('\n\t'+"'d-zero':[\n")
1528                for data2 in data['d-zero']:
1529                    File.write('\t\t{')
1530                    for key in keys2:
1531                        File.write("'"+key+"':"+str(data2[key])+',')
1532                    File.write("'ImxyObs':[[],[]],'ImtaObs':[[],[]],'ImtaCalc':[[],[]]},\n")
1533                File.write('\t]\n}')
1534                File.close()
1535        finally:
1536            dlg.Destroy()
1537           
1538    def OnStrStaSample(event):
1539        filename = ''
1540        dlg = wx.FileDialog(G2frame, 'Choose multihistogram metadata text file', '.', '', 
1541            'metadata file (*.*)|*.*',wx.OPEN|wx.CHANGE_DIR)
1542        try:
1543            if dlg.ShowModal() == wx.ID_OK:
1544                filename = dlg.GetPath()
1545                File = open(filename,'r')
1546                S = File.readline()
1547                newItems = []
1548                itemNames = []
1549                Comments = []
1550                while S:
1551                    if S[0] == '#':
1552                        Comments.append(S)
1553                        S = File.readline()
1554                        continue
1555                    S = S.replace(',',' ').replace('\t',' ')
1556                    Stuff = S[:-1].split()
1557                    itemNames.append(Stuff[0])
1558                    newItems.append(Stuff[1:])
1559                    S = File.readline()               
1560                File.close()
1561        finally:
1562            dlg.Destroy()
1563        if not filename:
1564            G2frame.ErrorDialog('Nothing to do','No file selected')
1565            return
1566        dataDict = dict(zip(itemNames,newItems))
1567        ifany = False
1568        Names = [' ','Sample phi','Sample z','Sample load']
1569        dlg = G2G.G2ColumnIDDialog( G2frame,' Choose multihistogram metadata columns:',
1570            'Select columns',Comments,Names,np.array(newItems).T)
1571        try:
1572            if dlg.ShowModal() == wx.ID_OK:
1573                colNames,newData = dlg.GetSelection()
1574                dataDict = dict(zip(itemNames,newData.T))
1575                for item in colNames:
1576                    if item != ' ':
1577                        ifany = True
1578        finally:
1579            dlg.Destroy()
1580        if not ifany:
1581            G2frame.ErrorDialog('Nothing to do','No columns identified')
1582            return
1583        histList = []
1584        item, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root)       
1585        while item:
1586            name = G2frame.PatternTree.GetItemText(item)
1587            if name.startswith('IMG'):
1588                histList.append(name)
1589            item, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie)
1590        colIds = {}
1591        for i,name in enumerate(colNames):
1592            if name != ' ':
1593                colIds[name] = i
1594        for hist in histList:
1595            name = hist.split()[1]  #this is file name
1596            if name in dataDict:
1597                newItems = {}
1598                for item in colIds:
1599                    newItems[item] = float(dataDict[name][colIds[item]])
1600                Id = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,hist)
1601                stsrData = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,Id,'Stress/Strain'))
1602                stsrData.update(newItems)       
1603        UpdateStressStrain(G2frame,data)       
1604   
1605    def OnFitStrSta(event):
1606        Controls = G2frame.PatternTree.GetItemPyData(
1607            G2gd.GetPatternTreeItemId(G2frame,G2frame.Image, 'Image Controls'))
1608        G2img.FitStrSta(G2frame.ImageZ,data,Controls)
1609        print 'Strain fitting finished'
1610        UpdateStressStrain(G2frame,data)
1611        G2plt.PlotExposedImage(G2frame,event=event)
1612        G2plt.PlotStrain(G2frame,data,newPlot=True)
1613       
1614    def OnFitAllStrSta(event):
1615        TextList = [[False,'All IMG',0]]
1616        Names = []
1617        if G2frame.PatternTree.GetCount():
1618            choices = G2gd.GetPatternTreeDataNames(G2frame,['IMG ',])
1619            if len(choices) == 1:
1620                G2frame.ErrorDialog('Nothing to fit','There must some "IMG" patterns')
1621                return
1622            sel = []
1623            dlg = G2G.G2MultiChoiceDialog(G2frame,'Stress/Strain fitting','Select images to fit:',choices)
1624            dlg.SetSelections(sel)
1625            names = []
1626            if dlg.ShowModal() == wx.ID_OK:
1627                for sel in dlg.GetSelections():
1628                    names.append(choices[sel])
1629            dlg.Destroy()
1630            SeqResult = {}
1631            dlg = wx.ProgressDialog('Sequential IMG Strain fit','Data set name = '+names[0],len(names), 
1632                style = wx.PD_ELAPSED_TIME|wx.PD_AUTO_HIDE|wx.PD_REMAINING_TIME|wx.PD_CAN_ABORT)         
1633            wx.BeginBusyCursor()
1634            goodnames = []
1635            try:
1636                for i,name in enumerate(names):
1637                    print ' Sequential strain fit for ',name
1638                    GoOn = dlg.Update(i,newmsg='Data set name = '+name)[0]
1639                    if not GoOn:
1640                        break
1641                    Id =  G2gd.GetPatternTreeItemId(G2frame,G2frame.root,name)
1642                    Controls = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,Id, 'Image Controls'))
1643                    StaCtrls = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,Id, 'Stress/Strain'))
1644                    if not len(StaCtrls['d-zero']):
1645                        continue
1646                    goodnames.append(name)
1647                    id = G2gd.GetPatternTreeItemId(G2frame, G2frame.root, name)
1648                    Npix,imagefile = G2frame.PatternTree.GetItemPyData(Id)
1649                    image = G2IO.GetImageData(G2frame,imagefile,True)
1650                    dark = Controls['dark image']
1651                    if dark[0]:
1652                        darkfile = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame, 
1653                            G2frame.root,dark[0]))[1]
1654                        darkImg = G2IO.GetImageData(G2frame,darkfile,imageOnly=True)
1655                        image += dark[1]*darkImg
1656                    G2img.FitStrSta(image,StaCtrls,Controls)
1657                    G2plt.PlotStrain(G2frame,StaCtrls,newPlot=True)
1658                    parmDict = {'Sample load':StaCtrls['Sample load'],}
1659                    varyNames = ['e11','e12','e22']
1660                    sig = []
1661                    varyList = []
1662                    variables = []
1663                    for i,item in enumerate(StaCtrls['d-zero']):
1664                        variables += item['Emat']
1665                        sig += item['Esig']
1666                        varylist = ['%d%s%s'%(i,';',Name) for Name in varyNames]
1667                        varyList += varylist
1668                        parmDict.update(dict(zip(varylist,item['Emat'])))
1669                        parmDict['%d:Dcalc'%(i)] = item['Dcalc']
1670                    SeqResult[name] = {'variables':variables,'varyList':varyList,'sig':sig,'Rvals':[],
1671                        'covMatrix':np.eye(len(variables)),'title':name,'parmDict':parmDict}
1672                else:
1673                    SeqResult['histNames'] = goodnames
1674                    dlg.Destroy()
1675                    print ' ***** Sequential strain refinement successful *****'
1676            finally:
1677                wx.EndBusyCursor()   
1678            Id =  G2gd.GetPatternTreeItemId(G2frame,G2frame.root,'Sequential results')
1679            if Id:
1680                G2frame.PatternTree.SetItemPyData(Id,SeqResult)
1681            else:
1682                Id = G2frame.PatternTree.AppendItem(parent=G2frame.root,text='Sequential results')
1683                G2frame.PatternTree.SetItemPyData(Id,SeqResult)
1684            G2frame.PatternTree.SelectItem(Id)
1685            print 'All images fitted'
1686       
1687    def SamSizer():
1688       
1689        def OnStrainType(event):
1690            data['Type'] = strType.GetValue()
1691       
1692        def OnSamPhi(event):
1693            try:
1694                value = float(samPhi.GetValue())
1695            except ValueError:
1696                value = data['Sample phi']
1697            data['Sample phi'] = value
1698            samPhi.SetValue("%.3f" % (data['Sample phi']))
1699               
1700        def OnSamZ(event):
1701            try:
1702                value = float(samZ.GetValue())
1703            except ValueError:
1704                value = data['Sample z']
1705            data['Sample z'] = value
1706            samZ.SetValue("%.3f" % (data['Sample z']))
1707               
1708        def OnSamLoad(event):
1709            try:
1710                value = float(samLoad.GetValue())
1711            except ValueError:
1712                value = data['Sample load']
1713            data['Sample load'] = value
1714            samLoad.SetValue("%.3f" % (data['Sample load']))
1715               
1716        samSizer = wx.BoxSizer(wx.HORIZONTAL)
1717        samSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,label=' Strain type: '),0,WACV)
1718        strType = wx.ComboBox(G2frame.dataDisplay,value=data['Type'],choices=['True','Conventional'],
1719            style=wx.CB_READONLY|wx.CB_DROPDOWN)
1720        strType.SetValue(data['Type'])
1721        strType.Bind(wx.EVT_COMBOBOX, OnStrainType)
1722        samSizer.Add(strType,0,WACV)
1723       
1724        samSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,label=' Sample phi: '),0,WACV)
1725        samPhi = wx.TextCtrl(G2frame.dataDisplay,-1,value=("%.3f" % (data['Sample phi'])),
1726            style=wx.TE_PROCESS_ENTER)
1727        samSizer.Add(samPhi,0,WACV)
1728        samPhi.Bind(wx.EVT_TEXT_ENTER,OnSamPhi)
1729        samPhi.Bind(wx.EVT_KILL_FOCUS,OnSamPhi)
1730        samSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,label=' Sample delta-z(mm): '),0,WACV)
1731        samZ = wx.TextCtrl(G2frame.dataDisplay,-1,value=("%.3f" % (data['Sample z'])),
1732            style=wx.TE_PROCESS_ENTER)
1733        samSizer.Add(samZ,0,WACV)
1734        samZ.Bind(wx.EVT_TEXT_ENTER,OnSamZ)
1735        samZ.Bind(wx.EVT_KILL_FOCUS,OnSamZ)
1736        samSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,label=' Sample load(MPa): '),0,WACV)
1737        samLoad = G2G.ValidatedTxtCtrl(G2frame.dataDisplay,data,'Sample load',
1738                nDig=[8,3],typeHint=float,)
1739        samSizer.Add(samLoad,0,WACV)
1740
1741        return samSizer
1742       
1743    def DzeroSizer():
1744   
1745        def OnDzero(event):
1746            Obj = event.GetEventObject()
1747            try:
1748                value = min(20.0,max(0.25,float(Obj.GetValue())))
1749            except ValueError:
1750                value = 1.0
1751            Obj.SetValue("%.5f"%(value))
1752            data['d-zero'][Indx[Obj.GetId()]]['Dset'] = value
1753            data['d-zero'] = G2mth.sortArray(data['d-zero'],'Dset',reverse=True)
1754            Ring,R = G2img.MakeStrStaRing(data['d-zero'][Indx[Obj.GetId()]],G2frame.ImageZ,Controls)
1755            if len(Ring):
1756                data['d-zero'][Indx[Obj.GetId()]].update(R)
1757            else:
1758                G2frame.ErrorDialog('Strain peak selection','WARNING - No points found for this ring selection')
1759               
1760            UpdateStressStrain(G2frame,data)
1761            G2plt.PlotExposedImage(G2frame,event=event,newPlot=False)
1762            G2plt.PlotStrain(G2frame,data,newPlot=True)
1763           
1764        def OnDeleteDzero(event):
1765            Obj = event.GetEventObject()
1766            del(data['d-zero'][delIndx.index(Obj)])
1767            UpdateStressStrain(G2frame,data)
1768            G2plt.PlotExposedImage(G2frame,event=event,newPlot=True)
1769            G2plt.PlotStrain(G2frame,data,newPlot=True)
1770       
1771        def OnCutOff(event):
1772            Obj = event.GetEventObject()
1773            try:
1774                value = min(10.0,max(0.5,float(Obj.GetValue())))
1775            except ValueError:
1776                value = 1.0
1777            Obj.SetValue("%.1f"%(value))
1778            data['d-zero'][Indx[Obj.GetId()]]['cutoff'] = value
1779            Ring,R = G2img.MakeStrStaRing(data['d-zero'][Indx[Obj.GetId()]],G2frame.ImageZ,Controls)
1780            G2plt.PlotExposedImage(G2frame,event=event)
1781            G2plt.PlotStrain(G2frame,data,newPlot=True)
1782       
1783        def OnPixLimit(event):
1784            Obj = event.GetEventObject()
1785            data['d-zero'][Indx[Obj.GetId()]]['pixLimit'] = int(Obj.GetValue())
1786            Ring,R = G2img.MakeStrStaRing(data['d-zero'][Indx[Obj.GetId()]],G2frame.ImageZ,Controls)
1787            G2plt.PlotExposedImage(G2frame,event=event)
1788            G2plt.PlotStrain(G2frame,data,newPlot=True)
1789           
1790        Indx = {}
1791        delIndx = []   
1792        dzeroSizer = wx.FlexGridSizer(0,8,5,5)
1793        for id,dzero in enumerate(data['d-zero']):
1794            dzeroSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,label=(' d-zero #%d: '%(id))),0,WACV)
1795            dZero = wx.TextCtrl(G2frame.dataDisplay,-1,value=('%.5f'%(dzero['Dset'])),
1796                style=wx.TE_PROCESS_ENTER)
1797            dzeroSizer.Add(dZero,0,WACV)
1798            dZero.Bind(wx.EVT_TEXT_ENTER,OnDzero)
1799            dZero.Bind(wx.EVT_KILL_FOCUS,OnDzero)
1800            Indx[dZero.GetId()] = id
1801            dzeroSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,label=(' d-zero ave: %.5f'%(dzero['Dcalc']))),0,WACV)
1802               
1803            dzeroSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Min ring I/Ib '),0,WACV)
1804            cutOff = wx.TextCtrl(parent=G2frame.dataDisplay,value=("%.1f" % (dzero['cutoff'])),
1805                style=wx.TE_PROCESS_ENTER)
1806            cutOff.Bind(wx.EVT_TEXT_ENTER,OnCutOff)
1807            cutOff.Bind(wx.EVT_KILL_FOCUS,OnCutOff)
1808            Indx[cutOff.GetId()] = id
1809            dzeroSizer.Add(cutOff,0,WACV)
1810       
1811            dzeroSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Pixel search range '),0,WACV)
1812            pixLimit = wx.ComboBox(parent=G2frame.dataDisplay,value=str(dzero['pixLimit']),choices=['1','2','5','10','15','20'],
1813                style=wx.CB_READONLY|wx.CB_DROPDOWN)
1814            pixLimit.Bind(wx.EVT_COMBOBOX, OnPixLimit)
1815            Indx[pixLimit.GetId()] = id
1816            dzeroSizer.Add(pixLimit,0,WACV)               
1817               
1818            dzeroDelete = wx.CheckBox(parent=G2frame.dataDisplay,label='delete?')
1819            dzeroDelete.Bind(wx.EVT_CHECKBOX,OnDeleteDzero)
1820            delIndx.append(dzeroDelete)
1821            dzeroSizer.Add(dzeroDelete,0,WACV)
1822           
1823            dzeroSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,label=(' Strain tensor:')),WACV)
1824            names = ['e11','e12','e22']
1825            for i in range(3):
1826                dzeroSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,label=names[i]),0,WACV)
1827                tensorElem = wx.TextCtrl(G2frame.dataDisplay,-1,value='%.2f'%(dzero['Emat'][i]),style=wx.TE_READONLY)
1828                tensorElem.SetBackgroundColour(VERY_LIGHT_GREY)
1829                dzeroSizer.Add(tensorElem,0,WACV)
1830            dzeroSizer.Add((5,5),0)             
1831        return dzeroSizer
1832       
1833# patches
1834    if 'Sample load' not in data:
1835        data['Sample load'] = 0.0
1836# end patches
1837   
1838    if G2frame.dataDisplay:
1839        G2frame.dataDisplay.Destroy()
1840    Controls = G2frame.PatternTree.GetItemPyData(
1841        G2gd.GetPatternTreeItemId(G2frame,G2frame.Image, 'Image Controls'))       
1842    G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.StrStaMenu)
1843    G2frame.dataFrame.Bind(wx.EVT_MENU, OnAppendDzero, id=G2gd.wxID_APPENDDZERO)
1844    G2frame.dataFrame.Bind(wx.EVT_MENU, OnUpdateDzero, id=G2gd.wxID_UPDATEDZERO)
1845    G2frame.dataFrame.Bind(wx.EVT_MENU, OnFitStrSta, id=G2gd.wxID_STRSTAFIT)
1846    G2frame.dataFrame.Bind(wx.EVT_MENU, OnFitAllStrSta, id=G2gd.wxID_STRSTAALLFIT)
1847    G2frame.dataFrame.Bind(wx.EVT_MENU, OnCopyStrSta, id=G2gd.wxID_STRSTACOPY)
1848    G2frame.dataFrame.Bind(wx.EVT_MENU, OnLoadStrSta, id=G2gd.wxID_STRSTALOAD)
1849    G2frame.dataFrame.Bind(wx.EVT_MENU, OnSaveStrSta, id=G2gd.wxID_STRSTASAVE)
1850    G2frame.dataFrame.Bind(wx.EVT_MENU, OnStrStaSample, id=G2gd.wxID_STRSTSAMPLE)       
1851    if not G2frame.dataFrame.GetStatusBar():
1852        Status = G2frame.dataFrame.CreateStatusBar()
1853    if G2frame.StrainKey == 'a':    #probably doesn't happen
1854        G2frame.dataFrame.GetStatusBar().SetStatusText('Add strain ring active - LB pick d-zero value')
1855    else:
1856        G2frame.dataFrame.GetStatusBar().SetStatusText("To add strain data: On 2D Powder Image, key a:add ring")
1857       
1858    G2frame.dataDisplay = wxscroll.ScrolledPanel(G2frame.dataFrame)
1859    mainSizer = wx.BoxSizer(wx.VERTICAL)
1860    mainSizer.Add((5,10),0)
1861    mainSizer.Add(SamSizer())
1862    mainSizer.Add((5,10),0)
1863    mainSizer.Add(DzeroSizer())
1864   
1865    mainSizer.Layout()   
1866    G2frame.dataDisplay.SetSizer(mainSizer)
1867    G2frame.dataDisplay.SetAutoLayout(1)
1868    G2frame.dataDisplay.SetupScrolling()
1869    Size = mainSizer.Fit(G2frame.dataFrame)
1870    Size[0] += 25
1871    G2frame.dataDisplay.SetSize(Size)
1872    G2frame.dataFrame.setSizePosLeft(Size)   
Note: See TracBrowser for help on using the repository browser.