source: trunk/GSASIIimgGUI.py @ 1762

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

fix exports of reflection csv & txt files to work for CW & TOF data as well as
3 & (3+1) symmetries
fix Det-X --> Det-Y
remove a Yield - caused crash
fix c-unique & a-unique monoclinit cell refinement & display
fix cif readers for phase

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