source: trunk/GSASIIimgGUI.py @ 1174

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

correct image integration for sample absorption - cylinders only for now

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