source: trunk/GSASIIimgGUI.py @ 1268

Last change on this file since 1268 was 1268, checked in by vondreele, 9 years ago

WACV = wx.ALIGN_CENTER_VERTICAL in G2imgGUI
add more sasd modeling code

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