source: trunk/GSASIIimgGUI.py @ 1331

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

fix cake integration problem - in G2IO return in wrong indent
fix seq refinement display problem in G2obj self.eObj.assgnVars[v] returned a list not a name

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