source: trunk/GSASIIimgGUI.py @ 1763

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

new item in imgGUI - Flat Bkg; subtracted from image on display & integration

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