source: trunk/GSASIIimgGUI.py @ 1149

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

cleanup of image stuff
remove wx from G2image, limit fitting to ellipses - break on hyperbola

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