source: trunk/GSASIIimgGUI.py @ 1163

Last change on this file since 1163 was 1163, checked in by vondreele, 10 years ago

ellipse & hyperbola fitting & plotting - much closer
still issues tho.

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