source: trunk/GSASIIimgGUI.py @ 1619

Last change on this file since 1619 was 1619, checked in by toby, 7 years ago

add columnsorter for hetrogeneous seq ref; reorg to start moving widgets out of g2grid

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