source: trunk/GSASIIimgGUI.py @ 2065

Last change on this file since 2065 was 2065, checked in by toby, 6 years ago

Allow reading of multiple images from single file

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Author Revision URL Id
File size: 87.9 KB
Line 
1# -*- coding: utf-8 -*-
2#GSASII - image data display routines
3########### SVN repository information ###################
4# $Date: 2015-11-22 23:56:33 +0000 (Sun, 22 Nov 2015) $
5# $Author: toby $
6# $Revision: 2065 $
7# $URL: trunk/GSASIIimgGUI.py $
8# $Id: GSASIIimgGUI.py 2065 2015-11-22 23:56:33Z 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: 2065 $")
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,imagetag = G2frame.PatternTree.GetImageLoc(Did)
146                darkImage = G2IO.GetImageData(G2frame,imagefile,True,ImageTag=imagetag)
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,imagetag = G2frame.PatternTree.GetImageLoc(Bid)
152                backImage = G2IO.GetImageData(G2frame,imagefile,True,ImageTag=imagetag)
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,imagetag = G2frame.PatternTree.GetImageLoc(BDid)
158                    BdarkImage = G2IO.GetImageData(G2frame,imagefile,True,ImageTag=imagetag)
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,imagetag = G2frame.PatternTree.GetImageLoc(id)
209                                image = G2IO.GetImageData(G2frame,imagefile,True,ImageTag=imagetag)
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,imagetag = G2frame.PatternTree.GetImageLoc(id)
216                                    backImage = G2IO.GetImageData(G2frame,imagefile,True,ImageTag=imagetag)*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.SetFlexibleDirection(wx.HORIZONTAL)
506        calibSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Calibration coefficients'),0,WACV)   
507        calibSizer.Add((5,0),0)
508        cent = data['center']
509        Names = ['det-X','det-Y','wave','dist','tilt','phi']
510        if 'PWDR' in data['type']:
511            Names.append('dep') 
512        Parms = {'dist':['Distance','%.3f',data['distance']],'det-X':['Beam center X','%.3f',data['center'][0]],
513            'det-Y':['Beam center Y','%.3f',data['center'][1]],'tilt':['Tilt angle','%.3f',data['tilt']],
514            'phi':['Tilt rotation','%.2f',data['rotation']],'dep':['Penetration','%.2f',data['DetDepth']],
515            'wave':['Wavelength','%.6f',data['wavelength']]}
516        Indx = {}
517        for name in Names:
518            calSel = wx.CheckBox(parent=G2frame.dataDisplay,label=Parms[name][0])
519            calibSizer.Add(calSel,0,WACV)
520            calSel.Bind(wx.EVT_CHECKBOX, OnCalRef)
521            calSel.SetValue(data['varyList'][name])
522            Indx[calSel] = name
523            calVal = wx.TextCtrl(G2frame.dataDisplay,value=(Parms[name][1]%(Parms[name][2])),style=wx.TE_PROCESS_ENTER)
524            calVal.Bind(wx.EVT_TEXT_ENTER,OnCalVal)
525            calVal.Bind(wx.EVT_KILL_FOCUS,OnCalVal)
526            Indx[calVal] = name
527            calibSizer.Add(calVal,0,WACV)
528        return calibSizer
529   
530    def IntegrateSizer():
531       
532        def OnNewBinType(event):
533            data['binType'] = binSel.GetValue()
534            wx.CallLater(100,UpdateImageControls,G2frame,data,masks)
535       
536        def OnIOtth(event):
537            Ltth = max(float(G2frame.InnerTth.GetValue()),0.001)
538            Utth = float(G2frame.OuterTth.GetValue())
539            if Ltth > Utth:
540                Ltth,Utth = Utth,Ltth
541            if 'Q' in data['binType']:
542                data['IOtth'] = [2.*asind(Ltth*wave/(4.*math.pi)),2.*asind(Utth*wave/(4.*math.pi))]
543            else:
544                data['IOtth'] = [Ltth,Utth]
545            G2frame.InnerTth.SetValue("%8.3f" % (Ltth))
546            G2frame.OuterTth.SetValue("%8.3f" % (Utth))
547            G2plt.PlotExposedImage(G2frame,event=event)
548       
549        def OnLRazim(event):
550            Lazm = int(G2frame.Lazim.GetValue())%360
551            Razm = int(G2frame.Razim.GetValue())%360
552            if Lazm > Razm:
553                Razm += 360
554            if data['fullIntegrate']:
555                Razm = Lazm+360
556            G2frame.Lazim.SetValue("%6d" % (Lazm))
557            G2frame.Razim.SetValue("%6d" % (Razm))
558            data['LRazimuth'] = [Lazm,Razm]
559            G2plt.PlotExposedImage(G2frame,event=event)
560       
561        def OnNumOutChans(event):
562            try:
563                numChans = int(outChan.GetValue())
564                if numChans < 10:
565                    raise ValueError
566                data['outChannels'] = numChans
567            except ValueError:
568                pass
569            outChan.SetValue(str(data['outChannels']))          #reset in case of error       
570       
571        def OnNumOutAzms(event):
572            try:
573                numAzms = int(outAzim.GetValue())
574                if numAzms < 1:
575                    raise ValueError
576                data['outAzimuths'] = numAzms           
577            except ValueError:
578                pass
579            outAzim.SetValue(str(data['outAzimuths']))          #reset in case of error       
580            G2plt.PlotExposedImage(G2frame,event=event)
581       
582        def OnOblique(event):
583            if data['Oblique'][1]:
584                data['Oblique'][1] = False
585            else:
586                data['Oblique'][1] = True
587               
588        def OnObliqVal(event):
589            try:
590                value = float(obliqVal.GetValue())
591                if 0.01 <= value <= 0.99:
592                    data['Oblique'][0] = value
593                else:
594                    raise ValueError
595            except ValueError:
596                pass
597            obliqVal.SetValue('%.3f'%(data['Oblique'][0]))
598                           
599        def OnSamAbs(event):
600            if data['SampleAbs'][1]:
601                data['SampleAbs'][1] = False
602            else:
603                data['SampleAbs'][1] = True
604               
605        def OnSamAbsVal(event):
606            try:
607                value = float(samabsVal.GetValue())
608                minmax = [0.,2.]
609                if 'SASD' in data['type']:
610                    minmax = [.05,1.0]
611                if minmax[0] <= value <= minmax[1]:
612                    data['SampleAbs'][0] = value
613                else:
614                    raise ValueError
615            except ValueError:
616                pass
617            samabsVal.SetValue('%.3f'%(data['SampleAbs'][0]))
618                           
619        def OnShowLines(event):
620            if data['showLines']:
621                data['showLines'] = False
622            else:
623                data['showLines'] = True
624            G2plt.PlotExposedImage(G2frame,event=event)
625           
626        def OnFullIntegrate(event):
627            Lazm =int(G2frame.Lazim.GetValue())
628            if data['fullIntegrate']:
629                data['fullIntegrate'] = False
630                data['LRazimuth'] = [Lazm,Lazm+20]
631            else:
632                data['fullIntegrate'] = True
633                data['LRazimuth'] = [Lazm,Lazm+360]
634            wx.CallLater(100,UpdateImageControls,G2frame,data,masks)
635            G2plt.PlotExposedImage(G2frame,event=event)
636           
637        def OnSetDefault(event):
638            if data['setDefault']:
639                G2frame.imageDefault = {}
640                data['setDefault'] = False
641            else:
642                G2frame.imageDefault = copy.copy(data)
643                data['setDefault'] = True
644               
645        def OnCenterAzm(event):
646            if data['centerAzm']:
647                data['centerAzm'] = False
648            else:
649                data['centerAzm'] = True
650            G2plt.PlotExposedImage(G2frame,event=event)
651               
652        def OnApplyPola(event):
653            if data['PolaVal'][1]:
654                data['PolaVal'][1] = False
655            else:
656                data['PolaVal'][1] = True
657               
658        def OnPolaVal(event):
659            try:
660                value = float(polaVal.GetValue())
661                if 0.001 <= value <= 0.999:
662                    data['PolaVal'][0] = value
663                else:
664                    raise ValueError
665            except ValueError:
666                pass
667            polaVal.SetValue('%.3f'%(data['PolaVal'][0]))
668                           
669        dataSizer = wx.FlexGridSizer(0,2,5,3)
670        dataSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Integration coefficients'),0,WACV)   
671        dataSizer.Add((5,0),0)
672        if 'PWDR' in data['type']:
673            binChoice = ['2-theta','Q']
674        elif 'SASD' in data['type']:
675            binChoice = ['2-theta','Q','log(q)']
676        dataSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Bin style: Constant step bins in'),0,WACV)           
677        binSel = wx.ComboBox(parent=G2frame.dataDisplay,value=data['binType'],choices=binChoice,
678            style=wx.CB_READONLY|wx.CB_DROPDOWN)
679        binSel.Bind(wx.EVT_COMBOBOX, OnNewBinType)
680        dataSizer.Add(binSel,0,WACV)
681        binType = '2-theta'
682        if 'q' in data['binType'].lower():
683            binType = 'Q'
684        dataSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Inner/Outer '+binType),0,WACV)           
685        IOtth = data['IOtth'][:]
686        if 'Q' in data['binType']:
687            wave = data['wavelength']
688            IOtth = [4.*math.pi*sind(IOtth[0]/2.)/wave,4.*math.pi*sind(IOtth[1]/2.)/wave]
689        littleSizer = wx.BoxSizer(wx.HORIZONTAL)
690        G2frame.InnerTth = wx.TextCtrl(parent=G2frame.dataDisplay,
691            value=("%8.3f" % (IOtth[0])),style=wx.TE_PROCESS_ENTER)
692        G2frame.InnerTth.Bind(wx.EVT_TEXT_ENTER,OnIOtth)
693        G2frame.InnerTth.Bind(wx.EVT_KILL_FOCUS,OnIOtth)
694        littleSizer.Add(G2frame.InnerTth,0,WACV)
695        G2frame.OuterTth = wx.TextCtrl(parent=G2frame.dataDisplay,
696            value=("%8.2f" % (IOtth[1])),style=wx.TE_PROCESS_ENTER)
697        G2frame.OuterTth.Bind(wx.EVT_TEXT_ENTER,OnIOtth)
698        G2frame.OuterTth.Bind(wx.EVT_KILL_FOCUS,OnIOtth)
699        littleSizer.Add(G2frame.OuterTth,0,WACV)
700        dataSizer.Add(littleSizer,0,)
701        dataSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Start/End azimuth'),0,WACV)
702        LRazim = data['LRazimuth']
703        littleSizer = wx.BoxSizer(wx.HORIZONTAL)
704        G2frame.Lazim = wx.TextCtrl(parent=G2frame.dataDisplay,
705            value=("%6d" % (LRazim[0])),style=wx.TE_PROCESS_ENTER)
706        G2frame.Lazim.Bind(wx.EVT_TEXT_ENTER,OnLRazim)
707        G2frame.Lazim.Bind(wx.EVT_KILL_FOCUS,OnLRazim)
708        littleSizer.Add(G2frame.Lazim,0,WACV)
709        G2frame.Razim = wx.TextCtrl(parent=G2frame.dataDisplay,
710            value=("%6d" % (LRazim[1])),style=wx.TE_PROCESS_ENTER)
711        G2frame.Razim.Bind(wx.EVT_TEXT_ENTER,OnLRazim)
712        G2frame.Razim.Bind(wx.EVT_KILL_FOCUS,OnLRazim)
713        if data['fullIntegrate']:
714            G2frame.Razim.Enable(False)
715            G2frame.Razim.SetBackgroundColour(VERY_LIGHT_GREY)
716            G2frame.Razim.SetValue("%6d" % (LRazim[0]+360))
717        littleSizer.Add(G2frame.Razim,0,WACV)
718        dataSizer.Add(littleSizer,0,)
719        dataSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' No. 2-theta/azimuth bins'),0,WACV)
720        littleSizer = wx.BoxSizer(wx.HORIZONTAL)
721        outChan = wx.TextCtrl(parent=G2frame.dataDisplay,value=str(data['outChannels']),style=wx.TE_PROCESS_ENTER)
722        outChan.Bind(wx.EVT_TEXT_ENTER,OnNumOutChans)
723        outChan.Bind(wx.EVT_KILL_FOCUS,OnNumOutChans)
724        littleSizer.Add(outChan,0,WACV)
725        outAzim = wx.TextCtrl(parent=G2frame.dataDisplay,value=str(data['outAzimuths']),style=wx.TE_PROCESS_ENTER)
726        outAzim.Bind(wx.EVT_TEXT_ENTER,OnNumOutAzms)
727        outAzim.Bind(wx.EVT_KILL_FOCUS,OnNumOutAzms)
728        littleSizer.Add(outAzim,0,WACV)
729        dataSizer.Add(littleSizer,0,)
730        littleSizer = wx.BoxSizer(wx.HORIZONTAL)
731        samabs = wx.CheckBox(parent=G2frame.dataDisplay,label='Apply sample absorption?')
732        dataSizer.Add(samabs,0,WACV)
733        samabs.Bind(wx.EVT_CHECKBOX, OnSamAbs)
734        samabs.SetValue(data['SampleAbs'][1])
735        if 'PWDR' in data['type']:
736            littleSizer.Add(wx.StaticText(G2frame.dataDisplay,label='mu/R (0.00-2.0) '),0,WACV)
737        elif 'SASD' in data['type']:
738            littleSizer.Add(wx.StaticText(G2frame.dataDisplay,label='transmission '),0,WACV)
739        samabsVal = wx.TextCtrl(parent=G2frame.dataDisplay,value='%.3f'%(data['SampleAbs'][0]),style=wx.TE_PROCESS_ENTER)           
740        samabsVal.Bind(wx.EVT_TEXT_ENTER,OnSamAbsVal)
741        samabsVal.Bind(wx.EVT_KILL_FOCUS,OnSamAbsVal)
742        littleSizer.Add(samabsVal,0,WACV)
743        dataSizer.Add(littleSizer,0,)
744        if 'PWDR' in data['type']:
745            littleSizer = wx.BoxSizer(wx.HORIZONTAL)
746            oblique = wx.CheckBox(parent=G2frame.dataDisplay,label='Apply detector absorption?')
747            dataSizer.Add(oblique,0,WACV)
748            oblique.Bind(wx.EVT_CHECKBOX, OnOblique)
749            oblique.SetValue(data['Oblique'][1])
750            littleSizer.Add(wx.StaticText(G2frame.dataDisplay,label='Value (0.01-0.99)  '),0,WACV)
751            obliqVal = wx.TextCtrl(parent=G2frame.dataDisplay,value='%.3f'%(data['Oblique'][0]),style=wx.TE_PROCESS_ENTER)
752            obliqVal.Bind(wx.EVT_TEXT_ENTER,OnObliqVal)
753            obliqVal.Bind(wx.EVT_KILL_FOCUS,OnObliqVal)
754            littleSizer.Add(obliqVal,0,WACV)
755            dataSizer.Add(littleSizer,0,)
756        if 'SASD' in data['type']:
757            littleSizer = wx.BoxSizer(wx.HORIZONTAL)
758            setPolariz = wx.CheckBox(parent=G2frame.dataDisplay,label='Apply polarization?')
759            dataSizer.Add(setPolariz,0,WACV)
760            setPolariz.Bind(wx.EVT_CHECKBOX, OnApplyPola)
761            setPolariz.SetValue(data['PolaVal'][1])
762            littleSizer.Add(wx.StaticText(G2frame.dataDisplay,label='Value (0.001-0.999)  '),0,WACV)
763            polaVal = wx.TextCtrl(parent=G2frame.dataDisplay,value='%.3f'%(data['PolaVal'][0]),
764                style=wx.TE_PROCESS_ENTER)
765            polaVal.Bind(wx.EVT_TEXT_ENTER,OnPolaVal)
766            polaVal.Bind(wx.EVT_KILL_FOCUS,OnPolaVal)
767            littleSizer.Add(polaVal,0,WACV)
768            dataSizer.Add(littleSizer,0,)
769       
770        showLines = wx.CheckBox(parent=G2frame.dataDisplay,label='Show integration limits?')
771        dataSizer.Add(showLines,0,WACV)
772        showLines.Bind(wx.EVT_CHECKBOX, OnShowLines)
773        showLines.SetValue(data['showLines'])
774        fullIntegrate = wx.CheckBox(parent=G2frame.dataDisplay,label='Do full integration?')
775        dataSizer.Add(fullIntegrate,0,WACV)
776        fullIntegrate.Bind(wx.EVT_CHECKBOX, OnFullIntegrate)
777        fullIntegrate.SetValue(data['fullIntegrate'])
778        setDefault = wx.CheckBox(parent=G2frame.dataDisplay,label='Use as default for all images?')
779        dataSizer.Add(setDefault,0,WACV)
780        setDefault.Bind(wx.EVT_CHECKBOX, OnSetDefault)
781        setDefault.SetValue(data['setDefault'])
782        centerAzm = wx.CheckBox(parent=G2frame.dataDisplay,label='Azimuth at bin center?')
783        dataSizer.Add(centerAzm,0,WACV)
784        centerAzm.Bind(wx.EVT_CHECKBOX, OnCenterAzm)
785        centerAzm.SetValue(data['centerAzm'])
786        return dataSizer
787       
788    def BackSizer():
789       
790        def OnBackImage(event):
791            data['background image'][0] = backImage.GetValue()
792           
793        def OnDarkImage(event):
794            data['dark image'][0] = darkImage.GetValue()
795            G2plt.PlotExposedImage(G2frame,event=event)
796           
797        def OnFlatBkg(event):
798            try:
799                value = float(flatbkg.GetValue())
800                data['Flat Bkg'] = value
801            except ValueError:
802                pass
803            flatbkg.SetValue("%.0f"%(data['Flat Bkg']))   
804            G2plt.PlotExposedImage(G2frame,event=event)
805
806        def OnBackMult(event):
807            try:
808                mult = float(backMult.GetValue())
809                data['background image'][1] = mult
810            except ValueError:
811                pass
812            backMult.SetValue("%.3f" % (data['background image'][1]))          #reset in case of error
813       
814        def OnDarkMult(event):
815            try:
816                mult = float(darkMult.GetValue())
817                data['dark image'][1] = mult
818            except ValueError:
819                pass
820            darkMult.SetValue("%.3f" % (data['dark image'][1]))          #reset in case of error
821            G2plt.PlotExposedImage(G2frame,event=event)
822       
823        backSizer = wx.FlexGridSizer(0,6,5,5)
824
825        backSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' Dark image'),0,WACV)
826        Choices = ['',]+G2gd.GetPatternTreeDataNames(G2frame,['IMG ',])
827        darkImage = wx.ComboBox(parent=G2frame.dataDisplay,value=data['dark image'][0],choices=Choices,
828            style=wx.CB_READONLY|wx.CB_DROPDOWN)
829        darkImage.Bind(wx.EVT_COMBOBOX,OnDarkImage)
830        backSizer.Add(darkImage)
831        backSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' multiplier'),0,WACV)
832        darkMult =  wx.TextCtrl(parent=G2frame.dataDisplay,value=("%.3f" % (data['dark image'][1])),
833            style=wx.TE_PROCESS_ENTER)
834        darkMult.Bind(wx.EVT_TEXT_ENTER,OnDarkMult)
835        darkMult.Bind(wx.EVT_KILL_FOCUS,OnDarkMult)
836        backSizer.Add(darkMult,0,WACV)
837        backSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' Flat Bkg: '),0,WACV)
838        flatbkg = wx.TextCtrl(parent=G2frame.dataDisplay,value=("%.0f" % (data['Flat Bkg'])),
839            style=wx.TE_PROCESS_ENTER)
840        flatbkg.Bind(wx.EVT_TEXT_ENTER,OnFlatBkg)
841        flatbkg.Bind(wx.EVT_KILL_FOCUS,OnFlatBkg)
842        backSizer.Add(flatbkg,0,WACV)
843
844        backSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' Background image'),0,WACV)
845        Choices = ['',]+G2gd.GetPatternTreeDataNames(G2frame,['IMG ',])
846        backImage = wx.ComboBox(parent=G2frame.dataDisplay,value=data['background image'][0],choices=Choices,
847            style=wx.CB_READONLY|wx.CB_DROPDOWN)
848        backImage.Bind(wx.EVT_COMBOBOX,OnBackImage)
849        backSizer.Add(backImage)
850        backSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' multiplier'),0,WACV)
851        backMult =  wx.TextCtrl(parent=G2frame.dataDisplay,value=("%.3f" % (data['background image'][1])),
852            style=wx.TE_PROCESS_ENTER)
853        backMult.Bind(wx.EVT_TEXT_ENTER,OnBackMult)
854        backMult.Bind(wx.EVT_KILL_FOCUS,OnBackMult)
855        backSizer.Add(backMult,0,WACV)
856        return backSizer
857                       
858    def CalibSizer():
859               
860        def OnNewCalibrant(event):
861            data['calibrant'] = calSel.GetValue()
862            data['calibskip'] = calFile.Calibrants[data['calibrant']][3]
863            limits = calFile.Calibrants[data['calibrant']][4]
864            data['calibdmin'],data['pixLimit'],data['cutoff'] = limits
865            pixLimit.SetValue(str(limits[1]))
866            cutOff.SetValue('%.1f'%(limits[2]))
867            calibSkip.SetValue(str(data['calibskip']))
868            calibDmin.SetValue('%.1f'%(limits[0]))
869           
870        def OnCalibSkip(event):
871            data['calibskip'] = int(calibSkip.GetValue())
872           
873        def OnCalibDmin(event):
874            try:
875                dmin = float(calibDmin.GetValue())
876                if dmin < 0.25:
877                    raise ValueError
878                data['calibdmin'] = dmin
879            except ValueError:
880                pass
881            calibDmin.SetValue("%.2f"%(data['calibdmin']))          #reset in case of error 
882                   
883        def OnCutOff(event):
884            try:
885                cutoff = float(cutOff.GetValue())
886                if cutoff < 0.1:
887                    raise ValueError
888                data['cutoff'] = cutoff
889            except ValueError:
890                pass
891            cutOff.SetValue("%.1f"%(data['cutoff']))          #reset in case of error 
892       
893        def OnPixLimit(event):
894            data['pixLimit'] = int(pixLimit.GetValue())
895           
896        def OnSetRings(event):
897            if data['setRings']:
898                data['setRings'] = False
899            else:
900                data['setRings'] = True
901            G2plt.PlotExposedImage(G2frame,event=event)
902   
903        calibSizer = wx.FlexGridSizer(0,3,5,5)
904        comboSizer = wx.BoxSizer(wx.HORIZONTAL)   
905        comboSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Calibrant '),0,WACV)
906        calSel = wx.ComboBox(parent=G2frame.dataDisplay,value=data['calibrant'],choices=calList,
907            style=wx.CB_READONLY|wx.CB_DROPDOWN)
908        calSel.Bind(wx.EVT_COMBOBOX, OnNewCalibrant)
909        comboSizer.Add(calSel,0,WACV)
910        calibSizer.Add(comboSizer,0)
911       
912        comboSizer = wx.BoxSizer(wx.HORIZONTAL)   
913        comboSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Calib lines to skip   '),0,WACV)
914        calibSkip  = wx.ComboBox(parent=G2frame.dataDisplay,value=str(data['calibskip']),choices=[str(i) for i in range(25)],
915            style=wx.CB_READONLY|wx.CB_DROPDOWN)
916        calibSkip.Bind(wx.EVT_COMBOBOX, OnCalibSkip)
917        comboSizer.Add(calibSkip,0,WACV)
918        calibSizer.Add(comboSizer,0)
919       
920        comboSizer = wx.BoxSizer(wx.HORIZONTAL)       
921        comboSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Min calib d-spacing '),0,WACV)
922        calibDmin = wx.TextCtrl(parent=G2frame.dataDisplay,value=("%.2f" % (data['calibdmin'])),
923            style=wx.TE_PROCESS_ENTER)
924        calibDmin.Bind(wx.EVT_TEXT_ENTER,OnCalibDmin)
925        calibDmin.Bind(wx.EVT_KILL_FOCUS,OnCalibDmin)
926        comboSizer.Add(calibDmin,0,WACV)
927        calibSizer.Add(comboSizer,0)
928       
929        comboSizer = wx.BoxSizer(wx.HORIZONTAL)
930        comboSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Min ring I/Ib '),0,WACV)
931        cutOff = wx.TextCtrl(parent=G2frame.dataDisplay,value=("%.1f" % (data['cutoff'])),
932            style=wx.TE_PROCESS_ENTER)
933        cutOff.Bind(wx.EVT_TEXT_ENTER,OnCutOff)
934        cutOff.Bind(wx.EVT_KILL_FOCUS,OnCutOff)
935        comboSizer.Add(cutOff,0,WACV)
936        calibSizer.Add(comboSizer,0)
937       
938        comboSizer = wx.BoxSizer(wx.HORIZONTAL)
939        comboSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Pixel search range '),0,WACV)
940        pixLimit = wx.ComboBox(parent=G2frame.dataDisplay,value=str(data['pixLimit']),choices=['1','2','5','10','15','20'],
941            style=wx.CB_READONLY|wx.CB_DROPDOWN)
942        pixLimit.Bind(wx.EVT_COMBOBOX, OnPixLimit)
943        comboSizer.Add(pixLimit,0,WACV)
944        calibSizer.Add(comboSizer,0)
945       
946        comboSizer = wx.BoxSizer(wx.HORIZONTAL)
947        setRings = wx.CheckBox(parent=G2frame.dataDisplay,label='Show ring picks?')
948        comboSizer.Add(setRings,0)
949        setRings.Bind(wx.EVT_CHECKBOX, OnSetRings)
950        setRings.SetValue(data['setRings'])
951        calibSizer.Add(comboSizer,0)
952        return calibSizer
953       
954    def GonioSizer():
955       
956        ValObj = {}
957       
958        def OnGonioAngle(event):
959            Obj = event.GetEventObject()
960            item = ValObj[Obj.GetId()]
961            try:
962                value = float(Obj.GetValue())
963            except ValueError:
964                value = data['GonioAngles'][item]
965            data['GonioAngles'][item] = value
966            Obj.SetValue('%8.2f'%(value))
967           
968        def OnGlobalEdit(event):
969            Names = []
970            Items = []
971            if G2frame.PatternTree.GetCount():
972                id, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root)
973                while id:
974                    name = G2frame.PatternTree.GetItemText(id)
975                    if 'IMG' in name:
976                        ctrls = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,id,'Image Controls'))
977                        Names.append(name)
978                        Items.append(ctrls['GonioAngles'])
979                    id, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie)
980                if len(Names) == 1:
981                    G2frame.ErrorDialog('Nothing for global editing','There must be more than one "IMG" pattern')
982                    return
983                dlg = G2G.G2HistoDataDialog(G2frame,' Edit sample goniometer data:',
984                    'Edit data',['Omega','Chi','Phi'],['%.2f','%.2f','%.2f'],Names,Items)
985            try:
986                if dlg.ShowModal() == wx.ID_OK:
987                    result = dlg.GetData()
988                    id, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root)
989                    while id:
990                        name = G2frame.PatternTree.GetItemText(id)
991                        if 'IMG' in name:
992                            ctrls = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,id,'Image Controls'))
993                            vals = Items[Names.index(name)]
994                            ctrls['GonioAngles'] = vals
995#                            G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,id, 'Image Controls'),ctrls)
996                        id, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie)
997            finally:
998                dlg.Destroy()
999                G2frame.PatternTree.SelectItem(G2frame.PickId)
1000       
1001        gonioSizer = wx.BoxSizer(wx.HORIZONTAL)
1002        names = ['Omega','Chi','Phi']
1003        gonioSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,'Sample goniometer angles: '),0,WACV)
1004        for i,name in enumerate(names):
1005            gonioSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,name),0,WACV)
1006            angle = wx.TextCtrl(G2frame.dataDisplay,-1,value='%8.2f'%(data['GonioAngles'][i]),
1007                style=wx.TE_PROCESS_ENTER)
1008            angle.Bind(wx.EVT_TEXT_ENTER,OnGonioAngle)
1009            angle.Bind(wx.EVT_KILL_FOCUS,OnGonioAngle)
1010            ValObj[angle.GetId()] = i
1011            gonioSizer.Add(angle,0,WACV)
1012        globEdit = wx.Button(G2frame.dataDisplay,-1,'Global edit')
1013        globEdit.Bind(wx.EVT_BUTTON,OnGlobalEdit)
1014        gonioSizer.Add(globEdit,0,WACV)
1015        return gonioSizer
1016       
1017# Image Controls main code             
1018                           
1019    #fix for old files:
1020    if 'azmthOff' not in data:
1021        data['azmthOff'] = 0.0
1022    if 'background image' not in data:
1023        data['background image'] = ['',-1.0]
1024    if 'dark image' not in data:
1025        data['dark image'] = ['',-1.0]
1026    if 'centerAzm' not in data:
1027        data['centerAzm'] = False
1028    if 'Oblique' not in data:
1029        data['Oblique'] = [0.5,False]
1030    if 'PolaVal' not in data:
1031        data['PolaVal'] = [0.99,False]
1032    #end fix
1033   
1034    if IntegrateOnly:
1035        OnIntegrate(None)
1036        return
1037   
1038    colorList = sorted([m for m in mpl.cm.datad.keys() if not m.endswith("_r")],key=lambda s: s.lower())
1039    calList = sorted([m for m in calFile.Calibrants.keys()],key=lambda s: s.lower())
1040    typeList = ['PWDR - powder diffraction data','SASD - small angle scattering data',
1041        'REFL - reflectometry data']
1042    if not data.get('type'):                        #patch for old project files
1043        data['type'] = 'PWDR'
1044    typeDict = {'PWDR':typeList[0],'SASD':typeList[1],'REFL':typeList[2]}
1045    if G2frame.dataDisplay:
1046        G2frame.dataDisplay.Destroy()
1047    G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.ImageMenu)
1048    if not G2frame.dataFrame.GetStatusBar():
1049        G2frame.dataFrame.CreateStatusBar()
1050    G2frame.dataFrame.Bind(wx.EVT_MENU, OnCalibrate, id=G2gd.wxID_IMCALIBRATE)
1051    G2frame.dataFrame.Bind(wx.EVT_MENU, OnRecalibrate, id=G2gd.wxID_IMRECALIBRATE)
1052    G2frame.dataFrame.Bind(wx.EVT_MENU, OnClearCalib, id=G2gd.wxID_IMCLEARCALIB)
1053    if 'chisq' not in data:
1054        G2frame.dataFrame.ImageEdit.Enable(id=G2gd.wxID_IMRECALIBRATE,enable=False)   
1055    G2frame.dataFrame.Bind(wx.EVT_MENU, OnIntegrate, id=G2gd.wxID_IMINTEGRATE)
1056    G2frame.dataFrame.Bind(wx.EVT_MENU, OnIntegrateAll, id=G2gd.wxID_INTEGRATEALL)
1057    G2frame.dataFrame.Bind(wx.EVT_MENU, OnCopyControls, id=G2gd.wxID_IMCOPYCONTROLS)
1058    G2frame.dataFrame.Bind(wx.EVT_MENU, OnSaveControls, id=G2gd.wxID_IMSAVECONTROLS)
1059    G2frame.dataFrame.Bind(wx.EVT_MENU, OnLoadControls, id=G2gd.wxID_IMLOADCONTROLS)
1060    if GSASIIpath.GetConfigValue('debug'):
1061        import autoint
1062        def OnDestroy(event):
1063            G2frame.autoIntFrame = None
1064        def OnAutoInt(event):
1065            reload(autoint)
1066            if G2frame.autoIntFrame: # ensure only one open at a time
1067                G2frame.autoIntFrame.Raise()
1068                return
1069            G2frame.autoIntFrame = autoint.AutoIntFrame(G2frame,PollTime=5.0)
1070            G2frame.autoIntFrame.Bind(wx.EVT_WINDOW_DESTROY,OnDestroy) # clean up name on window close
1071        G2frame.dataFrame.Bind(wx.EVT_MENU, OnAutoInt, id=G2gd.wxID_IMAUTOINTEG)
1072    G2frame.dataDisplay = wx.Panel(G2frame.dataFrame)
1073
1074    mainSizer = wx.BoxSizer(wx.VERTICAL)
1075    mainSizer.Add((5,10),0)   
1076    mainSizer.Add(ComboSizer(),0,wx.ALIGN_LEFT)
1077    mainSizer.Add((5,5),0)           
1078    mainSizer.Add(MaxSizer(),0,wx.ALIGN_LEFT|wx.EXPAND)
1079   
1080    mainSizer.Add((5,5),0)
1081    DataSizer = wx.FlexGridSizer(0,2,5,5)
1082    DataSizer.Add(CalibCoeffSizer(),0)
1083    DataSizer.Add(IntegrateSizer(),0)       
1084    mainSizer.Add(DataSizer,0)
1085    mainSizer.Add((5,5),0)           
1086    mainSizer.Add(BackSizer(),0)
1087    mainSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Calibration controls:'),0,WACV)
1088    mainSizer.Add((5,5),0)
1089    mainSizer.Add(CalibSizer(),0,WACV)
1090    mainSizer.Add((5,5),0)
1091    mainSizer.Add(GonioSizer(),0,WACV)   
1092       
1093    mainSizer.Layout()   
1094    G2frame.dataDisplay.SetSizer(mainSizer)
1095    fitSize = mainSizer.Fit(G2frame.dataFrame)
1096    G2frame.dataFrame.setSizePosLeft(fitSize)
1097    G2frame.dataDisplay.SetSize(fitSize)
1098   
1099################################################################################
1100##### Masks
1101################################################################################
1102def CleanupMasks(data):
1103    '''If a mask creation is not completed, an empty mask entry is created in the
1104    masks array. This cleans them out. It is called when the masks page is first loaded
1105    and before saving them or after reading them in. This should also probably be done
1106    before they are used for integration.
1107    '''
1108    for key in ['Points','Rings','Arcs','Polygons']:
1109        data[key] = data.get(key,[])
1110        l1 = len(data[key])
1111        data[key] = [i for i in data[key] if i]
1112        l2 = len(data[key])
1113        if GSASIIpath.GetConfigValue('debug') and l1 != l2:
1114            print 'Mask Cleanup:',key,'was',l1,'entries','now',l2
1115   
1116def UpdateMasks(G2frame,data):
1117    '''Shows and handles the controls on the "Masks" data tree entry
1118    '''
1119   
1120    def OnTextMsg(event):
1121        Obj = event.GetEventObject()
1122        Obj.SetToolTipString('Drag this mask on 2D Powder Image with mouse to change ')
1123
1124    def Replot(*args,**kwargs):
1125        G2plt.PlotExposedImage(G2frame,newPlot=True)       
1126
1127    def onDeleteMask(event):
1128        Obj = event.GetEventObject()
1129        typ = Obj.locationcode.split('+')[1]
1130        num = int(Obj.locationcode.split('+')[2])
1131        del(data[typ][num])
1132        wx.CallAfter(UpdateMasks,G2frame,data)
1133        G2plt.PlotExposedImage(G2frame,event=event)
1134
1135    def onDeleteFrame(event):
1136        data['Frames'] = []
1137        wx.CallAfter(UpdateMasks,G2frame,data)
1138        G2plt.PlotExposedImage(G2frame,event=event)
1139
1140    def OnCopyMask(event):
1141        TextList = [[False,'All IMG',0]]
1142        Names = []
1143        if G2frame.PatternTree.GetCount():
1144            id, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root)
1145            while id:
1146                name = G2frame.PatternTree.GetItemText(id)
1147                Names.append(name)
1148                if 'IMG' in name:
1149                    if id == G2frame.Image:
1150                        Source = name
1151                        Mask = copy.deepcopy(G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,id, 'Masks')))
1152                        Thresh = Mask.pop('Thresholds')  #remove Thresholds from source mask & save it for later
1153                    else:
1154                        TextList.append([False,name,id])
1155                id, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie)
1156            if len(TextList) == 1:
1157                G2frame.ErrorDialog('Nothing to copy mask to','There must be more than one "IMG" pattern')
1158                return
1159            dlg = G2frame.CopyDialog(G2frame,'Copy mask information','Copy mask from '+Source+' to:',TextList)
1160            try:
1161                if dlg.ShowModal() == wx.ID_OK:
1162                    result = dlg.GetData()
1163                    if result[0][0]:
1164                        result = TextList[1:]
1165                        for item in result: item[0] = True
1166                    for i,item in enumerate(result):
1167                        ifcopy,name,id = item
1168                        if ifcopy:
1169                            mask = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,id, 'Masks'))
1170#                            Mask['Thresholds'][0] = mask['Thresholds'][0]
1171#                            Mask['Thresholds'][1][1] = min(mask['Thresholds'][1][1],Mask['Thresholds'][1][1])
1172                            mask.update(Mask)
1173                            mask['Thresholds'][1][0] = Thresh[1][0]  #copy only lower threshold                             
1174                            G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,id, 'Masks'),copy.deepcopy(mask))
1175            finally:
1176                dlg.Destroy()
1177               
1178    def OnSaveMask(event):
1179        CleanupMasks(data)
1180        dlg = wx.FileDialog(G2frame, 'Choose image mask file', '.', '', 
1181            'image mask files (*.immask)|*.immask',wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT|wx.CHANGE_DIR)
1182        try:
1183            if dlg.ShowModal() == wx.ID_OK:
1184                filename = dlg.GetPath()
1185                File = open(filename,'w')
1186                save = {}
1187                keys = ['Points','Rings','Arcs','Polygons','Frames','Thresholds']
1188                for key in keys:
1189                    File.write(key+':'+str(data[key])+'\n')
1190                File.close()
1191        finally:
1192            dlg.Destroy()
1193       
1194    def OnLoadMask(event):
1195        if event.Id == G2gd.wxID_MASKLOADNOT:
1196            ignoreThreshold = True
1197        else:
1198            ignoreThreshold = False
1199        dlg = wx.FileDialog(G2frame, 'Choose image mask file', '.', '', 
1200            'image mask files (*.immask)|*.immask',wx.OPEN|wx.CHANGE_DIR)
1201        try:
1202            if dlg.ShowModal() == wx.ID_OK:
1203                filename = dlg.GetPath()
1204                File = open(filename,'r')
1205                save = {}
1206                oldThreshold = data['Thresholds'][0]
1207                S = File.readline()
1208                while S:
1209                    if S[0] == '#':
1210                        S = File.readline()
1211                        continue
1212                    [key,val] = S[:-1].split(':')
1213                    if key in ['Points','Rings','Arcs','Polygons','Frames','Thresholds']:
1214                        if ignoreThreshold and key == 'Thresholds':
1215                            S = File.readline() 
1216                            continue
1217                        save[key] = eval(val)
1218                        if key == 'Thresholds':
1219                            save[key][0] = oldThreshold
1220                            save[key][1][1] = min(oldThreshold[1],save[key][1][1])
1221                    S = File.readline()
1222                File.close()
1223                data.update(save)
1224                CleanupMasks(data)
1225                wx.CallAfter(UpdateMasks,G2frame,data)
1226                G2plt.PlotExposedImage(G2frame,event=event)               
1227        finally:
1228            dlg.Destroy()
1229           
1230    def OnNewSpotMask(event):
1231        'Start a new spot mask'
1232        G2frame.MaskKey = 's'
1233        G2plt.OnStartMask(G2frame)
1234       
1235    def OnNewArcMask(event):
1236        'Start a new arc mask'
1237        G2frame.MaskKey = 'a'
1238        G2plt.OnStartMask(G2frame)
1239       
1240    def OnNewRingMask(event):
1241        'Start a new ring mask'
1242        G2frame.MaskKey = 'r'
1243        G2plt.OnStartMask(G2frame)
1244       
1245    def OnNewPolyMask(event):
1246        'Start a new polygon mask'
1247        G2frame.MaskKey = 'p'
1248        G2plt.OnStartMask(G2frame)
1249       
1250    def OnNewFrameMask(event):
1251        'Start a new Frame mask'
1252        G2frame.MaskKey = 'f'
1253        G2plt.OnStartMask(G2frame)
1254
1255    startScroll = None
1256    if G2frame.dataDisplay:
1257        startScroll = G2frame.dataDisplay.GetScrollPos(wx.VERTICAL) # save scroll position
1258        G2frame.dataDisplay.Destroy()
1259    else:
1260        CleanupMasks(data) # posting page for 1st time; clean out anything unfinished
1261    G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.MaskMenu)
1262    G2frame.dataFrame.Bind(wx.EVT_MENU, OnCopyMask, id=G2gd.wxID_MASKCOPY)
1263    G2frame.dataFrame.Bind(wx.EVT_MENU, OnLoadMask, id=G2gd.wxID_MASKLOAD)
1264    G2frame.dataFrame.Bind(wx.EVT_MENU, OnLoadMask, id=G2gd.wxID_MASKLOADNOT)
1265    G2frame.dataFrame.Bind(wx.EVT_MENU, OnSaveMask, id=G2gd.wxID_MASKSAVE)
1266    G2frame.dataFrame.Bind(wx.EVT_MENU, OnNewSpotMask, id=G2gd.wxID_NEWMASKSPOT)
1267    G2frame.dataFrame.Bind(wx.EVT_MENU, OnNewArcMask, id=G2gd.wxID_NEWMASKARC)
1268    G2frame.dataFrame.Bind(wx.EVT_MENU, OnNewRingMask, id=G2gd.wxID_NEWMASKRING)
1269    G2frame.dataFrame.Bind(wx.EVT_MENU, OnNewPolyMask, id=G2gd.wxID_NEWMASKPOLY)
1270    G2frame.dataFrame.Bind(wx.EVT_MENU, OnNewFrameMask, id=G2gd.wxID_NEWMASKFRAME)
1271    if not G2frame.dataFrame.GetStatusBar():
1272        Status = G2frame.dataFrame.CreateStatusBar()
1273    if G2frame.MaskKey == 'f':
1274        G2frame.dataFrame.GetStatusBar().SetStatusText('Frame mask active - LB pick next point, RB close polygon')
1275    elif G2frame.MaskKey == 'p':
1276        G2frame.dataFrame.GetStatusBar().SetStatusText('Polygon mask active - LB pick next point, RB close polygon')
1277    elif G2frame.MaskKey == 's':
1278        G2frame.dataFrame.GetStatusBar().SetStatusText('Spot mask active - LB pick spot location')
1279    elif G2frame.MaskKey == 'a':
1280        G2frame.dataFrame.GetStatusBar().SetStatusText('Arc mask active - LB pick arc location')
1281    elif G2frame.MaskKey == 'r':
1282        G2frame.dataFrame.GetStatusBar().SetStatusText('Ring mask active - LB pick ring location')
1283    else:
1284        G2frame.dataFrame.GetStatusBar().SetStatusText("To add mask: press a,r,s,p or f on 2D image for arc/ring/spot/polygon/frame")
1285    G2frame.dataDisplay = wxscroll.ScrolledPanel(G2frame.dataFrame)
1286    mainSizer = wx.BoxSizer(wx.VERTICAL)
1287    mainSizer.Add((5,10),0)
1288
1289    thresh = data['Thresholds']         #min/max intensity range
1290    Spots = data['Points']               #x,y,radius in mm
1291    Rings = data['Rings']               #radius, thickness
1292    Polygons = data['Polygons']         #3+ x,y pairs
1293    if 'Frames' not in data:
1294        data['Frames'] = []
1295    frame = data['Frames']             #3+ x,y pairs
1296    Arcs = data['Arcs']                 #radius, start/end azimuth, thickness
1297   
1298    littleSizer = wx.FlexGridSizer(0,3,0,5)
1299    littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Lower/Upper limits '),0,WACV)
1300    Text = wx.TextCtrl(G2frame.dataDisplay,value=str(thresh[0][0]),style=wx.TE_READONLY)
1301    littleSizer.Add(Text,0,WACV)
1302    Text.SetBackgroundColour(VERY_LIGHT_GREY)
1303    Text = wx.TextCtrl(G2frame.dataDisplay,value=str(thresh[0][1]),style=wx.TE_READONLY)
1304    littleSizer.Add(Text,0,WACV)
1305    Text.SetBackgroundColour(VERY_LIGHT_GREY)
1306    littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Lower/Upper thresholds '),0,WACV)
1307    lowerThreshold = G2G.ValidatedTxtCtrl(G2frame.dataDisplay,loc=thresh[1],key=0,
1308                                           min=thresh[0][0],OnLeave=Replot,typeHint=int)
1309    littleSizer.Add(lowerThreshold,0,WACV)
1310    upperThreshold = G2G.ValidatedTxtCtrl(G2frame.dataDisplay,loc=thresh[1],key=1,
1311                                           max=thresh[0][1],OnLeave=Replot,typeHint=int)
1312    littleSizer.Add(upperThreshold,0,WACV)
1313    mainSizer.Add(littleSizer,0,)
1314    if Spots:
1315        lbl = wx.StaticText(parent=G2frame.dataDisplay,label=' Spot masks')
1316        lbl.SetBackgroundColour(wx.Colour(200,200,210))
1317        mainSizer.Add(lbl,0,wx.EXPAND|wx.ALIGN_CENTER,0)
1318        littleSizer = wx.FlexGridSizer(0,3,0,5)
1319        littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' position, mm'),0,WACV)
1320        littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' diameter, mm'),0,WACV)
1321        littleSizer.Add((5,0),0)
1322        for i in range(len(Spots)):
1323            if Spots[i]:
1324                x,y,d = Spots[i]
1325                spotText = wx.TextCtrl(parent=G2frame.dataDisplay,value=("%.2f,%.2f" % (x,y)),
1326                    style=wx.TE_READONLY)
1327                spotText.SetBackgroundColour(VERY_LIGHT_GREY)
1328                littleSizer.Add(spotText,0,WACV)
1329                spotText.Bind(wx.EVT_ENTER_WINDOW,OnTextMsg)
1330                spotDiameter = G2G.ValidatedTxtCtrl(G2frame.dataDisplay,loc=Spots[i],key=2,
1331                                           max=100.,OnLeave=Replot,nDig=[8,2])
1332                littleSizer.Add(spotDiameter,0,WACV)
1333                spotDelete = G2G.G2LoggedButton(G2frame.dataDisplay,label='delete?',
1334                                            locationcode='Delete+Points+'+str(i),
1335                                            handler=onDeleteMask)
1336                littleSizer.Add(spotDelete,0,WACV)
1337        mainSizer.Add(littleSizer,0,)
1338    if Rings:
1339        lbl = wx.StaticText(parent=G2frame.dataDisplay,label=' Ring masks')
1340        lbl.SetBackgroundColour(wx.Colour(200,200,210))
1341        mainSizer.Add(lbl,0,wx.EXPAND|wx.ALIGN_CENTER,0)
1342        littleSizer = wx.FlexGridSizer(0,3,0,5)
1343        littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' 2-theta,deg'),0,WACV)
1344        littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' thickness, deg'),0,WACV)
1345        littleSizer.Add((5,0),0)
1346        for i in range(len(Rings)):
1347            if Rings[i]:
1348                ringText = wx.TextCtrl(parent=G2frame.dataDisplay,value=("%.3f" % (Rings[i][0])),
1349                    style=wx.TE_READONLY)
1350                ringText.SetBackgroundColour(VERY_LIGHT_GREY)
1351                ringText.Bind(wx.EVT_ENTER_WINDOW,OnTextMsg)
1352                littleSizer.Add(ringText,0,WACV)
1353                ringThick = G2G.ValidatedTxtCtrl(G2frame.dataDisplay,loc=Rings[i],key=1,
1354                                           min=0.001,max=1.,OnLeave=Replot,nDig=[8,3])
1355                littleSizer.Add(ringThick,0,WACV)
1356                ringDelete = G2G.G2LoggedButton(G2frame.dataDisplay,label='delete?',
1357                                            locationcode='Delete+Rings+'+str(i),
1358                                            handler=onDeleteMask)
1359                littleSizer.Add(ringDelete,0,WACV)
1360        mainSizer.Add(littleSizer,0,)
1361    if Arcs:
1362        lbl = wx.StaticText(parent=G2frame.dataDisplay,label=' Arc masks')
1363        lbl.SetBackgroundColour(wx.Colour(200,200,210))
1364        mainSizer.Add(lbl,0,wx.EXPAND|wx.ALIGN_CENTER,0)
1365        littleSizer = wx.FlexGridSizer(0,4,0,5)
1366        littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' 2-theta,deg'),0,WACV)
1367        littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' azimuth, deg'),0,WACV)
1368        littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' thickness, deg'),0,WACV)
1369        littleSizer.Add((5,0),0)
1370        for i in range(len(Arcs)):
1371            if Arcs[i]:
1372                tth,azimuth,thick = Arcs[i]
1373                arcText = wx.TextCtrl(parent=G2frame.dataDisplay,value=("%.3f" % (tth)),
1374                    style=wx.TE_READONLY)
1375                arcText.SetBackgroundColour(VERY_LIGHT_GREY)
1376                arcText.Bind(wx.EVT_ENTER_WINDOW,OnTextMsg)
1377                littleSizer.Add(arcText,0,WACV)
1378                azmText = wx.TextCtrl(parent=G2frame.dataDisplay,value=("%d,%d" % (azimuth[0],azimuth[1])),
1379                    style=wx.TE_READONLY)
1380                azmText.SetBackgroundColour(VERY_LIGHT_GREY)
1381                azmText.Bind(wx.EVT_ENTER_WINDOW,OnTextMsg)
1382                littleSizer.Add(azmText,0,WACV)
1383                arcThick = G2G.ValidatedTxtCtrl(G2frame.dataDisplay,loc=Arcs[i],key=2,
1384                                           min=0.001,max=20.,OnLeave=Replot,nDig=[8,3])
1385                littleSizer.Add(arcThick,0,WACV)
1386                arcDelete = G2G.G2LoggedButton(G2frame.dataDisplay,label='delete?',
1387                                            locationcode='Delete+Arcs+'+str(i),
1388                                            handler=onDeleteMask)
1389                littleSizer.Add(arcDelete,0,WACV)
1390        mainSizer.Add(littleSizer,0,)
1391    if Polygons:
1392        lbl = wx.StaticText(parent=G2frame.dataDisplay,
1393            label=' Polygon masks (on plot RB vertex drag to move,\nLB vertex drag to insert)')
1394        lbl.SetBackgroundColour(wx.Colour(200,200,210))
1395        mainSizer.Add(lbl,0,wx.EXPAND|wx.ALIGN_CENTER,0)
1396        littleSizer = wx.FlexGridSizer(0,2,0,5)
1397        for i in range(len(Polygons)):
1398            if Polygons[i]:
1399                polyList = []
1400                for x,y in Polygons[i]:
1401                    polyList.append("%.2f, %.2f"%(x,y))
1402                polyText = wx.ComboBox(G2frame.dataDisplay,value=polyList[0],choices=polyList,style=wx.CB_READONLY)
1403                littleSizer.Add(polyText,0,WACV)
1404                polyDelete = G2G.G2LoggedButton(G2frame.dataDisplay,label='delete?',
1405                                            locationcode='Delete+Polygons+'+str(i),
1406                                            handler=onDeleteMask)
1407                littleSizer.Add(polyDelete,0,WACV)
1408        mainSizer.Add(littleSizer,0,)
1409    if frame:
1410        lbl = wx.StaticText(parent=G2frame.dataDisplay,
1411            label=' Frame mask (on plot RB vertex drag to move,LB vertex drag to insert)')
1412        lbl.SetBackgroundColour(wx.Colour(200,200,210))
1413        mainSizer.Add(lbl,0,wx.EXPAND|wx.ALIGN_CENTER,0)
1414        littleSizer = wx.FlexGridSizer(0,2,0,5)
1415        frameList = []
1416        for x,y in frame:
1417            frameList.append("%.2f, %.2f"%(x,y))
1418        frameText = wx.ComboBox(G2frame.dataDisplay,value=frameList[0],choices=frameList,style=wx.CB_READONLY)
1419        littleSizer.Add(frameText,0,WACV)
1420        frameDelete = G2G.G2LoggedButton(G2frame.dataDisplay,label='delete?',
1421                                            locationcode='Delete+Frame',
1422                                            handler=onDeleteFrame)
1423        littleSizer.Add(frameDelete,0,WACV)
1424        mainSizer.Add(littleSizer,0,)
1425    mainSizer.Layout()   
1426    G2frame.dataDisplay.SetSizer(mainSizer)
1427    G2frame.dataDisplay.SetSize(mainSizer.Fit(G2frame.dataFrame))
1428    G2frame.dataDisplay.SetupScrolling()
1429    Size = mainSizer.Fit(G2frame.dataFrame)
1430    Size[0] += 50 # room for scrollbar & status msg
1431    Size[1] = min(Size[1],500)
1432    G2frame.dataDisplay.SetSize(Size)
1433    G2frame.dataFrame.setSizePosLeft(Size)   
1434    wx.Yield()
1435    if startScroll: # reset scroll to saved position
1436        G2frame.dataDisplay.Scroll(0,startScroll) # set to saved scroll position
1437        wx.Yield()
1438
1439################################################################################
1440##### Stress/Strain
1441################################################################################
1442
1443def UpdateStressStrain(G2frame,data):
1444    '''Shows and handles the controls on the "Stress/Strain"
1445    data tree entry
1446    '''
1447   
1448    def OnAppendDzero(event):
1449        data['d-zero'].append({'Dset':1.0,'Dcalc':0.0,'pixLimit':10,'cutoff':1.0,
1450            'ImxyObs':[[],[]],'ImtaObs':[[],[]],'ImtaCalc':[[],[]],'Emat':[1.0,1.0,1.0]})
1451        UpdateStressStrain(G2frame,data)
1452       
1453    def OnUpdateDzero(event):
1454        for item in data['d-zero']:
1455            if item['Dcalc']:   #skip unrefined ones
1456                item['Dset'] = item['Dcalc']
1457        UpdateStressStrain(G2frame,data)
1458           
1459    def OnCopyStrSta(event):
1460        TextList = [[False,'All IMG',0,0]]
1461        Names = []
1462        if G2frame.PatternTree.GetCount():
1463            id, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root)
1464            while id:
1465                name = G2frame.PatternTree.GetItemText(id)
1466                Names.append(name)
1467                if 'IMG' in name:
1468                    Data = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,id, 'Stress/Strain'))
1469                    if id == G2frame.Image:
1470                        Source = name
1471                    else:
1472                        TextList.append([False,name,id,Data.get('Sample load',0.0)])
1473                id, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie)
1474            if len(TextList) == 1:
1475                G2frame.ErrorDialog('Nothing to copy controls to','There must be more than one "IMG" pattern')
1476                return
1477            dlg = G2frame.CopyDialog(G2frame,'Copy stress/strain controls','Copy controls from '+Source+' to:',TextList)
1478            try:
1479                if dlg.ShowModal() == wx.ID_OK:
1480                    result = dlg.GetData()
1481                    if result[0][0]:
1482                        result = TextList[1:]
1483                        for item in result: item[0] = True
1484                    for i,item in enumerate(result):
1485                        ifcopy,name,id,load = item
1486                        if ifcopy:
1487                            Data = copy.deepcopy(data)
1488                            Data['Sample load'] = load
1489                            G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,id, 'Stress/Strain'),Data)
1490            finally:
1491                dlg.Destroy()
1492
1493    def OnLoadStrSta(event):
1494        dlg = wx.FileDialog(G2frame, 'Choose stress/strain file', '.', '', 
1495            'image control files (*.strsta)|*.strsta',wx.OPEN|wx.CHANGE_DIR)
1496        try:
1497            if dlg.ShowModal() == wx.ID_OK:
1498                filename = dlg.GetPath()
1499                File = open(filename,'r')
1500                S = File.read()
1501                data = eval(S)
1502                Controls = G2frame.PatternTree.GetItemPyData(
1503                    G2gd.GetPatternTreeItemId(G2frame,G2frame.Image, 'Image Controls'))
1504                G2img.FitStrSta(G2frame.ImageZ,data,Controls)
1505                UpdateStressStrain(G2frame,data)
1506                G2plt.PlotExposedImage(G2frame,event=event)
1507                G2plt.PlotStrain(G2frame,data,newPlot=True)
1508                File.close()
1509        finally:
1510            dlg.Destroy()
1511
1512    def OnSaveStrSta(event):
1513        dlg = wx.FileDialog(G2frame, 'Choose stress/strain file', '.', '', 
1514            'image control files (*.strsta)|*.strsta',wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT|wx.CHANGE_DIR)
1515        try:
1516            if dlg.ShowModal() == wx.ID_OK:
1517                filename = dlg.GetPath()
1518                File = open(filename,'w')
1519                save = {}
1520                keys = ['Type','Sample phi','Sample z','Sample load']
1521                keys2 = ['Dset','Dcalc','pixLimit','cutoff','Emat']
1522                File.write('{\n\t')
1523                for key in keys:
1524                    if key in 'Type':
1525                        File.write("'"+key+"':'"+data[key]+"',")
1526                    else:
1527                        File.write("'"+key+"':"+str(data[key])+',')
1528                File.write('\n\t'+"'d-zero':[\n")
1529                for data2 in data['d-zero']:
1530                    File.write('\t\t{')
1531                    for key in keys2:
1532                        File.write("'"+key+"':"+str(data2[key])+',')
1533                    File.write("'ImxyObs':[[],[]],'ImtaObs':[[],[]],'ImtaCalc':[[],[]]},\n")
1534                File.write('\t]\n}')
1535                File.close()
1536        finally:
1537            dlg.Destroy()
1538           
1539    def OnStrStaSample(event):
1540        filename = ''
1541        dlg = wx.FileDialog(G2frame, 'Choose multihistogram metadata text file', '.', '', 
1542            'metadata file (*.*)|*.*',wx.OPEN|wx.CHANGE_DIR)
1543        try:
1544            if dlg.ShowModal() == wx.ID_OK:
1545                filename = dlg.GetPath()
1546                File = open(filename,'r')
1547                S = File.readline()
1548                newItems = []
1549                itemNames = []
1550                Comments = []
1551                while S:
1552                    if S[0] == '#':
1553                        Comments.append(S)
1554                        S = File.readline()
1555                        continue
1556                    S = S.replace(',',' ').replace('\t',' ')
1557                    Stuff = S[:-1].split()
1558                    itemNames.append(Stuff[0])
1559                    newItems.append(Stuff[1:])
1560                    S = File.readline()               
1561                File.close()
1562        finally:
1563            dlg.Destroy()
1564        if not filename:
1565            G2frame.ErrorDialog('Nothing to do','No file selected')
1566            return
1567        dataDict = dict(zip(itemNames,newItems))
1568        ifany = False
1569        Names = [' ','Sample phi','Sample z','Sample load']
1570        dlg = G2G.G2ColumnIDDialog( G2frame,' Choose multihistogram metadata columns:',
1571            'Select columns',Comments,Names,np.array(newItems).T)
1572        try:
1573            if dlg.ShowModal() == wx.ID_OK:
1574                colNames,newData = dlg.GetSelection()
1575                dataDict = dict(zip(itemNames,newData.T))
1576                for item in colNames:
1577                    if item != ' ':
1578                        ifany = True
1579        finally:
1580            dlg.Destroy()
1581        if not ifany:
1582            G2frame.ErrorDialog('Nothing to do','No columns identified')
1583            return
1584        histList = []
1585        item, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root)       
1586        while item:
1587            name = G2frame.PatternTree.GetItemText(item)
1588            if name.startswith('IMG'):
1589                histList.append(name)
1590            item, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie)
1591        colIds = {}
1592        for i,name in enumerate(colNames):
1593            if name != ' ':
1594                colIds[name] = i
1595        for hist in histList:
1596            name = hist.split()[1]  #this is file name
1597            if name in dataDict:
1598                newItems = {}
1599                for item in colIds:
1600                    newItems[item] = float(dataDict[name][colIds[item]])
1601                Id = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,hist)
1602                stsrData = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,Id,'Stress/Strain'))
1603                stsrData.update(newItems)       
1604        UpdateStressStrain(G2frame,data)       
1605   
1606    def OnFitStrSta(event):
1607        Controls = G2frame.PatternTree.GetItemPyData(
1608            G2gd.GetPatternTreeItemId(G2frame,G2frame.Image, 'Image Controls'))
1609        G2img.FitStrSta(G2frame.ImageZ,data,Controls)
1610        print 'Strain fitting finished'
1611        UpdateStressStrain(G2frame,data)
1612        G2plt.PlotExposedImage(G2frame,event=event)
1613        G2plt.PlotStrain(G2frame,data,newPlot=True)
1614       
1615    def OnFitAllStrSta(event):
1616        TextList = [[False,'All IMG',0]]
1617        Names = []
1618        if G2frame.PatternTree.GetCount():
1619            choices = G2gd.GetPatternTreeDataNames(G2frame,['IMG ',])
1620            if len(choices) == 1:
1621                G2frame.ErrorDialog('Nothing to fit','There must some "IMG" patterns')
1622                return
1623            sel = []
1624            dlg = G2G.G2MultiChoiceDialog(G2frame,'Stress/Strain fitting','Select images to fit:',choices)
1625            dlg.SetSelections(sel)
1626            names = []
1627            if dlg.ShowModal() == wx.ID_OK:
1628                for sel in dlg.GetSelections():
1629                    names.append(choices[sel])
1630            dlg.Destroy()
1631            SeqResult = {}
1632            dlg = wx.ProgressDialog('Sequential IMG Strain fit','Data set name = '+names[0],len(names), 
1633                style = wx.PD_ELAPSED_TIME|wx.PD_AUTO_HIDE|wx.PD_REMAINING_TIME|wx.PD_CAN_ABORT)         
1634            wx.BeginBusyCursor()
1635            goodnames = []
1636            try:
1637                for i,name in enumerate(names):
1638                    print ' Sequential strain fit for ',name
1639                    GoOn = dlg.Update(i,newmsg='Data set name = '+name)[0]
1640                    if not GoOn:
1641                        break
1642                    Id =  G2gd.GetPatternTreeItemId(G2frame,G2frame.root,name)
1643                    Controls = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,Id, 'Image Controls'))
1644                    StaCtrls = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,Id, 'Stress/Strain'))
1645                    if not len(StaCtrls['d-zero']):
1646                        continue
1647                    goodnames.append(name)
1648                    id = G2gd.GetPatternTreeItemId(G2frame, G2frame.root, name)
1649                    Npix,imagefile,imagetag = G2frame.PatternTree.GetImageLoc(Id)
1650                    image = G2IO.GetImageData(G2frame,imagefile,True,ImageTag=imagetag)
1651                    dark = Controls['dark image']
1652                    if dark[0]:
1653                        id = G2gd.GetPatternTreeItemId(G2frame, G2frame.root,dark[0])
1654                        Npix,darkfile,imagetag = G2frame.PatternTree.GetImageLoc(id)
1655                        darkImg = G2IO.GetImageData(G2frame,darkfile,True,ImageTag=imagetag)
1656                        image += dark[1]*darkImg
1657                    G2img.FitStrSta(image,StaCtrls,Controls)
1658                    G2plt.PlotStrain(G2frame,StaCtrls,newPlot=True)
1659                    parmDict = {'Sample load':StaCtrls['Sample load'],}
1660                    varyNames = ['e11','e12','e22']
1661                    sig = []
1662                    varyList = []
1663                    variables = []
1664                    for i,item in enumerate(StaCtrls['d-zero']):
1665                        variables += item['Emat']
1666                        sig += item['Esig']
1667                        varylist = ['%d%s%s'%(i,';',Name) for Name in varyNames]
1668                        varyList += varylist
1669                        parmDict.update(dict(zip(varylist,item['Emat'])))
1670                        parmDict['%d:Dcalc'%(i)] = item['Dcalc']
1671                    SeqResult[name] = {'variables':variables,'varyList':varyList,'sig':sig,'Rvals':[],
1672                        'covMatrix':np.eye(len(variables)),'title':name,'parmDict':parmDict}
1673                else:
1674                    SeqResult['histNames'] = goodnames
1675                    dlg.Destroy()
1676                    print ' ***** Sequential strain refinement successful *****'
1677            finally:
1678                wx.EndBusyCursor()   
1679            Id =  G2gd.GetPatternTreeItemId(G2frame,G2frame.root,'Sequential results')
1680            if Id:
1681                G2frame.PatternTree.SetItemPyData(Id,SeqResult)
1682            else:
1683                Id = G2frame.PatternTree.AppendItem(parent=G2frame.root,text='Sequential results')
1684                G2frame.PatternTree.SetItemPyData(Id,SeqResult)
1685            G2frame.PatternTree.SelectItem(Id)
1686            print 'All images fitted'
1687       
1688    def SamSizer():
1689       
1690        def OnStrainType(event):
1691            data['Type'] = strType.GetValue()
1692       
1693        def OnSamPhi(event):
1694            try:
1695                value = float(samPhi.GetValue())
1696            except ValueError:
1697                value = data['Sample phi']
1698            data['Sample phi'] = value
1699            samPhi.SetValue("%.3f" % (data['Sample phi']))
1700               
1701        def OnSamZ(event):
1702            try:
1703                value = float(samZ.GetValue())
1704            except ValueError:
1705                value = data['Sample z']
1706            data['Sample z'] = value
1707            samZ.SetValue("%.3f" % (data['Sample z']))
1708               
1709        def OnSamLoad(event):
1710            try:
1711                value = float(samLoad.GetValue())
1712            except ValueError:
1713                value = data['Sample load']
1714            data['Sample load'] = value
1715            samLoad.SetValue("%.3f" % (data['Sample load']))
1716               
1717        samSizer = wx.BoxSizer(wx.HORIZONTAL)
1718        samSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,label=' Strain type: '),0,WACV)
1719        strType = wx.ComboBox(G2frame.dataDisplay,value=data['Type'],choices=['True','Conventional'],
1720            style=wx.CB_READONLY|wx.CB_DROPDOWN)
1721        strType.SetValue(data['Type'])
1722        strType.Bind(wx.EVT_COMBOBOX, OnStrainType)
1723        samSizer.Add(strType,0,WACV)
1724       
1725        samSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,label=' Sample phi: '),0,WACV)
1726        samPhi = wx.TextCtrl(G2frame.dataDisplay,-1,value=("%.3f" % (data['Sample phi'])),
1727            style=wx.TE_PROCESS_ENTER)
1728        samSizer.Add(samPhi,0,WACV)
1729        samPhi.Bind(wx.EVT_TEXT_ENTER,OnSamPhi)
1730        samPhi.Bind(wx.EVT_KILL_FOCUS,OnSamPhi)
1731        samSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,label=' Sample delta-z(mm): '),0,WACV)
1732        samZ = wx.TextCtrl(G2frame.dataDisplay,-1,value=("%.3f" % (data['Sample z'])),
1733            style=wx.TE_PROCESS_ENTER)
1734        samSizer.Add(samZ,0,WACV)
1735        samZ.Bind(wx.EVT_TEXT_ENTER,OnSamZ)
1736        samZ.Bind(wx.EVT_KILL_FOCUS,OnSamZ)
1737        samSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,label=' Sample load(MPa): '),0,WACV)
1738        samLoad = G2G.ValidatedTxtCtrl(G2frame.dataDisplay,data,'Sample load',
1739                nDig=[8,3],typeHint=float,)
1740        samSizer.Add(samLoad,0,WACV)
1741
1742        return samSizer
1743       
1744    def DzeroSizer():
1745   
1746        def OnDzero(event):
1747            Obj = event.GetEventObject()
1748            try:
1749                value = min(20.0,max(0.25,float(Obj.GetValue())))
1750            except ValueError:
1751                value = 1.0
1752            Obj.SetValue("%.5f"%(value))
1753            data['d-zero'][Indx[Obj.GetId()]]['Dset'] = value
1754            data['d-zero'] = G2mth.sortArray(data['d-zero'],'Dset',reverse=True)
1755            Ring,R = G2img.MakeStrStaRing(data['d-zero'][Indx[Obj.GetId()]],G2frame.ImageZ,Controls)
1756            if len(Ring):
1757                data['d-zero'][Indx[Obj.GetId()]].update(R)
1758            else:
1759                G2frame.ErrorDialog('Strain peak selection','WARNING - No points found for this ring selection')
1760               
1761            UpdateStressStrain(G2frame,data)
1762            G2plt.PlotExposedImage(G2frame,event=event,newPlot=False)
1763            G2plt.PlotStrain(G2frame,data,newPlot=True)
1764           
1765        def OnDeleteDzero(event):
1766            Obj = event.GetEventObject()
1767            del(data['d-zero'][delIndx.index(Obj)])
1768            UpdateStressStrain(G2frame,data)
1769            G2plt.PlotExposedImage(G2frame,event=event,newPlot=True)
1770            G2plt.PlotStrain(G2frame,data,newPlot=True)
1771       
1772        def OnCutOff(event):
1773            Obj = event.GetEventObject()
1774            try:
1775                value = min(10.0,max(0.5,float(Obj.GetValue())))
1776            except ValueError:
1777                value = 1.0
1778            Obj.SetValue("%.1f"%(value))
1779            data['d-zero'][Indx[Obj.GetId()]]['cutoff'] = value
1780            Ring,R = G2img.MakeStrStaRing(data['d-zero'][Indx[Obj.GetId()]],G2frame.ImageZ,Controls)
1781            G2plt.PlotExposedImage(G2frame,event=event)
1782            G2plt.PlotStrain(G2frame,data,newPlot=True)
1783       
1784        def OnPixLimit(event):
1785            Obj = event.GetEventObject()
1786            data['d-zero'][Indx[Obj.GetId()]]['pixLimit'] = int(Obj.GetValue())
1787            Ring,R = G2img.MakeStrStaRing(data['d-zero'][Indx[Obj.GetId()]],G2frame.ImageZ,Controls)
1788            G2plt.PlotExposedImage(G2frame,event=event)
1789            G2plt.PlotStrain(G2frame,data,newPlot=True)
1790           
1791        Indx = {}
1792        delIndx = []   
1793        dzeroSizer = wx.FlexGridSizer(0,8,5,5)
1794        for id,dzero in enumerate(data['d-zero']):
1795            dzeroSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,label=(' d-zero #%d: '%(id))),0,WACV)
1796            dZero = wx.TextCtrl(G2frame.dataDisplay,-1,value=('%.5f'%(dzero['Dset'])),
1797                style=wx.TE_PROCESS_ENTER)
1798            dzeroSizer.Add(dZero,0,WACV)
1799            dZero.Bind(wx.EVT_TEXT_ENTER,OnDzero)
1800            dZero.Bind(wx.EVT_KILL_FOCUS,OnDzero)
1801            Indx[dZero.GetId()] = id
1802            dzeroSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,label=(' d-zero ave: %.5f'%(dzero['Dcalc']))),0,WACV)
1803               
1804            dzeroSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Min ring I/Ib '),0,WACV)
1805            cutOff = wx.TextCtrl(parent=G2frame.dataDisplay,value=("%.1f" % (dzero['cutoff'])),
1806                style=wx.TE_PROCESS_ENTER)
1807            cutOff.Bind(wx.EVT_TEXT_ENTER,OnCutOff)
1808            cutOff.Bind(wx.EVT_KILL_FOCUS,OnCutOff)
1809            Indx[cutOff.GetId()] = id
1810            dzeroSizer.Add(cutOff,0,WACV)
1811       
1812            dzeroSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Pixel search range '),0,WACV)
1813            pixLimit = wx.ComboBox(parent=G2frame.dataDisplay,value=str(dzero['pixLimit']),choices=['1','2','5','10','15','20'],
1814                style=wx.CB_READONLY|wx.CB_DROPDOWN)
1815            pixLimit.Bind(wx.EVT_COMBOBOX, OnPixLimit)
1816            Indx[pixLimit.GetId()] = id
1817            dzeroSizer.Add(pixLimit,0,WACV)               
1818               
1819            dzeroDelete = wx.CheckBox(parent=G2frame.dataDisplay,label='delete?')
1820            dzeroDelete.Bind(wx.EVT_CHECKBOX,OnDeleteDzero)
1821            delIndx.append(dzeroDelete)
1822            dzeroSizer.Add(dzeroDelete,0,WACV)
1823           
1824            dzeroSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,label=(' Strain tensor:')),WACV)
1825            names = ['e11','e12','e22']
1826            for i in range(3):
1827                dzeroSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,label=names[i]),0,WACV)
1828                tensorElem = wx.TextCtrl(G2frame.dataDisplay,-1,value='%.2f'%(dzero['Emat'][i]),style=wx.TE_READONLY)
1829                tensorElem.SetBackgroundColour(VERY_LIGHT_GREY)
1830                dzeroSizer.Add(tensorElem,0,WACV)
1831            dzeroSizer.Add((5,5),0)             
1832        return dzeroSizer
1833       
1834# patches
1835    if 'Sample load' not in data:
1836        data['Sample load'] = 0.0
1837# end patches
1838   
1839    if G2frame.dataDisplay:
1840        G2frame.dataDisplay.Destroy()
1841    Controls = G2frame.PatternTree.GetItemPyData(
1842        G2gd.GetPatternTreeItemId(G2frame,G2frame.Image, 'Image Controls'))       
1843    G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.StrStaMenu)
1844    G2frame.dataFrame.Bind(wx.EVT_MENU, OnAppendDzero, id=G2gd.wxID_APPENDDZERO)
1845    G2frame.dataFrame.Bind(wx.EVT_MENU, OnUpdateDzero, id=G2gd.wxID_UPDATEDZERO)
1846    G2frame.dataFrame.Bind(wx.EVT_MENU, OnFitStrSta, id=G2gd.wxID_STRSTAFIT)
1847    G2frame.dataFrame.Bind(wx.EVT_MENU, OnFitAllStrSta, id=G2gd.wxID_STRSTAALLFIT)
1848    G2frame.dataFrame.Bind(wx.EVT_MENU, OnCopyStrSta, id=G2gd.wxID_STRSTACOPY)
1849    G2frame.dataFrame.Bind(wx.EVT_MENU, OnLoadStrSta, id=G2gd.wxID_STRSTALOAD)
1850    G2frame.dataFrame.Bind(wx.EVT_MENU, OnSaveStrSta, id=G2gd.wxID_STRSTASAVE)
1851    G2frame.dataFrame.Bind(wx.EVT_MENU, OnStrStaSample, id=G2gd.wxID_STRSTSAMPLE)       
1852    if not G2frame.dataFrame.GetStatusBar():
1853        Status = G2frame.dataFrame.CreateStatusBar()
1854    if G2frame.StrainKey == 'a':    #probably doesn't happen
1855        G2frame.dataFrame.GetStatusBar().SetStatusText('Add strain ring active - LB pick d-zero value')
1856    else:
1857        G2frame.dataFrame.GetStatusBar().SetStatusText("To add strain data: On 2D Powder Image, key a:add ring")
1858       
1859    G2frame.dataDisplay = wxscroll.ScrolledPanel(G2frame.dataFrame)
1860    mainSizer = wx.BoxSizer(wx.VERTICAL)
1861    mainSizer.Add((5,10),0)
1862    mainSizer.Add(SamSizer())
1863    mainSizer.Add((5,10),0)
1864    mainSizer.Add(DzeroSizer())
1865   
1866    mainSizer.Layout()   
1867    G2frame.dataDisplay.SetSizer(mainSizer)
1868    G2frame.dataDisplay.SetAutoLayout(1)
1869    G2frame.dataDisplay.SetupScrolling()
1870    Size = mainSizer.Fit(G2frame.dataFrame)
1871    Size[0] += 25
1872    G2frame.dataDisplay.SetSize(Size)
1873    G2frame.dataFrame.setSizePosLeft(Size)   
Note: See TracBrowser for help on using the repository browser.