source: trunk/GSASIIimgGUI.py @ 1152

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

fixes to image integration

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