source: trunk/GSASIIimgGUI.py @ 697

Last change on this file since 697 was 697, checked in by vondreele, 10 years ago

add ranId to PWDR histograms & each PhaseSelector?
implement 'Use' for every histogram & restraint
remove OnPwdrRead? dead code from GSASII.py
implement stress/strain GUI stuff
implement a clear map menu item
remove getBackupName2 dead code from GSASIIstruct.py

  • Property svn:keywords set to Date Author Revision URL Id
File size: 61.6 KB
Line 
1# -*- coding: utf-8 -*-
2#GSASII - image data display routines
3########### SVN repository information ###################
4# $Date: 2012-08-03 18:34:38 +0000 (Fri, 03 Aug 2012) $
5# $Author: vondreele $
6# $Revision: 697 $
7# $URL: trunk/GSASIIimgGUI.py $
8# $Id: GSASIIimgGUI.py 697 2012-08-03 18:34:38Z vondreele $
9########### SVN repository information ###################
10import wx
11import matplotlib as mpl
12import math
13import time
14import copy
15import cPickle
16import GSASIIpath
17GSASIIpath.SetVersionNumber("$Revision: 697 $")
18import GSASIIimage as G2img
19import GSASIIplot as G2plt
20import GSASIIIO as G2IO
21import GSASIIgrid as G2gd
22import numpy as np
23
24VERY_LIGHT_GREY = wx.Colour(235,235,235)
25
26# trig functions in degrees
27sind = lambda x: math.sin(x*math.pi/180.)
28tand = lambda x: math.tan(x*math.pi/180.)
29cosd = lambda x: math.cos(x*math.pi/180.)
30asind = lambda x: 180.*math.asin(x)/math.pi
31
32################################################################################
33##### Image Controls
34################################################################################                   
35def UpdateImageControls(G2frame,data,masks):
36    import ImageCalibrants as calFile
37   
38# Menu items
39           
40    def OnCalibrate(event):       
41        G2frame.dataFrame.ImageEdit.Enable(id=G2gd.wxID_IMRECALIBRATE,enable=True)   
42        G2frame.dataFrame.GetStatusBar().SetStatusText('Select > 4 points on 1st used ring; LB to pick, RB on point to delete else RB to finish')
43        G2frame.ifGetRing = True
44       
45    def OnRecalibrate(event):
46        G2img.ImageRecalibrate(G2frame,data)
47        UpdateImageControls(G2frame,data,masks)
48       
49    def OnClearCalib(event):
50        data['ring'] = []
51        data['rings'] = []
52        data['ellipses'] = []
53#        G2frame.dataFrame.ImageEdit.Enable(id=G2gd.wxID_IMRECALIBRATE,enable=False)   
54        G2plt.PlotExposedImage(G2frame,event=event)
55           
56    def OnIntegrate(event):
57       
58        if data['background image'][0]:
59            maskCopy = copy.deepcopy(masks)
60            backImg = data['background image'][0]
61            backScale = data['background image'][1]
62            id = G2gd.GetPatternTreeItemId(G2frame, G2frame.root, backImg)
63            Npix,imagefile = G2frame.PatternTree.GetItemPyData(id)
64            backImage = G2IO.GetImageData(G2frame,imagefile,True)*backScale
65            sumImage = G2frame.ImageZ+backImage
66            sumMin = np.min(sumImage)
67            sumMax = np.max(sumImage)
68            maskCopy['Thresholds'] = [(sumMin,sumMax),[sumMin,sumMax]]
69            G2frame.Integrate = G2img.ImageIntegrate(sumImage,data,maskCopy)
70        else:
71            G2frame.Integrate = G2img.ImageIntegrate(G2frame.ImageZ,data,masks)
72        G2plt.PlotIntegration(G2frame,newPlot=True)
73        G2IO.SaveIntegration(G2frame,G2frame.PickId,data)
74        G2frame.MakePDF.Enable(True)
75       
76    def OnIntegrateAll(event):
77        print 'integrate all'
78        TextList = [[False,'All IMG',0]]
79        Names = []
80        if G2frame.PatternTree.GetCount():
81            id, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root)
82            while id:
83                name = G2frame.PatternTree.GetItemText(id)
84                Names.append(name)
85                if 'IMG' in name:
86                    TextList.append([False,name,id])
87                id, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie)
88            if len(TextList) == 1:
89                G2frame.ErrorDialog('Nothing to integrate','There must some "IMG" patterns')
90                return
91            dlg = G2frame.CopyDialog(G2frame,'Image integration controls','Select images to integrate:',TextList)
92            try:
93                if dlg.ShowModal() == wx.ID_OK:
94                    result = dlg.GetData()
95                    if result[0][0]:                    #the 'All IMG' is True
96                        result = TextList[1:]
97                        for item in result: item[0] = True
98                    for item in result:
99                        ifintegrate,name,id = item
100                        if ifintegrate:
101                            id = G2gd.GetPatternTreeItemId(G2frame, G2frame.root, name)
102                            Npix,imagefile = G2frame.PatternTree.GetItemPyData(id)
103                            image = G2IO.GetImageData(G2frame,imagefile,True)
104                            Id = G2gd.GetPatternTreeItemId(G2frame,id, 'Image Controls')
105                            Data = G2frame.PatternTree.GetItemPyData(Id)
106                            backImage = []
107                            if Data['background image'][0]:
108                                backImg = Data['background image'][0]
109                                backScale = Data['background image'][1]
110                                id = G2gd.GetPatternTreeItemId(G2frame, G2frame.root, backImg)
111                                Npix,imagefile = G2frame.PatternTree.GetItemPyData(id)
112                                backImage = G2IO.GetImageData(G2frame,imagefile,True)*backScale
113                            try:
114                                Masks = G2frame.PatternTree.GetItemPyData(
115                                    G2gd.GetPatternTreeItemId(G2frame,G2frame.Image, 'Masks'))
116                            except TypeError:       #missing Masks
117                                Imin,Imax = Data['Range']
118                                Masks = {'Points':[],'Rings':[],'Arcs':[],'Polygons':[],'Thresholds':[(Imin,Imax),[Imin,Imax]]}
119                                G2frame.PatternTree.SetItemPyData(
120                                    G2gd.GetPatternTreeItemId(G2frame,G2frame.Image, 'Masks'),Masks)
121                            if len(backImage):                               
122                                G2frame.Integrate = G2img.ImageIntegrate(image+backImage,Data,Masks)
123                            else:
124                                G2frame.Integrate = G2img.ImageIntegrate(image,Data,Masks)
125#                            G2plt.PlotIntegration(G2frame,newPlot=True,event=event)
126                            G2IO.SaveIntegration(G2frame,Id,Data)
127            finally:
128                dlg.Destroy()
129       
130    def OnCopyControls(event):
131        import copy
132        TextList = [[False,'All IMG',0]]
133        Names = []
134        if G2frame.PatternTree.GetCount():
135            id, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root)
136            while id:
137                name = G2frame.PatternTree.GetItemText(id)
138                Names.append(name)
139                if 'IMG' in name:
140                    if id == G2frame.Image:
141                        Source = name
142                        Data = copy.deepcopy(G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,id, 'Image Controls')))
143                        Data['showLines'] = True
144                        Data['ring'] = []
145                        Data['rings'] = []
146                        Data['ellipses'] = []
147                        Data['setDefault'] = False
148                    else:
149                        TextList.append([False,name,id])
150                id, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie)
151            if len(TextList) == 1:
152                G2frame.ErrorDialog('Nothing to copy controls to','There must be more than one "IMG" pattern')
153                return
154            dlg = G2frame.CopyDialog(G2frame,'Copy image controls','Copy controls from '+Source+' to:',TextList)
155            try:
156                if dlg.ShowModal() == wx.ID_OK:
157                    result = dlg.GetData()
158                    if result[0][0]:
159                        result = TextList[1:]
160                        for item in result: item[0] = True
161                    for i,item in enumerate(result):
162                        ifcopy,name,id = item
163                        if ifcopy:
164                            oldData = copy.deepcopy(G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,id, 'Image Controls')))
165                            Data['range'] = oldData['range']
166                            Data['size'] = oldData['size']                               
167                            Data['ring'] = []
168                            Data['rings'] = []
169                            Data['ellipses'] = []
170                            G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,id, 'Image Controls'),copy.deepcopy(Data))
171            finally:
172                dlg.Destroy()
173               
174    def OnSaveControls(event):
175        dlg = wx.FileDialog(G2frame, 'Choose image controls file', '.', '', 
176            'image control files (*.imctrl)|*.imctrl',wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT|wx.CHANGE_DIR)
177        try:
178            if dlg.ShowModal() == wx.ID_OK:
179                filename = dlg.GetPath()
180                File = open(filename,'w')
181                save = {}
182                keys = ['type','wavelength','calibrant','distance','center',
183                    'tilt','rotation','azmthOff','fullIntegrate','LRazimuth',
184                    'IOtth','outAzimuths']
185                for key in keys:
186                    if key in ['rotation']:
187                        File.write(key+':'+str(data[key]-90.)+'\n')                       
188                    else:
189                        File.write(key+':'+str(data[key])+'\n')
190                File.close()
191        finally:
192            dlg.Destroy()
193       
194    def OnLoadControls(event):
195        cntlList = ['wavelength','distance','tilt','rotation',
196            'fullIntegrate','outAzimuths','LRazimuth','IOtth']
197        dlg = wx.FileDialog(G2frame, 'Choose image controls file', '.', '', 
198            'image control files (*.imctrl)|*.imctrl',wx.OPEN|wx.CHANGE_DIR)
199        try:
200            if dlg.ShowModal() == wx.ID_OK:
201                filename = dlg.GetPath()
202                File = open(filename,'r')
203                save = {}
204                S = File.readline()
205                while S:
206                    if S[0] == '#':
207                        S = File.readline()
208                        continue
209                    [key,val] = S[:-1].split(':')
210                    if key in ['type','calibrant',]:
211                        save[key] = val
212                    elif key in ['rotation']:
213                        save[key] = float(val)+90.
214                    elif key in ['center',]:
215                        if ',' in val:
216                            save[key] = eval(val)
217                        else:
218                            vals = val.strip('[] ').split()
219                            save[key] = [float(vals[0]),float(vals[1])] 
220                    elif key in cntlList:
221                        save[key] = eval(val)
222                    S = File.readline()
223                data.update(save)
224                UpdateImageControls(G2frame,data,masks)
225                G2plt.PlotExposedImage(G2frame,event=event)
226               
227                File.close()
228        finally:
229            dlg.Destroy()
230           
231# Sizers
232                                       
233    def ComboSizer():
234
235        def OnDataType(event):
236            data['type'] = typeSel.GetValue()[:4]
237   
238        def OnNewColorBar(event):
239            data['color'] = colSel.GetValue()
240            G2plt.PlotExposedImage(G2frame,event=event)
241       
242        def OnAzmthOff(event):
243            try:
244                azmthoff = float(azmthOff.GetValue())
245                data['azmthOff'] = azmthoff
246            except ValueError:
247                pass
248            azmthOff.SetValue("%.2f"%(data['azmthOff']))          #reset in case of error 
249       
250        comboSizer = wx.BoxSizer(wx.HORIZONTAL)
251        comboSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Type of image data: '),0,
252            wx.ALIGN_CENTER_VERTICAL)
253        typeSel = wx.ComboBox(parent=G2frame.dataDisplay,value=typeDict[data['type']],choices=typeList,
254            style=wx.CB_READONLY|wx.CB_DROPDOWN)
255        typeSel.SetValue(data['type'])
256        typeSel.Bind(wx.EVT_COMBOBOX, OnDataType)
257        comboSizer.Add(typeSel,0,wx.ALIGN_CENTER_VERTICAL)
258        comboSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Color bar '),0,
259            wx.ALIGN_CENTER_VERTICAL)
260        colSel = wx.ComboBox(parent=G2frame.dataDisplay,value=data['color'],choices=colorList,
261            style=wx.CB_READONLY|wx.CB_DROPDOWN|wx.CB_SORT)
262        colSel.Bind(wx.EVT_COMBOBOX, OnNewColorBar)
263        comboSizer.Add(colSel,0,wx.ALIGN_CENTER_VERTICAL)
264        comboSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Azimuth offset '),0,
265            wx.ALIGN_CENTER_VERTICAL)
266        azmthOff = wx.TextCtrl(parent=G2frame.dataDisplay,value=("%.2f" % (data['azmthOff'])),
267            style=wx.TE_PROCESS_ENTER)
268        azmthOff.Bind(wx.EVT_TEXT_ENTER,OnAzmthOff)
269        azmthOff.Bind(wx.EVT_KILL_FOCUS,OnAzmthOff)
270        comboSizer.Add(azmthOff,0,wx.ALIGN_CENTER_VERTICAL)
271        return comboSizer
272       
273    def MaxSizer():
274               
275        def OnMaxVal(event):
276            try:
277                value = min(data['range'][0][1],int(maxVal.GetValue()))
278                if value < data['range'][1][0]+1:
279                    raise ValueError
280                data['range'][1][1] = value
281            except ValueError:
282                pass
283            maxVal.SetValue('%.0f'%(data['range'][1][1]))
284            DeltOne = data['range'][1][1]-max(0.0,data['range'][0][0])
285            sqrtDeltOne = math.sqrt(DeltOne)
286            maxSel.SetValue(int(100*sqrtDeltOne/sqrtDeltZero))
287            minSel.SetValue(int(100*(data['range'][1][0]/DeltOne)))
288            G2plt.PlotExposedImage(G2frame,event=event)
289           
290        def OnMinVal(event):
291            try:
292                value = int(minVal.GetValue())
293                if value > data['range'][1][1]-1:
294                    raise ValueError
295                data['range'][1][0] = value
296            except ValueError:
297                pass
298            minVal.SetValue('%.0f'%(data['range'][1][0]))
299            minSel.SetValue(int(100*(data['range'][1][0]-max(0.0,data['range'][0][0]))/DeltOne))
300            G2plt.PlotExposedImage(G2frame,event=event)
301           
302        def OnMaxSlider(event):
303            sqrtDeltZero = math.sqrt(data['range'][0][1])
304            imax = int(maxSel.GetValue())*sqrtDeltZero/100.
305            data['range'][1][1] = imax**2
306            data['range'][1][0] = max(0.0,min(data['range'][1][1]-1,data['range'][1][0]))
307            DeltOne = max(1.0,data['range'][1][1]-data['range'][1][0])
308            minSel.SetValue(int(100*(data['range'][1][0]/DeltOne)))
309            maxVal.SetValue('%.0f'%(data['range'][1][1]))
310            G2plt.PlotExposedImage(G2frame,event=event)
311           
312        def OnMinSlider(event):
313            DeltOne = data['range'][1][1]-data['range'][1][0]
314            imin = int(minSel.GetValue())*DeltOne/100.
315            data['range'][1][0] = max(0.0,min(data['range'][1][1]-1,imin))
316            minVal.SetValue('%.0f'%(data['range'][1][0]))
317            G2plt.PlotExposedImage(G2frame,event=event)
318           
319        maxSizer = wx.FlexGridSizer(2,3,0,5)
320        maxSizer.AddGrowableCol(1,1)
321        maxSizer.SetFlexibleDirection(wx.HORIZONTAL)
322        sqrtDeltZero = math.sqrt(data['range'][0][1]-max(0.0,data['range'][0][0]))
323        DeltOne = data['range'][1][1]-max(0.0,data['range'][0][0])
324        sqrtDeltOne = math.sqrt(DeltOne)
325        maxSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Max intensity'),0,
326            wx.ALIGN_CENTER_VERTICAL)
327        maxSel = wx.Slider(parent=G2frame.dataDisplay,style=wx.SL_HORIZONTAL,
328            value=int(100*sqrtDeltOne/sqrtDeltZero))
329        maxSizer.Add(maxSel,1,wx.EXPAND)
330        maxSel.Bind(wx.EVT_SLIDER, OnMaxSlider)
331        maxVal = wx.TextCtrl(parent=G2frame.dataDisplay,value='%.0f'%(data['range'][1][1]))
332        maxVal.Bind(wx.EVT_TEXT_ENTER,OnMaxVal)   
333        maxVal.Bind(wx.EVT_KILL_FOCUS,OnMaxVal)
334        maxSizer.Add(maxVal,0,wx.ALIGN_CENTER_VERTICAL)   
335        maxSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Min intensity'),0,
336            wx.ALIGN_CENTER_VERTICAL)
337        minSel = wx.Slider(parent=G2frame.dataDisplay,style=wx.SL_HORIZONTAL,
338            value=int(100*(data['range'][1][0]-max(0.0,data['range'][0][0]))/DeltOne))
339        maxSizer.Add(minSel,1,wx.EXPAND)
340        minSel.Bind(wx.EVT_SLIDER, OnMinSlider)
341        minVal = wx.TextCtrl(parent=G2frame.dataDisplay,value='%.0f'%(data['range'][1][0]))
342        minVal.Bind(wx.EVT_TEXT_ENTER,OnMinVal)   
343        minVal.Bind(wx.EVT_KILL_FOCUS,OnMinVal)
344        maxSizer.Add(minVal,0,wx.ALIGN_CENTER_VERTICAL)
345        return maxSizer
346       
347    def CalibCoeffSizer():
348       
349        def OnWavelength(event):
350            try:
351                wave = float(waveSel.GetValue())
352                if wave < .01:
353                    raise ValueError
354                data['wavelength'] = wave
355            except ValueError:
356                pass
357            waveSel.SetValue("%6.5f" % (data['wavelength']))          #reset in case of error         
358           
359        calibSizer = wx.FlexGridSizer(5,2,5,5)
360        calibSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Calibration coefficients'),0,
361            wx.ALIGN_CENTER_VERTICAL)   
362        calibSizer.Add((5,0),0)       
363        calibSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Beam center X,Y'),0,
364            wx.ALIGN_CENTER_VERTICAL)
365        cent = data['center']
366        centText = wx.TextCtrl(parent=G2frame.dataDisplay,value=("%8.3f,%8.3f" % (cent[0],cent[1])),style=wx.TE_READONLY)
367        centText.SetBackgroundColour(VERY_LIGHT_GREY)
368        calibSizer.Add(centText,0,wx.ALIGN_CENTER_VERTICAL)       
369        calibSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Wavelength'),0,
370            wx.ALIGN_CENTER_VERTICAL)
371        waveSel = wx.TextCtrl(parent=G2frame.dataDisplay,value=("%6.5f" % (data['wavelength'])),
372            style=wx.TE_PROCESS_ENTER)
373        waveSel.Bind(wx.EVT_TEXT_ENTER,OnWavelength)
374        waveSel.Bind(wx.EVT_KILL_FOCUS,OnWavelength)
375        calibSizer.Add(waveSel,0,wx.ALIGN_CENTER_VERTICAL)             
376        calibSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Distance'),0,
377            wx.ALIGN_CENTER_VERTICAL)
378        distSel = wx.TextCtrl(parent=G2frame.dataDisplay,value=("%8.3f"%(data['distance'])),style=wx.TE_READONLY)
379        distSel.SetBackgroundColour(VERY_LIGHT_GREY)
380        calibSizer.Add(distSel,0,wx.ALIGN_CENTER_VERTICAL)
381        calibSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Tilt angle'),0,
382            wx.ALIGN_CENTER_VERTICAL)
383        tiltSel = wx.TextCtrl(parent=G2frame.dataDisplay,value=("%9.3f"%(data['tilt'])),style=wx.TE_READONLY)
384        tiltSel.SetBackgroundColour(VERY_LIGHT_GREY)
385        calibSizer.Add(tiltSel,0,wx.ALIGN_CENTER_VERTICAL)
386        calibSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Tilt rotation'),0,
387            wx.ALIGN_CENTER_VERTICAL)
388        rotSel = wx.TextCtrl(parent=G2frame.dataDisplay,value=("%9.3f"%(data['rotation']-90.)),style=wx.TE_READONLY) #kluge to get rotation from vertical - see GSASIIimage
389        rotSel.SetBackgroundColour(VERY_LIGHT_GREY)
390        calibSizer.Add(rotSel,0,wx.ALIGN_CENTER_VERTICAL)
391        return calibSizer
392   
393    def IntegrateSizer():
394       
395        def OnIOtth(event):
396            Ltth = max(float(G2frame.InnerTth.GetValue()),0.001)
397            Utth = float(G2frame.OuterTth.GetValue())
398            if Ltth > Utth:
399                Ltth,Utth = Utth,Ltth
400            data['IOtth'] = [Ltth,Utth]
401            G2frame.InnerTth.SetValue("%8.3f" % (Ltth))
402            G2frame.OuterTth.SetValue("%8.2f" % (Utth))
403            G2plt.PlotExposedImage(G2frame,event=event)
404       
405        def OnLRazim(event):
406            Lazm =int(G2frame.Lazim.GetValue())
407            if data['fullIntegrate']:
408               G2frame.Razim.SetValue("%6d" % (Lazm+360))
409            Razm = int(G2frame.Razim.GetValue())
410            if Lazm > Razm:
411                Lazm -= 360
412            data['LRazimuth'] = [Lazm,Razm]
413            G2plt.PlotExposedImage(G2frame,event=event)
414       
415        def OnNumOutChans(event):
416            try:
417                numChans = int(outChan.GetValue())
418                if numChans < 1:
419                    raise ValueError
420                data['outChannels'] = numChans
421            except ValueError:
422                pass
423            outChan.SetValue(str(data['outChannels']))          #reset in case of error       
424       
425        def OnNumOutAzms(event):
426            try:
427                numAzms = int(outAzim.GetValue())
428                if numAzms < 1:
429                    raise ValueError
430                data['outAzimuths'] = numAzms           
431            except ValueError:
432                pass
433            outAzim.SetValue(str(data['outAzimuths']))          #reset in case of error       
434            G2plt.PlotExposedImage(G2frame,event=event)
435       
436        def OnOblique(event):
437            if data['Oblique'][1]:
438                data['Oblique'][1] = False
439            else:
440                data['Oblique'][1] = True
441               
442        def OnObliqVal(event):
443            try:
444                value = float(obliqVal.GetValue())
445                if 0.01 <= value <= 0.99:
446                    data['Oblique'][0] = value
447                else:
448                    raise ValueError
449            except ValueError:
450                pass
451            obliqVal.SetValue('%.3f'%(data['Oblique'][0]))
452                           
453        def OnShowLines(event):
454            if data['showLines']:
455                data['showLines'] = False
456            else:
457                data['showLines'] = True
458            G2plt.PlotExposedImage(G2frame,event=event)
459           
460        def OnFullIntegrate(event):
461            Lazm =int(G2frame.Lazim.GetValue())
462            if data['fullIntegrate']:
463                data['fullIntegrate'] = False
464                data['LRazimuth'] = [Lazm,Lazm+20]
465            else:
466                data['fullIntegrate'] = True
467                data['LRazimuth'] = [Lazm,Lazm+360]
468            UpdateImageControls(G2frame,data,masks)
469            G2plt.PlotExposedImage(G2frame,event=event)
470           
471        def OnSetDefault(event):
472            import copy
473            if data['setDefault']:
474                G2frame.imageDefault = {}
475                data['setDefault'] = False
476            else:
477                G2frame.imageDefault = copy.copy(data)
478                data['setDefault'] = True
479               
480        def OnCenterAzm(event):
481            if data['centerAzm']:
482                data['centerAzm'] = False
483            else:
484                data['centerAzm'] = True
485            G2plt.PlotExposedImage(G2frame,event=event)
486               
487        dataSizer = wx.FlexGridSizer(5,2,5,5)
488        dataSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Integration coefficients'),0,
489            wx.ALIGN_CENTER_VERTICAL)   
490        dataSizer.Add((5,0),0)
491        dataSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Inner/Outer 2-theta'),0,
492            wx.ALIGN_CENTER_VERTICAL)
493           
494        IOtth = data['IOtth']
495        littleSizer = wx.BoxSizer(wx.HORIZONTAL)
496        G2frame.InnerTth = wx.TextCtrl(parent=G2frame.dataDisplay,
497            value=("%8.3f" % (IOtth[0])),style=wx.TE_PROCESS_ENTER)
498        G2frame.InnerTth.Bind(wx.EVT_TEXT_ENTER,OnIOtth)
499        G2frame.InnerTth.Bind(wx.EVT_KILL_FOCUS,OnIOtth)
500        littleSizer.Add(G2frame.InnerTth,0,wx.ALIGN_CENTER_VERTICAL)
501        G2frame.OuterTth = wx.TextCtrl(parent=G2frame.dataDisplay,
502            value=("%8.2f" % (IOtth[1])),style=wx.TE_PROCESS_ENTER)
503        G2frame.OuterTth.Bind(wx.EVT_TEXT_ENTER,OnIOtth)
504        G2frame.OuterTth.Bind(wx.EVT_KILL_FOCUS,OnIOtth)
505        littleSizer.Add(G2frame.OuterTth,0,wx.ALIGN_CENTER_VERTICAL)
506        dataSizer.Add(littleSizer,0,)
507        dataSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Start/End azimuth'),0,
508            wx.ALIGN_CENTER_VERTICAL)
509        LRazim = data['LRazimuth']
510        littleSizer = wx.BoxSizer(wx.HORIZONTAL)
511        G2frame.Lazim = wx.TextCtrl(parent=G2frame.dataDisplay,
512            value=("%6d" % (LRazim[0])),style=wx.TE_PROCESS_ENTER)
513        G2frame.Lazim.Bind(wx.EVT_TEXT_ENTER,OnLRazim)
514        G2frame.Lazim.Bind(wx.EVT_KILL_FOCUS,OnLRazim)
515        littleSizer.Add(G2frame.Lazim,0,wx.ALIGN_CENTER_VERTICAL)
516        G2frame.Razim = wx.TextCtrl(parent=G2frame.dataDisplay,
517            value=("%6d" % (LRazim[1])),style=wx.TE_PROCESS_ENTER)
518        G2frame.Razim.Bind(wx.EVT_TEXT_ENTER,OnLRazim)
519        G2frame.Razim.Bind(wx.EVT_KILL_FOCUS,OnLRazim)
520        if data['fullIntegrate']:
521            G2frame.Razim.Enable(False)
522            G2frame.Razim.SetBackgroundColour(VERY_LIGHT_GREY)
523            G2frame.Razim.SetValue("%6d" % (LRazim[0]+360))
524        littleSizer.Add(G2frame.Razim,0,wx.ALIGN_CENTER_VERTICAL)
525        dataSizer.Add(littleSizer,0,)
526        dataSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' No. 2-theta/azimuth bins'),0,
527            wx.ALIGN_CENTER_VERTICAL)
528        littleSizer = wx.BoxSizer(wx.HORIZONTAL)
529        outChan = wx.TextCtrl(parent=G2frame.dataDisplay,value=str(data['outChannels']),style=wx.TE_PROCESS_ENTER)
530        outChan.Bind(wx.EVT_TEXT_ENTER,OnNumOutChans)
531        outChan.Bind(wx.EVT_KILL_FOCUS,OnNumOutChans)
532        littleSizer.Add(outChan,0,wx.ALIGN_CENTER_VERTICAL)
533        outAzim = wx.TextCtrl(parent=G2frame.dataDisplay,value=str(data['outAzimuths']),style=wx.TE_PROCESS_ENTER)
534        outAzim.Bind(wx.EVT_TEXT_ENTER,OnNumOutAzms)
535        outAzim.Bind(wx.EVT_KILL_FOCUS,OnNumOutAzms)
536        littleSizer.Add(outAzim,0,wx.ALIGN_CENTER_VERTICAL)
537        dataSizer.Add(littleSizer,0,)
538        littleSizer = wx.BoxSizer(wx.HORIZONTAL)
539        oblique = wx.CheckBox(parent=G2frame.dataDisplay,label='Apply detector absorption?')
540        dataSizer.Add(oblique,0,wx.ALIGN_CENTER_VERTICAL)
541        oblique.Bind(wx.EVT_CHECKBOX, OnOblique)
542        oblique.SetValue(data['Oblique'][1])
543        littleSizer.Add(wx.StaticText(G2frame.dataDisplay,label='Value (0.01-0.99)  '),0,
544            wx.ALIGN_CENTER_VERTICAL)
545        obliqVal = wx.TextCtrl(parent=G2frame.dataDisplay,value='%.3f'%(data['Oblique'][0]),style=wx.TE_PROCESS_ENTER)
546        obliqVal.Bind(wx.EVT_TEXT_ENTER,OnObliqVal)
547        obliqVal.Bind(wx.EVT_KILL_FOCUS,OnObliqVal)
548        littleSizer.Add(obliqVal,0,wx.ALIGN_CENTER_VERTICAL)
549        dataSizer.Add(littleSizer,0,)
550       
551        showLines = wx.CheckBox(parent=G2frame.dataDisplay,label='Show integration limits?')
552        dataSizer.Add(showLines,0,wx.ALIGN_CENTER_VERTICAL)
553        showLines.Bind(wx.EVT_CHECKBOX, OnShowLines)
554        showLines.SetValue(data['showLines'])
555        fullIntegrate = wx.CheckBox(parent=G2frame.dataDisplay,label='Do full integration?')
556        dataSizer.Add(fullIntegrate,0,wx.ALIGN_CENTER_VERTICAL)
557        fullIntegrate.Bind(wx.EVT_CHECKBOX, OnFullIntegrate)
558        fullIntegrate.SetValue(data['fullIntegrate'])
559        setDefault = wx.CheckBox(parent=G2frame.dataDisplay,label='Use as default for all images?')
560        dataSizer.Add(setDefault,0,wx.ALIGN_CENTER_VERTICAL)
561        setDefault.Bind(wx.EVT_CHECKBOX, OnSetDefault)
562        setDefault.SetValue(data['setDefault'])
563        centerAzm = wx.CheckBox(parent=G2frame.dataDisplay,label='Azimuth at bin center?')
564        dataSizer.Add(centerAzm,0,wx.ALIGN_CENTER_VERTICAL)
565        centerAzm.Bind(wx.EVT_CHECKBOX, OnCenterAzm)
566        centerAzm.SetValue(data['centerAzm'])
567        return dataSizer
568       
569    def BackSizer():
570       
571        def OnBackImage(event):
572            data['background image'][0] = backImage.GetValue()
573           
574        def OnBackMult(event):
575            try:
576                mult = float(backMult.GetValue())
577                data['background image'][1] = mult
578            except ValueError:
579                pass
580            backMult.SetValue("%.3f" % (data['background image'][1]))          #reset in case of error
581       
582        backSizer = wx.FlexGridSizer(1,4,5,5)
583        backSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' Background image'),0,wx.ALIGN_CENTER_VERTICAL)
584        Choices = ['',]+G2gd.GetPatternTreeDataNames(G2frame,['IMG ',])
585        backImage = wx.ComboBox(parent=G2frame.dataDisplay,value=data['background image'][0],choices=Choices,
586            style=wx.CB_READONLY|wx.CB_DROPDOWN)
587        backImage.Bind(wx.EVT_COMBOBOX,OnBackImage)
588        backSizer.Add(backImage)
589        backSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,' multiplier'),0,wx.ALIGN_CENTER_VERTICAL)
590        backMult =  wx.TextCtrl(parent=G2frame.dataDisplay,value=("%.3f" % (data['background image'][1])),
591            style=wx.TE_PROCESS_ENTER)
592        backMult.Bind(wx.EVT_TEXT_ENTER,OnBackMult)
593        backMult.Bind(wx.EVT_KILL_FOCUS,OnBackMult)
594        backSizer.Add(backMult,0,wx.ALIGN_CENTER_VERTICAL)
595        return backSizer
596                       
597    def CalibSizer():
598               
599        def OnNewCalibrant(event):
600            data['calibrant'] = calSel.GetValue()
601            data['calibskip'] = calFile.Calibrants[data['calibrant']][2]
602            limits = calFile.Calibrants[data['calibrant']][3]
603            data['calibdmin'],data['pixLimit'],data['cutoff'] = limits
604            pixLimit.SetValue(str(limits[1]))
605            cutOff.SetValue('%.1f'%(limits[2]))
606            calibSkip.SetValue(str(data['calibskip']))
607            calibDmin.SetValue('%.1f'%(limits[0]))
608           
609        def OnCalibSkip(event):
610            data['calibskip'] = int(calibSkip.GetValue())
611           
612        def OnCalibDmin(event):
613            try:
614                dmin = float(calibDmin.GetValue())
615                if dmin < 0.25:
616                    raise ValueError
617                data['calibdmin'] = dmin
618            except ValueError:
619                pass
620            calibDmin.SetValue("%.2f"%(data['calibdmin']))          #reset in case of error 
621                   
622        def OnCutOff(event):
623            try:
624                cutoff = float(cutOff.GetValue())
625                if cutoff < 0.1:
626                    raise ValueError
627                data['cutoff'] = cutoff
628            except ValueError:
629                pass
630            cutOff.SetValue("%.1f"%(data['cutoff']))          #reset in case of error 
631       
632        def OnPixLimit(event):
633            data['pixLimit'] = int(pixLimit.GetValue())
634           
635        def OnSetRings(event):
636            if data['setRings']:
637                data['setRings'] = False
638            else:
639                data['setRings'] = True
640            G2plt.PlotExposedImage(G2frame,event=event)
641   
642        calibSizer = wx.FlexGridSizer(2,3,5,5)
643        comboSizer = wx.BoxSizer(wx.HORIZONTAL)   
644        comboSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Calibrant '),0,
645            wx.ALIGN_CENTER_VERTICAL)
646        calSel = wx.ComboBox(parent=G2frame.dataDisplay,value=data['calibrant'],choices=calList,
647            style=wx.CB_READONLY|wx.CB_DROPDOWN|wx.CB_SORT)
648        calSel.Bind(wx.EVT_COMBOBOX, OnNewCalibrant)
649        comboSizer.Add(calSel,0,wx.ALIGN_CENTER_VERTICAL)
650        calibSizer.Add(comboSizer,0)
651       
652        comboSizer = wx.BoxSizer(wx.HORIZONTAL)   
653        comboSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Calib lines to skip   '),0,
654            wx.ALIGN_CENTER_VERTICAL)
655        calibSkip  = wx.ComboBox(parent=G2frame.dataDisplay,value=str(data['calibskip']),choices=[str(i) for i in range(25)],
656            style=wx.CB_READONLY|wx.CB_DROPDOWN)
657        calibSkip.Bind(wx.EVT_COMBOBOX, OnCalibSkip)
658        comboSizer.Add(calibSkip,0,wx.ALIGN_CENTER_VERTICAL)
659        calibSizer.Add(comboSizer,0)
660       
661        comboSizer = wx.BoxSizer(wx.HORIZONTAL)       
662        comboSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Min calib d-spacing '),0,
663            wx.ALIGN_CENTER_VERTICAL)
664        calibDmin = wx.TextCtrl(parent=G2frame.dataDisplay,value=("%.2f" % (data['calibdmin'])),
665            style=wx.TE_PROCESS_ENTER)
666        calibDmin.Bind(wx.EVT_TEXT_ENTER,OnCalibDmin)
667        calibDmin.Bind(wx.EVT_KILL_FOCUS,OnCalibDmin)
668        comboSizer.Add(calibDmin,0,wx.ALIGN_CENTER_VERTICAL)
669        calibSizer.Add(comboSizer,0)
670       
671        comboSizer = wx.BoxSizer(wx.HORIZONTAL)
672        comboSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Min ring I/Ib '),0,
673            wx.ALIGN_CENTER_VERTICAL)
674        cutOff = wx.TextCtrl(parent=G2frame.dataDisplay,value=("%.1f" % (data['cutoff'])),
675            style=wx.TE_PROCESS_ENTER)
676        cutOff.Bind(wx.EVT_TEXT_ENTER,OnCutOff)
677        cutOff.Bind(wx.EVT_KILL_FOCUS,OnCutOff)
678        comboSizer.Add(cutOff,0,wx.ALIGN_CENTER_VERTICAL)
679        calibSizer.Add(comboSizer,0)
680       
681        comboSizer = wx.BoxSizer(wx.HORIZONTAL)
682        comboSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Pixel search range '),0,
683            wx.ALIGN_CENTER_VERTICAL)
684        pixLimit = wx.ComboBox(parent=G2frame.dataDisplay,value=str(data['pixLimit']),choices=['1','2','5','10','15','20'],
685            style=wx.CB_READONLY|wx.CB_DROPDOWN)
686        pixLimit.Bind(wx.EVT_COMBOBOX, OnPixLimit)
687        comboSizer.Add(pixLimit,0,wx.ALIGN_CENTER_VERTICAL)
688        calibSizer.Add(comboSizer,0)
689       
690        comboSizer = wx.BoxSizer(wx.HORIZONTAL)
691        setRings = wx.CheckBox(parent=G2frame.dataDisplay,label='Show ring picks?')
692        comboSizer.Add(setRings,0)
693        setRings.Bind(wx.EVT_CHECKBOX, OnSetRings)
694        setRings.SetValue(data['setRings'])
695        calibSizer.Add(comboSizer,0)
696        return calibSizer
697       
698# Image Controls main code             
699                           
700    #fix for old files:
701    if 'azmthOff' not in data:
702        data['azmthOff'] = 0.0
703    if 'background image' not in data:
704        data['background image'] = ['',1.0]
705    if 'centerAzm' not in data:
706        data['centerAzm'] = False
707    if 'Oblique' not in data:
708        data['Oblique'] = [0.5,False]
709    #end fix
710   
711    colorList = [m for m in mpl.cm.datad.keys() if not m.endswith("_r")]
712    calList = [m for m in calFile.Calibrants.keys()]
713    typeList = ['PWDR - powder diffraction data','SASD - small angle scattering data',
714        'REFL - reflectometry data']
715    if not data.get('type'):                        #patch for old project files
716        data['type'] = 'PWDR'
717    typeDict = {'PWDR':typeList[0],'SASD':typeList[1],'REFL':typeList[2]}
718    if G2frame.dataDisplay:
719        G2frame.dataDisplay.Destroy()
720    G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.ImageMenu)
721    if not G2frame.dataFrame.GetStatusBar():
722        G2frame.dataFrame.CreateStatusBar()
723    G2frame.dataFrame.Bind(wx.EVT_MENU, OnCalibrate, id=G2gd.wxID_IMCALIBRATE)
724    G2frame.dataFrame.Bind(wx.EVT_MENU, OnRecalibrate, id=G2gd.wxID_IMRECALIBRATE)
725    G2frame.dataFrame.Bind(wx.EVT_MENU, OnClearCalib, id=G2gd.wxID_IMCLEARCALIB)
726    if not data['rings']:
727        G2frame.dataFrame.ImageEdit.Enable(id=G2gd.wxID_IMRECALIBRATE,enable=False)   
728    G2frame.dataFrame.Bind(wx.EVT_MENU, OnIntegrate, id=G2gd.wxID_IMINTEGRATE)
729    G2frame.dataFrame.Bind(wx.EVT_MENU, OnIntegrateAll, id=G2gd.wxID_INTEGRATEALL)
730    G2frame.dataFrame.Bind(wx.EVT_MENU, OnCopyControls, id=G2gd.wxID_IMCOPYCONTROLS)
731    G2frame.dataFrame.Bind(wx.EVT_MENU, OnSaveControls, id=G2gd.wxID_IMSAVECONTROLS)
732    G2frame.dataFrame.Bind(wx.EVT_MENU, OnLoadControls, id=G2gd.wxID_IMLOADCONTROLS)
733    G2frame.dataDisplay = wx.Panel(G2frame.dataFrame)
734
735    mainSizer = wx.BoxSizer(wx.VERTICAL)
736    mainSizer.Add((5,10),0)   
737    mainSizer.Add(ComboSizer(),0,wx.ALIGN_LEFT)
738    mainSizer.Add((5,5),0)           
739    mainSizer.Add(MaxSizer(),0,wx.ALIGN_LEFT|wx.EXPAND)
740   
741    mainSizer.Add((5,5),0)
742    DataSizer = wx.FlexGridSizer(1,2,5,5)
743    DataSizer.Add(CalibCoeffSizer(),0)
744    DataSizer.Add(IntegrateSizer(),0)       
745    mainSizer.Add(DataSizer,0)
746    mainSizer.Add((5,5),0)           
747    mainSizer.Add(BackSizer(),0)
748    mainSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Calibration controls:'),0,
749        wx.ALIGN_CENTER_VERTICAL)
750    mainSizer.Add((5,5),0)
751    mainSizer.Add(CalibSizer(),0,wx.ALIGN_CENTER_VERTICAL)
752       
753    mainSizer.Layout()   
754    G2frame.dataDisplay.SetSizer(mainSizer)
755    fitSize = mainSizer.Fit(G2frame.dataFrame)
756    G2frame.dataFrame.setSizePosLeft(fitSize)
757    G2frame.dataDisplay.SetSize(fitSize)
758   
759################################################################################
760##### Masks
761################################################################################
762   
763def UpdateMasks(G2frame,data):
764   
765    def OnTextMsg(event):
766        Obj = event.GetEventObject()
767        Obj.SetToolTipString('Drag this mask on 2D Powder Image with mouse to change ')
768       
769    def OnThreshold(event):
770        try:
771            lower = max(int(lowerThreshold.GetValue()),thresh[0][0])
772        except ValueError:
773            lower = thresh[0][0]
774        try:
775            upper = min(int(upperThreshold.GetValue()),thresh[0][1])
776        except ValueError:
777            upper = thresh[0][1]
778        data['Thresholds'][1] = [lower,upper]
779        lowerThreshold.SetValue("%8d" % (lower))
780        upperThreshold.SetValue("%8d" % (upper))
781        G2plt.PlotExposedImage(G2frame,event=event)
782       
783    def OnSpotDiameter(event):
784        Obj = event.GetEventObject()
785        try:
786            diameter = min(100.,max(0.1,float(Obj.GetValue())))
787        except ValueError:
788            diameter = 1.0
789        Obj.SetValue("%.2f"%(diameter))
790        data['Points'][spotIds.index(Obj.GetId())][2] = diameter
791        G2plt.PlotExposedImage(G2frame,event=event)
792       
793    def OnDeleteSpot(event):
794        Obj = event.GetEventObject()
795        del(data['Points'][delSpotId.index(Obj)])
796        UpdateMasks(G2frame,data)
797        G2plt.PlotExposedImage(G2frame,event=event)
798       
799    def OnRingThickness(event):
800        Obj = event.GetEventObject()
801        try:
802            thick = min(1.0,max(0.001,float(Obj.GetValue())))
803        except ValueError:
804            thick = 0.1
805        Obj.SetValue("%.3f"%(thick))
806        data['Rings'][ringIds.index(Obj.GetId())][1] = thick
807        G2plt.PlotExposedImage(G2frame,event=event)
808       
809    def OnDeleteRing(event):
810        Obj = event.GetEventObject()
811        del(data['Rings'][delRingId.index(Obj)])
812        UpdateMasks(G2frame,data)
813        G2plt.PlotExposedImage(G2frame,event=event)
814
815    def OnArcThickness(event):
816        Obj = event.GetEventObject()
817        try:
818            thick = min(20.0,max(0.001,float(Obj.GetValue())))
819        except ValueError:
820            thick = 0.1
821        Obj.SetValue("%.3f"%(thick))
822        data['Arcs'][arcIds.index(Obj.GetId())][2] = thick
823        G2plt.PlotExposedImage(G2frame,event=event)
824       
825    def OnDeleteArc(event):
826        Obj = event.GetEventObject()
827        del(data['Arcs'][delArcId.index(Obj)])
828        UpdateMasks(G2frame,data)
829        G2plt.PlotExposedImage(G2frame,event=event)
830
831    def OnDeletePoly(event):
832        Obj = event.GetEventObject()
833        del(data['Polygons'][delPolyId.index(Obj)])
834        UpdateMasks(G2frame,data)
835        G2plt.PlotExposedImage(G2frame,event=event)
836
837    def OnCopyMask(event):
838        import copy
839        TextList = [[False,'All IMG',0]]
840        Names = []
841        if G2frame.PatternTree.GetCount():
842            id, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root)
843            while id:
844                name = G2frame.PatternTree.GetItemText(id)
845                Names.append(name)
846                if 'IMG' in name:
847                    if id == G2frame.Image:
848                        Source = name
849                        Mask = copy.deepcopy(G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,id, 'Masks')))
850                        del Mask['Thresholds']
851                    else:
852                        TextList.append([False,name,id])
853                id, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie)
854            if len(TextList) == 1:
855                G2frame.ErrorDialog('Nothing to copy mask to','There must be more than one "IMG" pattern')
856                return
857            dlg = G2frame.CopyDialog(G2frame,'Copy mask information','Copy mask from '+Source+' to:',TextList)
858            try:
859                if dlg.ShowModal() == wx.ID_OK:
860                    result = dlg.GetData()
861                    if result[0][0]:
862                        result = TextList[1:]
863                        for item in result: item[0] = True
864                    for i,item in enumerate(result):
865                        ifcopy,name,id = item
866                        if ifcopy:
867                            mask = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,id, 'Masks'))
868                            mask.update(Mask)                               
869                            G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,id, 'Masks'),copy.deepcopy(mask))
870            finally:
871                dlg.Destroy()
872               
873    def OnSaveMask(event):
874        dlg = wx.FileDialog(G2frame, 'Choose image mask file', '.', '', 
875            'image mask files (*.immask)|*.immask',wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT|wx.CHANGE_DIR)
876        try:
877            if dlg.ShowModal() == wx.ID_OK:
878                filename = dlg.GetPath()
879                File = open(filename,'w')
880                save = {}
881                keys = ['Points','Rings','Arcs','Polygons','Thresholds']
882                for key in keys:
883                    File.write(key+':'+str(data[key])+'\n')
884                File.close()
885        finally:
886            dlg.Destroy()
887       
888    def OnLoadMask(event):
889        dlg = wx.FileDialog(G2frame, 'Choose image mask file', '.', '', 
890            'image mask files (*.immask)|*.immask',wx.OPEN|wx.CHANGE_DIR)
891        try:
892            if dlg.ShowModal() == wx.ID_OK:
893                filename = dlg.GetPath()
894                File = open(filename,'r')
895                save = {}
896                S = File.readline()
897                while S:
898                    if S[0] == '#':
899                        S = File.readline()
900                        continue
901                    [key,val] = S[:-1].split(':')
902                    if key in ['Points','Rings','Arcs','Polygons','Thresholds']:
903                        save[key] = eval(val)
904                    S = File.readline()
905                data.update(save)
906                UpdateMasks(G2frame,data)
907                G2plt.PlotExposedImage(G2frame,event=event)
908               
909                File.close()
910        finally:
911            dlg.Destroy()
912       
913    if G2frame.dataDisplay:
914        G2frame.dataDisplay.Destroy()
915    G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.MaskMenu)
916    G2frame.dataFrame.Bind(wx.EVT_MENU, OnCopyMask, id=G2gd.wxID_MASKCOPY)
917    G2frame.dataFrame.Bind(wx.EVT_MENU, OnLoadMask, id=G2gd.wxID_MASKLOAD)
918    G2frame.dataFrame.Bind(wx.EVT_MENU, OnSaveMask, id=G2gd.wxID_MASKSAVE)   
919    if not G2frame.dataFrame.GetStatusBar():
920        Status = G2frame.dataFrame.CreateStatusBar()
921        Status.SetStatusText("To add mask: On 2D Powder Image, key a:arc, r:ring, s:spot, p:polygon")
922    G2frame.dataDisplay = wx.Panel(G2frame.dataFrame)
923    mainSizer = wx.BoxSizer(wx.VERTICAL)
924    mainSizer.Add((5,10),0)
925
926    thresh = data['Thresholds']         #min/max intensity range
927    spots = data['Points']               #x,y,radius in mm
928    rings = data['Rings']               #radius, thickness
929    polygons = data['Polygons']         #3+ x,y pairs
930    arcs = data['Arcs']                 #radius, start/end azimuth, thickness
931   
932    littleSizer = wx.FlexGridSizer(2,3,0,5)
933    littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Lower/Upper limits '),0,
934        wx.ALIGN_CENTER_VERTICAL)
935    Text = wx.TextCtrl(G2frame.dataDisplay,value=("%8d" % (thresh[0][0])),style=wx.TE_READONLY)
936    littleSizer.Add(Text,0,wx.ALIGN_CENTER_VERTICAL)
937    Text.SetBackgroundColour(VERY_LIGHT_GREY)
938    Text = wx.TextCtrl(G2frame.dataDisplay,value=("%8d" % (thresh[0][1])),style=wx.TE_READONLY)
939    littleSizer.Add(Text,0,wx.ALIGN_CENTER_VERTICAL)
940    Text.SetBackgroundColour(VERY_LIGHT_GREY)
941    littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Lower/Upper thresholds '),
942        0,wx.ALIGN_CENTER_VERTICAL)
943    lowerThreshold = wx.TextCtrl(parent=G2frame.dataDisplay,
944        value=("%8d" % (thresh[1][0])),style=wx.TE_PROCESS_ENTER)
945    lowerThreshold.Bind(wx.EVT_TEXT_ENTER,OnThreshold)
946    lowerThreshold.Bind(wx.EVT_KILL_FOCUS,OnThreshold)
947    littleSizer.Add(lowerThreshold,0,wx.ALIGN_CENTER_VERTICAL)
948    upperThreshold = wx.TextCtrl(parent=G2frame.dataDisplay,
949        value=("%8d" % (thresh[1][1])),style=wx.TE_PROCESS_ENTER)
950    upperThreshold.Bind(wx.EVT_TEXT_ENTER,OnThreshold)
951    upperThreshold.Bind(wx.EVT_KILL_FOCUS,OnThreshold)
952    littleSizer.Add(upperThreshold,0,wx.ALIGN_CENTER_VERTICAL)
953    mainSizer.Add(littleSizer,0,)
954    spotIds = []
955    delSpotId = []
956    if spots:
957        littleSizer = wx.FlexGridSizer(len(spots)+2,3,0,5)
958        littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Spot masks:'),0,
959            wx.ALIGN_CENTER_VERTICAL)
960        littleSizer.Add((5,0),0)
961        littleSizer.Add((5,0),0)
962        littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' position, mm'),0,
963            wx.ALIGN_CENTER_VERTICAL)
964        littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' diameter, mm'),0,
965            wx.ALIGN_CENTER_VERTICAL)
966        littleSizer.Add((5,0),0)
967        for x,y,d in spots:
968            spotText = wx.TextCtrl(parent=G2frame.dataDisplay,value=("%.2f,%.2f" % (x,y)),
969                style=wx.TE_READONLY)
970            spotText.SetBackgroundColour(VERY_LIGHT_GREY)
971            littleSizer.Add(spotText,0,wx.ALIGN_CENTER_VERTICAL)
972            spotText.Bind(wx.EVT_ENTER_WINDOW,OnTextMsg)
973            spotDiameter = wx.TextCtrl(parent=G2frame.dataDisplay,value=("%.2f" % (d)),
974                style=wx.TE_PROCESS_ENTER)
975            littleSizer.Add(spotDiameter,0,wx.ALIGN_CENTER_VERTICAL)
976            spotDiameter.Bind(wx.EVT_TEXT_ENTER,OnSpotDiameter)
977            spotDiameter.Bind(wx.EVT_KILL_FOCUS,OnSpotDiameter)
978            spotIds.append(spotDiameter.GetId())
979            spotDelete = wx.CheckBox(parent=G2frame.dataDisplay,label='delete?')
980            spotDelete.Bind(wx.EVT_CHECKBOX,OnDeleteSpot)
981            delSpotId.append(spotDelete)
982            littleSizer.Add(spotDelete,0,wx.ALIGN_CENTER_VERTICAL)
983        mainSizer.Add(littleSizer,0,)
984    ringIds = []
985    delRingId = []
986    if rings:
987        littleSizer = wx.FlexGridSizer(len(rings)+2,3,0,5)
988        littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Ring masks:'),0,
989            wx.ALIGN_CENTER_VERTICAL)
990        littleSizer.Add((5,0),0)
991        littleSizer.Add((5,0),0)
992        littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' 2-theta,deg'),0,
993            wx.ALIGN_CENTER_VERTICAL)
994        littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' thickness, deg'),0,
995            wx.ALIGN_CENTER_VERTICAL)
996        littleSizer.Add((5,0),0)
997        for tth,thick in rings:
998            ringText = wx.TextCtrl(parent=G2frame.dataDisplay,value=("%.3f" % (tth)),
999                style=wx.TE_READONLY)
1000            ringText.SetBackgroundColour(VERY_LIGHT_GREY)
1001            ringText.Bind(wx.EVT_ENTER_WINDOW,OnTextMsg)
1002            littleSizer.Add(ringText,0,wx.ALIGN_CENTER_VERTICAL)
1003            ringThick = wx.TextCtrl(parent=G2frame.dataDisplay,value=("%.3f" % (thick)),
1004                style=wx.TE_PROCESS_ENTER)
1005            littleSizer.Add(ringThick,0,wx.ALIGN_CENTER_VERTICAL)
1006            ringThick.Bind(wx.EVT_TEXT_ENTER,OnRingThickness)
1007            ringThick.Bind(wx.EVT_KILL_FOCUS,OnRingThickness)
1008            ringIds.append(ringThick.GetId())
1009            ringDelete = wx.CheckBox(parent=G2frame.dataDisplay,label='delete?')
1010            ringDelete.Bind(wx.EVT_CHECKBOX,OnDeleteRing)
1011            delRingId.append(ringDelete)
1012            littleSizer.Add(ringDelete,0,wx.ALIGN_CENTER_VERTICAL)
1013        mainSizer.Add(littleSizer,0,)
1014    arcIds = []
1015    delArcId = []
1016    if arcs:
1017        littleSizer = wx.FlexGridSizer(len(rings)+2,4,0,5)
1018        littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Arc masks:'),0,
1019            wx.ALIGN_CENTER_VERTICAL)
1020        littleSizer.Add((5,0),0)
1021        littleSizer.Add((5,0),0)
1022        littleSizer.Add((5,0),0)
1023        littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' 2-theta,deg'),0,
1024            wx.ALIGN_CENTER_VERTICAL)
1025        littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' azimuth, deg'),0,
1026            wx.ALIGN_CENTER_VERTICAL)
1027        littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' thickness, deg'),0,
1028            wx.ALIGN_CENTER_VERTICAL)
1029        littleSizer.Add((5,0),0)
1030        for tth,azimuth,thick in arcs:
1031            arcText = wx.TextCtrl(parent=G2frame.dataDisplay,value=("%.3f" % (tth)),
1032                style=wx.TE_READONLY)
1033            arcText.SetBackgroundColour(VERY_LIGHT_GREY)
1034            arcText.Bind(wx.EVT_ENTER_WINDOW,OnTextMsg)
1035            littleSizer.Add(arcText,0,wx.ALIGN_CENTER_VERTICAL)
1036            azmText = wx.TextCtrl(parent=G2frame.dataDisplay,value=("%d,%d" % (azimuth[0],azimuth[1])),
1037                style=wx.TE_READONLY)
1038            azmText.SetBackgroundColour(VERY_LIGHT_GREY)
1039            azmText.Bind(wx.EVT_ENTER_WINDOW,OnTextMsg)
1040            littleSizer.Add(azmText,0,wx.ALIGN_CENTER_VERTICAL)
1041            arcThick = wx.TextCtrl(parent=G2frame.dataDisplay,value=("%.3f" % (thick)),
1042                style=wx.TE_PROCESS_ENTER)
1043            littleSizer.Add(arcThick,0,wx.ALIGN_CENTER_VERTICAL)
1044            arcThick.Bind(wx.EVT_TEXT_ENTER,OnArcThickness)
1045            arcThick.Bind(wx.EVT_KILL_FOCUS,OnArcThickness)
1046            arcIds.append(arcThick.GetId())
1047            arcDelete = wx.CheckBox(parent=G2frame.dataDisplay,label='delete?')
1048            arcDelete.Bind(wx.EVT_CHECKBOX,OnDeleteArc)
1049            delArcId.append(arcDelete)
1050            littleSizer.Add(arcDelete,0,wx.ALIGN_CENTER_VERTICAL)
1051        mainSizer.Add(littleSizer,0,)
1052    polyIds = []
1053    delPolyId = []
1054    if polygons:
1055        littleSizer = wx.FlexGridSizer(len(polygons)+2,2,0,5)
1056        littleSizer.Add(wx.StaticText(parent=G2frame.dataDisplay,label=' Polygon masks:'),0,
1057            wx.ALIGN_CENTER_VERTICAL)
1058        littleSizer.Add((5,0),0)
1059        for polygon in polygons:
1060            if polygon:
1061                polyList = []
1062                for x,y in polygon:
1063                    polyList.append("%.2f, %.2f"%(x,y))
1064                polyText = wx.ComboBox(G2frame.dataDisplay,value=polyList[0],choices=polyList,style=wx.CB_READONLY)
1065                littleSizer.Add(polyText,0,wx.ALIGN_CENTER_VERTICAL)
1066                polyDelete = wx.CheckBox(parent=G2frame.dataDisplay,label='delete?')
1067                polyDelete.Bind(wx.EVT_CHECKBOX,OnDeletePoly)
1068                delPolyId.append(polyDelete)
1069                littleSizer.Add(polyDelete,0,wx.ALIGN_CENTER_VERTICAL)
1070        mainSizer.Add(littleSizer,0,)
1071    mainSizer.Layout()   
1072    G2frame.dataDisplay.SetSizer(mainSizer)
1073    G2frame.dataDisplay.SetSize(mainSizer.Fit(G2frame.dataFrame))
1074    G2frame.dataFrame.setSizePosLeft(mainSizer.Fit(G2frame.dataFrame))   
1075
1076################################################################################
1077##### Stress/Strain
1078################################################################################
1079
1080def UpdateStressStrain(G2frame,data):
1081   
1082    def OnAppendDzero(event):
1083        data['d-zero'].append({'Dset':1.0,'Dcalc':0.0,'pixLimit':10,'cutoff':10.0,'ImxyObs':[[],[]],'Imxycalc':[[],[]]})
1084        UpdateStressStrain(G2frame,data)
1085           
1086    def OnCopyStrSta(event):
1087        import copy
1088        TextList = [[False,'All IMG',0]]
1089        Names = []
1090        if G2frame.PatternTree.GetCount():
1091            id, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root)
1092            while id:
1093                name = G2frame.PatternTree.GetItemText(id)
1094                Names.append(name)
1095                if 'IMG' in name:
1096                    if id == G2frame.Image:
1097                        Source = name
1098                        Data = copy.deepcopy(G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,id, 'Stress/Strain')))
1099                    else:
1100                        TextList.append([False,name,id])
1101                id, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie)
1102            if len(TextList) == 1:
1103                G2frame.ErrorDialog('Nothing to copy controls to','There must be more than one "IMG" pattern')
1104                return
1105            dlg = G2frame.CopyDialog(G2frame,'Copy stress/strain controls','Copy controls from '+Source+' to:',TextList)
1106            try:
1107                if dlg.ShowModal() == wx.ID_OK:
1108                    result = dlg.GetData()
1109                    if result[0][0]:
1110                        result = TextList[1:]
1111                        for item in result: item[0] = True
1112                    for i,item in enumerate(result):
1113                        ifcopy,name,id = item
1114                        if ifcopy:
1115                            oldData = copy.deepcopy(G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,id, 'Stress/Strain')))
1116                            G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,id, 'Stress/Strain'),copy.deepcopy(Data))
1117            finally:
1118                dlg.Destroy()
1119
1120    def OnLoadStrSta(event):
1121        print 'Load stress/strain data - does nothing yet'
1122        event.Skip()
1123
1124    def OnSaveStrSta(event):
1125        dlg = wx.FileDialog(G2frame, 'Choose stress/strain file', '.', '', 
1126            'image control files (*.strsta)|*.strsta',wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT|wx.CHANGE_DIR)
1127        try:
1128            if dlg.ShowModal() == wx.ID_OK:
1129                filename = dlg.GetPath()
1130                File = open(filename,'w')
1131                save = {}
1132                keys = ['Type','Sample phi','Sample z','strain']
1133                keys2 = ['Dset','Dcalc','pixLimit','cutoff']
1134                File.write('{\n\t')
1135                for key in keys:
1136                    if key in 'strain':
1137                        File.write("'"+key+"':["+str(data[key][0])+','+str(data[key][1])+','+str(data[key][2])+'],')
1138                    else:
1139                        File.write("'"+key+"':"+str(data[key])+',')
1140                File.write('\n\t'+"'d-zero':[\n")
1141                for data2 in data['d-zero']:
1142                    File.write('\t\t{')
1143                    for key in keys2:
1144                        File.write("'"+key+"':"+':'+str(data2[key])+',')
1145                    File.write("'ImxyObs':[[],[]],'Imxycalc':[[],[]]},\n")
1146                File.write('\t]\n}')
1147                File.close()
1148        finally:
1149            dlg.Destroy()
1150
1151    def OnFitStrSta(event):
1152        print 'Fit stress/strain data - does nothing yet'
1153        event.Skip()
1154       
1155    def SamSizer():
1156       
1157        def OnStrainType(event):
1158            data['Type'] = strType.GetValue()
1159       
1160        def OnSamPhi(event):
1161            try:
1162                value = float(samPhi.GetValue())
1163            except ValueError:
1164                value = data['Sample phi']
1165            data['Sample phi'] = value
1166            samPhi.SetValue("%.3f" % (data['Sample phi']))
1167               
1168        def OnSamZ(event):
1169            try:
1170                value = float(samZ.GetValue())
1171            except ValueError:
1172                value = data['Sample z']
1173            data['Sample z'] = value
1174            samZ.SetValue("%.3f" % (data['Sample z']))
1175               
1176        samSizer = wx.BoxSizer(wx.HORIZONTAL)
1177        samSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,label=' Strain type: '),0,wx.ALIGN_CENTER_VERTICAL)
1178        strType = wx.ComboBox(G2frame.dataDisplay,value=data['Type'],choices=['True','Conventional'],
1179            style=wx.CB_READONLY|wx.CB_DROPDOWN)
1180        strType.SetValue(data['Type'])
1181        strType.Bind(wx.EVT_COMBOBOX, OnStrainType)
1182        samSizer.Add(strType,0,wx.ALIGN_CENTER_VERTICAL)
1183       
1184        samSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,label=' Sample phi: '),0,wx.ALIGN_CENTER_VERTICAL)
1185        samPhi = wx.TextCtrl(G2frame.dataDisplay,-1,value=("%.3f" % (data['Sample phi'])),
1186            style=wx.TE_PROCESS_ENTER)
1187        samSizer.Add(samPhi,0,wx.ALIGN_CENTER_VERTICAL)
1188        samPhi.Bind(wx.EVT_TEXT_ENTER,OnSamPhi)
1189        samPhi.Bind(wx.EVT_KILL_FOCUS,OnSamPhi)
1190        samSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,label=' Sample delta-z(mm): '),0,wx.ALIGN_CENTER_VERTICAL)
1191        samZ = wx.TextCtrl(G2frame.dataDisplay,-1,value=("%.3f" % (data['Sample z'])),
1192            style=wx.TE_PROCESS_ENTER)
1193        samSizer.Add(samZ,0,wx.ALIGN_CENTER_VERTICAL)
1194        samZ.Bind(wx.EVT_TEXT_ENTER,OnSamZ)
1195        samZ.Bind(wx.EVT_KILL_FOCUS,OnSamZ)
1196        return samSizer
1197       
1198    def DzeroSizer():
1199   
1200        def OnDzero(event):
1201            Obj = event.GetEventObject()
1202            try:
1203                value = min(10.0,max(1.0,float(Obj.GetValue())))
1204            except ValueError:
1205                value = 1.0
1206            Obj.SetValue("%.5f"%(value))
1207            data['d-zero'][Indx[Obj.GetId()]]['Dset'] = value
1208           
1209        def OnDeleteDzero(event):
1210            Obj = event.GetEventObject()
1211            del(data['d-zero'][delIndx.index(Obj)])
1212            UpdateStressStrain(G2frame,data)
1213       
1214        def OnCutOff(event):
1215            Obj = event.GetEventObject()
1216            try:
1217                value = min(10.0,max(0.5,float(Obj.GetValue())))
1218            except ValueError:
1219                value = 10.0
1220            Obj.SetValue("%.1f"%(value))
1221            data['d-zero'][Indx[Obj.GetId()]]['cutoff'] = value
1222       
1223        def OnPixLimit(event):
1224            Obj = event.GetEventObject()
1225            data['d-zero'][Indx[Obj.GetId()]]['pixLimit'] = int(Obj.GetValue())
1226           
1227        Indx = {}
1228        delIndx = []   
1229        dzeroSizer = wx.FlexGridSizer(1,8,5,5)
1230        for id,dzero in enumerate(data['d-zero']):
1231            dzeroSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,label=(' d-zero #%d: '%(id))),
1232                0,wx.ALIGN_CENTER_VERTICAL)
1233            dZero = wx.TextCtrl(G2frame.dataDisplay,-1,value=('%.5f'%(dzero['Dset'])),
1234                style=wx.TE_PROCESS_ENTER)
1235            dzeroSizer.Add(dZero,0,wx.ALIGN_CENTER_VERTICAL)
1236            dZero.Bind(wx.EVT_TEXT_ENTER,OnDzero)
1237            dZero.Bind(wx.EVT_KILL_FOCUS,OnDzero)
1238            Indx[dZero.GetId()] = id
1239            dzeroSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,label=(' d-zero calc: %.5f'%(dzero['Dcalc']))),
1240                0,wx.ALIGN_CENTER_VERTICAL)
1241               
1242            dzeroSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Min ring I/Ib '),0,
1243                wx.ALIGN_CENTER_VERTICAL)
1244            cutOff = wx.TextCtrl(parent=G2frame.dataDisplay,value=("%.1f" % (dzero['cutoff'])),
1245                style=wx.TE_PROCESS_ENTER)
1246            cutOff.Bind(wx.EVT_TEXT_ENTER,OnCutOff)
1247            cutOff.Bind(wx.EVT_KILL_FOCUS,OnCutOff)
1248            Indx[cutOff.GetId()] = id
1249            dzeroSizer.Add(cutOff,0,wx.ALIGN_CENTER_VERTICAL)
1250       
1251            dzeroSizer.Add(wx.StaticText(G2frame.dataDisplay,label=' Pixel search range '),0,
1252                wx.ALIGN_CENTER_VERTICAL)
1253            pixLimit = wx.ComboBox(parent=G2frame.dataDisplay,value=str(dzero['pixLimit']),choices=['1','2','5','10','15','20'],
1254                style=wx.CB_READONLY|wx.CB_DROPDOWN)
1255            pixLimit.Bind(wx.EVT_COMBOBOX, OnPixLimit)
1256            Indx[pixLimit.GetId()] = id
1257            dzeroSizer.Add(pixLimit,0,wx.ALIGN_CENTER_VERTICAL)               
1258               
1259            dzeroDelete = wx.CheckBox(parent=G2frame.dataDisplay,label='delete?')
1260            dzeroDelete.Bind(wx.EVT_CHECKBOX,OnDeleteDzero)
1261            delIndx.append(dzeroDelete)
1262            dzeroSizer.Add(dzeroDelete,0,wx.ALIGN_CENTER_VERTICAL)
1263        return dzeroSizer
1264       
1265    def StrainSizer():
1266       
1267        strainSizer = wx.BoxSizer(wx.VERTICAL)
1268        strainSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,label=(' Strain tensor:')),
1269            0,wx.ALIGN_CENTER_VERTICAL)
1270        tensorSizer = wx.FlexGridSizer(3,6,5,5)
1271        names = [[' e11','e12','e13'],[' e21','e22','e23'],[' e31','e32','e33']]
1272        for i in range(3):
1273            for j in range(3):
1274                tensorSizer.Add(wx.StaticText(G2frame.dataDisplay,-1,label=names[i][j]),0,wx.ALIGN_CENTER_VERTICAL)
1275                tensorElem = wx.TextCtrl(G2frame.dataDisplay,-1,value='%.2f'%(data['strain'][i][j]),style=wx.TE_READONLY)
1276                tensorElem.SetBackgroundColour(VERY_LIGHT_GREY)
1277                tensorSizer.Add(tensorElem,0,wx.ALIGN_CENTER_VERTICAL)
1278        strainSizer.Add(tensorSizer)
1279        return strainSizer
1280
1281    if G2frame.dataDisplay:
1282        G2frame.dataDisplay.Destroy()
1283    G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.StrStaMenu)
1284    G2frame.dataFrame.Bind(wx.EVT_MENU, OnAppendDzero, id=G2gd.wxID_APPENDDZERO)
1285    G2frame.dataFrame.Bind(wx.EVT_MENU, OnFitStrSta, id=G2gd.wxID_STRSTAFIT)
1286    G2frame.dataFrame.Bind(wx.EVT_MENU, OnCopyStrSta, id=G2gd.wxID_STRSTACOPY)
1287    G2frame.dataFrame.Bind(wx.EVT_MENU, OnLoadStrSta, id=G2gd.wxID_STRSTALOAD)
1288    G2frame.dataFrame.Bind(wx.EVT_MENU, OnSaveStrSta, id=G2gd.wxID_STRSTASAVE)   
1289    if not G2frame.dataFrame.GetStatusBar():
1290        Status = G2frame.dataFrame.CreateStatusBar()
1291        Status.SetStatusText(" test  ")
1292    G2frame.dataDisplay = wx.Panel(G2frame.dataFrame)
1293    mainSizer = wx.BoxSizer(wx.VERTICAL)
1294    mainSizer.Add((5,10),0)
1295    mainSizer.Add(SamSizer())
1296    mainSizer.Add((5,10),0)
1297    mainSizer.Add(DzeroSizer())
1298    mainSizer.Add((5,10),0)
1299    mainSizer.Add(StrainSizer())
1300   
1301    mainSizer.Layout()   
1302    G2frame.dataDisplay.SetSizer(mainSizer)
1303    G2frame.dataDisplay.SetSize(mainSizer.Fit(G2frame.dataFrame))
1304    G2frame.dataFrame.setSizePosLeft(mainSizer.Fit(G2frame.dataFrame))   
Note: See TracBrowser for help on using the repository browser.