source: trunk/GSASIIimgGUI.py @ 1204

Last change on this file since 1204 was 1204, checked in by vondreele, 11 years ago

SASD now in q only (not 2-theta); fix minor bugs

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