source: trunk/GSASIIimgGUI.py @ 1380

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

sequential refinement of strain from IMG data
and plotting of seq results.
fixes of small angle seq refinement

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