source: trunk/GSASIIimgGUI.py @ 1057

Last change on this file since 1057 was 1057, checked in by toby, 8 years ago

reorg UserCalibrants? into ImageCalibrants?; Add trim (whitespace) routine; fix InstName? bug in GetHistogramPhaseData?; rework ValidatedTxtCtrl? for CIF; ScrolledMultiEditor? now resets after Cancel; CIF export progress

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