source: trunk/GSASIIimgGUI.py @ 1389

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

fix format of image center in GUI - now two rows..

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