source: trunk/GSASIIimgGUI.py @ 294

Last change on this file since 294 was 294, checked in by vondreele, 11 years ago

implement mask save & load
implement copy to all for masks
refactor load controls

  • Property svn:keywords set to Date Author Revision URL Id
File size: 42.6 KB
Line 
1#GSASII - image data display routines
2########### SVN repository information ###################
3# $Date: 2011-05-26 16:02:42 +0000 (Thu, 26 May 2011) $
4# $Author: vondreele $
5# $Revision: 294 $
6# $URL: trunk/GSASIIimgGUI.py $
7# $Id: GSASIIimgGUI.py 294 2011-05-26 16:02:42Z vondreele $
8########### SVN repository information ###################
9import wx
10import wx.grid as wg
11import matplotlib as mpl
12import math
13import time
14import cPickle
15import GSASIIpath
16import GSASIIimage as G2img
17import GSASIIplot as G2plt
18import GSASIIIO as G2IO
19import GSASIIgrid as G2gd
20
21VERY_LIGHT_GREY = wx.Colour(235,235,235)
22
23# trig functions in degrees
24sind = lambda x: math.sin(x*math.pi/180.)
25tand = lambda x: math.tan(x*math.pi/180.)
26cosd = lambda x: math.cos(x*math.pi/180.)
27asind = lambda x: 180.*math.asin(x)/math.pi
28
29                   
30def UpdateImageControls(self,data,masks):
31    import ImageCalibrants as calFile
32   
33    def OnDataType(event):
34        data['type'] = typeSel.GetValue()[:4]
35   
36    def OnNewColorBar(event):
37        data['color'] = colSel.GetValue()
38        G2plt.PlotExposedImage(self,event=event)
39       
40    def OnNewCalibrant(event):
41        data['calibrant'] = calSel.GetValue()
42        data['calibskip'] = calFile.Calibrants[data['calibrant']][2]
43        limits = calFile.Calibrants[data['calibrant']][3]
44        data['calibdmin'],data['pixLimit'],data['cutoff'] = limits
45        pixLimit.SetValue(str(limits[1]))
46        cutOff.SetValue('%.1f'%(limits[2]))
47        calibSkip.SetValue(str(data['calibskip']))
48        calibDmin.SetValue('%.1f'%(limits[0]))
49       
50    def OnPixLimit(event):
51        data['pixLimit'] = int(pixLimit.GetValue())
52       
53    def OnCalibSkip(event):
54        data['calibskip'] = int(calibSkip.GetValue())
55       
56    def OnSetRings(event):
57        if data['setRings']:
58            data['setRings'] = False
59        else:
60            data['setRings'] = True
61        G2plt.PlotExposedImage(self,event=event)
62
63    def OnCalibDmin(event):
64        try:
65            dmin = float(calibDmin.GetValue())
66            if dmin < 0.25:
67                raise ValueError
68            data['calibdmin'] = dmin
69        except ValueError:
70            pass
71        calibDmin.SetValue("%.2f"%(data['calibdmin']))          #reset in case of error 
72               
73    def OnAzmthOff(event):
74        try:
75            azmthoff = float(azmthOff.GetValue())
76            data['azmthOff'] = azmthoff
77        except ValueError:
78            pass
79        azmthOff.SetValue("%.2f"%(data['azmthOff']))          #reset in case of error 
80       
81    def OnCutOff(event):
82        try:
83            cutoff = float(cutOff.GetValue())
84            if cutoff < 0.1:
85                raise ValueError
86            data['cutoff'] = cutoff
87        except ValueError:
88            pass
89        cutOff.SetValue("%.1f"%(data['cutoff']))          #reset in case of error 
90       
91    def OnMaxVal(event):
92        try:
93            value = min(data['range'][0][1],int(maxVal.GetValue()))
94            if value < data['range'][1][0]+1:
95                raise ValueError
96            data['range'][1][1] = value
97        except ValueError:
98            pass
99        maxVal.SetValue('%.0f'%(data['range'][1][1]))
100        DeltOne = data['range'][1][1]-max(0.0,data['range'][0][0])
101        sqrtDeltOne = math.sqrt(DeltOne)
102        maxSel.SetValue(int(100*sqrtDeltOne/sqrtDeltZero))
103        minSel.SetValue(int(100*(data['range'][1][0]/DeltOne)))
104        G2plt.PlotExposedImage(self,event=event)
105       
106    def OnMinVal(event):
107        try:
108            value = int(minVal.GetValue())
109            if value > data['range'][1][1]-1:
110                raise ValueError
111            data['range'][1][0] = value
112        except ValueError:
113            pass
114        minVal.SetValue('%.0f'%(data['range'][1][0]))
115        minSel.SetValue(int(100*(data['range'][1][0]-max(0.0,data['range'][0][0]))/DeltOne))
116        G2plt.PlotExposedImage(self,event=event)
117       
118    def OnMaxSlider(event):
119        sqrtDeltZero = math.sqrt(data['range'][0][1])
120        imax = int(maxSel.GetValue())*sqrtDeltZero/100.
121        data['range'][1][1] = imax**2
122        data['range'][1][0] = max(0.0,min(data['range'][1][1]-1,data['range'][1][0]))
123        DeltOne = max(1.0,data['range'][1][1]-data['range'][1][0])
124        minSel.SetValue(int(100*(data['range'][1][0]/DeltOne)))
125        maxVal.SetValue('%.0f'%(data['range'][1][1]))
126        G2plt.PlotExposedImage(self,event=event)
127       
128    def OnMinSlider(event):
129        DeltOne = data['range'][1][1]-data['range'][1][0]
130        imin = int(minSel.GetValue())*DeltOne/100.
131        data['range'][1][0] = max(0.0,min(data['range'][1][1]-1,imin))
132        minVal.SetValue('%.0f'%(data['range'][1][0]))
133        G2plt.PlotExposedImage(self,event=event)
134       
135    def OnNumOutChans(event):
136        try:
137            numChans = int(outChan.GetValue())
138            if numChans < 1:
139                raise ValueError
140            data['outChannels'] = numChans
141        except ValueError:
142            pass
143        outChan.SetValue(str(data['outChannels']))          #reset in case of error       
144       
145    def OnNumOutAzms(event):
146        try:
147            numAzms = int(outAzim.GetValue())
148            if numAzms < 1:
149                raise ValueError
150            data['outAzimuths'] = numAzms           
151        except ValueError:
152            pass
153        outAzim.SetValue(str(data['outAzimuths']))          #reset in case of error       
154        G2plt.PlotExposedImage(self,event=event)
155       
156    def OnWavelength(event):
157        try:
158            wave = float(waveSel.GetValue())
159            if wave < .01:
160                raise ValueError
161            data['wavelength'] = wave
162        except ValueError:
163            pass
164        waveSel.SetValue("%6.5f" % (data['wavelength']))          #reset in case of error         
165       
166    def OnShowLines(event):
167        if data['showLines']:
168            data['showLines'] = False
169        else:
170            data['showLines'] = True
171        G2plt.PlotExposedImage(self,event=event)
172       
173    def OnSetDefault(event):
174        import copy
175        if data['setDefault']:
176            self.imageDefault = {}
177            data['setDefault'] = False
178        else:
179            self.imageDefault = copy.copy(data)
180            data['setDefault'] = True
181           
182    def OnIOtth(event):
183        Ltth = max(float(self.InnerTth.GetValue()),0.001)
184        Utth = float(self.OuterTth.GetValue())
185        if Ltth > Utth:
186            Ltth,Utth = Utth,Ltth
187        data['IOtth'] = [Ltth,Utth]
188        self.InnerTth.SetValue("%8.3f" % (Ltth))
189        self.OuterTth.SetValue("%8.2f" % (Utth))
190        G2plt.PlotExposedImage(self,event=event)
191       
192    def OnFullIntegrate(event):
193        Lazm =int(self.Lazim.GetValue())
194        if data['fullIntegrate']:
195            data['fullIntegrate'] = False
196            data['LRazimuth'] = [Lazm,Lazm+20]
197        else:
198            data['fullIntegrate'] = True
199            data['LRazimuth'] = [Lazm,Lazm+360]
200        UpdateImageControls(self,data,masks)           
201        G2plt.PlotExposedImage(self,event=event)
202       
203    def OnLRazim(event):
204        Lazm =int(self.Lazim.GetValue())
205        if data['fullIntegrate']:
206           self.Razim.SetValue("%6d" % (Lazm+360))
207        Razm = int(self.Razim.GetValue())
208        if Lazm > Razm:
209            Lazm -= 360
210        data['LRazimuth'] = [Lazm,Razm]
211        G2plt.PlotExposedImage(self,event=event)
212           
213    def OnClearCalib(event):
214        data['ring'] = []
215        data['rings'] = []
216        data['ellipses'] = []
217        self.dataFrame.ImageEdit.Enable(id=G2gd.wxID_IMCLEARCALIB,enable=False)   
218        G2plt.PlotExposedImage(self,event=event)
219           
220    def OnCalibrate(event):       
221        self.dataFrame.ImageEdit.Enable(id=G2gd.wxID_IMCLEARCALIB,enable=True)   
222        self.dataFrame.GetStatusBar().SetStatusText('Select > 4 points on 1st used ring; LB to pick, RB on point to delete else RB to finish')
223        self.ifGetRing = True
224       
225    def OnIntegrate(event):
226        self.Integrate = G2img.ImageIntegrate(self.ImageZ,data,masks)
227        G2plt.PlotIntegration(self,newPlot=True)
228        G2IO.SaveIntegration(self,self.PickId,data)
229        self.MakePDF.Enable(True)
230       
231    def OnIntegrateAll(event):
232        print 'integrate all'
233        TextList = [[False,'All IMG',0]]
234        Names = []
235        if self.PatternTree.GetCount():
236            id, cookie = self.PatternTree.GetFirstChild(self.root)
237            while id:
238                name = self.PatternTree.GetItemText(id)
239                Names.append(name)
240                if 'IMG' in name:
241                    TextList.append([False,name,id])
242                id, cookie = self.PatternTree.GetNextChild(self.root, cookie)
243            if len(TextList) == 1:
244                self.ErrorDialog('Nothing to integrate','There must some "IMG" patterns')
245                return
246            dlg = self.CopyDialog(self,'Image integration controls','Select images to integrate:',TextList)
247            try:
248                if dlg.ShowModal() == wx.ID_OK:
249                    result = dlg.GetData()
250                    if result[0][0]:                    #the 'All IMG' is True
251                        result = TextList[1:]
252                        for item in result: item[0] = True
253                    for item in result:
254                        ifintegrate,name,id = item
255                        if ifintegrate:
256                            id = G2gd.GetPatternTreeItemId(self, self.root, name)
257                            Npix,imagefile = self.PatternTree.GetItemPyData(id)
258                            image = G2IO.GetImageData(self,imagefile,True)
259                            Id = G2gd.GetPatternTreeItemId(self,id, 'Image Controls')
260                            Data = self.PatternTree.GetItemPyData(Id)
261                            try:
262                                Masks = self.PatternTree.GetItemPyData(
263                                    G2gd.GetPatternTreeItemId(self,self.Image, 'Masks'))
264                            except TypeError:       #missing Masks
265                                Imin,Imax = Data['Range']
266                                Masks = {'Points':[],'Rings':[],'Arcs':[],'Polygons':[],'Thresholds':[(Imin,Imax),[Imin,Imax]]}
267                                self.PatternTree.SetItemPyData(
268                                    G2gd.GetPatternTreeItemId(self,self.Image, 'Masks'),Masks)                               
269                            self.Integrate = G2img.ImageIntegrate(image,Data,Masks)
270#                            G2plt.PlotIntegration(self,newPlot=True,event=event)
271                            G2IO.SaveIntegration(self,Id,Data)
272            finally:
273                dlg.Destroy()
274       
275    def OnCopyControls(event):
276        import copy
277        TextList = [[False,'All IMG',0]]
278        Names = []
279        if self.PatternTree.GetCount():
280            id, cookie = self.PatternTree.GetFirstChild(self.root)
281            while id:
282                name = self.PatternTree.GetItemText(id)
283                Names.append(name)
284                if 'IMG' in name:
285                    if id == self.Image:
286                        Source = name
287                        Data = copy.deepcopy(self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,id, 'Image Controls')))
288                        Data['showLines'] = True
289                        Data['ring'] = []
290                        Data['rings'] = []
291                        Data['ellipses'] = []
292                        Data['setDefault'] = False
293                    else:
294                        TextList.append([False,name,id])
295                id, cookie = self.PatternTree.GetNextChild(self.root, cookie)
296            if len(TextList) == 1:
297                self.ErrorDialog('Nothing to copy controls to','There must be more than one "IMG" pattern')
298                return
299            dlg = self.CopyDialog(self,'Copy image controls','Copy controls from '+Source+' to:',TextList)
300            try:
301                if dlg.ShowModal() == wx.ID_OK:
302                    result = dlg.GetData()
303                    if result[0][0]:
304                        result = TextList[1:]
305                        for item in result: item[0] = True
306                    for i,item in enumerate(result):
307                        ifcopy,name,id = item
308                        if ifcopy:
309                            oldData = copy.deepcopy(self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,id, 'Image Controls')))
310                            Data['range'] = oldData['range']
311                            Data['size'] = oldData['size']                               
312                            Data['ring'] = []
313                            Data['rings'] = []
314                            Data['ellipses'] = []
315                            self.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(self,id, 'Image Controls'),copy.deepcopy(Data))
316            finally:
317                dlg.Destroy()
318               
319    def OnSaveControls(event):
320        dlg = wx.FileDialog(self, 'Choose image controls file', '.', '', 
321            'image control files (*.imctrl)|*.imctrl',wx.OPEN)
322        if self.dirname:
323            dlg.SetDirectory(self.dirname)
324        try:
325            if dlg.ShowModal() == wx.ID_OK:
326                filename = dlg.GetPath()
327                File = open(filename,'w')
328                save = {}
329                keys = ['type','wavelength','calibrant','distance','center',
330                    'tilt','rotation','azmthOff','fullIntegrate','LRazimuth',
331                    'IOtth','outAzimuths']
332                for key in keys:
333                    File.write(key+':'+str(data[key])+'\n')
334                File.close()
335        finally:
336            dlg.Destroy()
337       
338    def OnLoadControls(event):
339        cntlList = ['wavelength','distance','tilt','rotation',
340            'fullIntegrate','outAzimuths','LRazimuth','IOtth']
341        dlg = wx.FileDialog(self, 'Choose image controls file', '.', '', 
342            'image control files (*.imctrl)|*.imctrl',wx.OPEN)
343        if self.dirname:
344            dlg.SetDirectory(self.dirname)
345        try:
346            if dlg.ShowModal() == wx.ID_OK:
347                filename = dlg.GetPath()
348                File = open(filename,'r')
349                save = {}
350                S = File.readline()
351                while S:
352                    if S[0] == '#':
353                        S = File.readline()
354                        continue
355                    [key,val] = S[:-1].split(':')
356                    if key in ['type','calibrant',]:
357                        save[key] = val
358                    elif key in ['center',]:
359                        if ',' in val:
360                            save[key] = eval(val)
361                        else:
362                            vals = val.strip('[] ').split()
363                            save[key] = [float(vals[0]),float(vals[1])] 
364                    elif key in cntlList:
365                        save[key] = eval(val)
366                    S = File.readline()
367                data.update(save)
368                UpdateImageControls(self,data,masks)           
369                G2plt.PlotExposedImage(self,event=event)
370               
371                File.close()
372        finally:
373            dlg.Destroy()
374                                       
375    #fix for old files:
376    if 'azmthOff' not in data:
377        data['azmthOff'] = 0.0
378    #end fix
379   
380    colorList = [m for m in mpl.cm.datad.keys() if not m.endswith("_r")]
381    calList = [m for m in calFile.Calibrants.keys()]
382    typeList = ['PWDR - powder diffraction data','SASD - small angle scattering data',
383        'REFL - reflectometry data']
384    if not data.get('type'):                        #patch for old project files
385        data['type'] = 'PWDR'
386    typeDict = {'PWDR':typeList[0],'SASD':typeList[1],'REFL':typeList[2]}
387    if self.dataDisplay:
388        self.dataDisplay.Destroy()
389    self.dataFrame.SetMenuBar(self.dataFrame.ImageMenu)
390    if not self.dataFrame.GetStatusBar():
391        self.dataFrame.CreateStatusBar()
392    self.dataFrame.Bind(wx.EVT_MENU, OnCalibrate, id=G2gd.wxID_IMCALIBRATE)
393    self.dataFrame.Bind(wx.EVT_MENU, OnClearCalib, id=G2gd.wxID_IMCLEARCALIB)
394    if not data['rings']:
395        self.dataFrame.ImageEdit.Enable(id=G2gd.wxID_IMCLEARCALIB,enable=False)   
396    self.dataFrame.Bind(wx.EVT_MENU, OnIntegrate, id=G2gd.wxID_IMINTEGRATE)
397    self.dataFrame.Bind(wx.EVT_MENU, OnIntegrateAll, id=G2gd.wxID_INTEGRATEALL)
398    self.dataFrame.Bind(wx.EVT_MENU, OnCopyControls, id=G2gd.wxID_IMCOPYCONTROLS)
399    self.dataFrame.Bind(wx.EVT_MENU, OnSaveControls, id=G2gd.wxID_IMSAVECONTROLS)
400    self.dataFrame.Bind(wx.EVT_MENU, OnLoadControls, id=G2gd.wxID_IMLOADCONTROLS)
401    self.dataDisplay = wx.Panel(self.dataFrame)
402    mainSizer = wx.BoxSizer(wx.VERTICAL)
403    mainSizer.Add((5,10),0)
404   
405    comboSizer = wx.BoxSizer(wx.HORIZONTAL)
406    comboSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Type of image data: '),0,
407        wx.ALIGN_CENTER_VERTICAL)
408    typeSel = wx.ComboBox(parent=self.dataDisplay,value=typeDict[data['type']],choices=typeList,
409        style=wx.CB_READONLY|wx.CB_DROPDOWN)
410    typeSel.SetValue(data['type'])
411    typeSel.Bind(wx.EVT_COMBOBOX, OnDataType)
412    comboSizer.Add(typeSel,0,wx.ALIGN_CENTER_VERTICAL)
413    comboSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Color bar '),0,
414        wx.ALIGN_CENTER_VERTICAL)
415    colSel = wx.ComboBox(parent=self.dataDisplay,value=data['color'],choices=colorList,
416        style=wx.CB_READONLY|wx.CB_DROPDOWN|wx.CB_SORT)
417    colSel.Bind(wx.EVT_COMBOBOX, OnNewColorBar)
418    comboSizer.Add(colSel,0,wx.ALIGN_CENTER_VERTICAL)
419    comboSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Azimuth offset '),0,
420        wx.ALIGN_CENTER_VERTICAL)
421    azmthOff = wx.TextCtrl(parent=self.dataDisplay,value=("%.2f" % (data['azmthOff'])),
422        style=wx.TE_PROCESS_ENTER)
423    azmthOff.Bind(wx.EVT_TEXT_ENTER,OnAzmthOff)
424    azmthOff.Bind(wx.EVT_KILL_FOCUS,OnAzmthOff)
425    comboSizer.Add(azmthOff,0,wx.ALIGN_CENTER_VERTICAL)
426    mainSizer.Add(comboSizer,0,wx.ALIGN_LEFT)
427    mainSizer.Add((5,5),0)
428           
429    maxSizer = wx.FlexGridSizer(2,3,0,5)
430    maxSizer.AddGrowableCol(1,1)
431    maxSizer.SetFlexibleDirection(wx.HORIZONTAL)
432    sqrtDeltZero = math.sqrt(data['range'][0][1]-max(0.0,data['range'][0][0]))
433    DeltOne = data['range'][1][1]-max(0.0,data['range'][0][0])
434    sqrtDeltOne = math.sqrt(DeltOne)
435    maxSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Max intensity'),0,
436        wx.ALIGN_CENTER_VERTICAL)
437    maxSel = wx.Slider(parent=self.dataDisplay,style=wx.SL_HORIZONTAL,
438        value=int(100*sqrtDeltOne/sqrtDeltZero))
439    maxSizer.Add(maxSel,1,wx.EXPAND)
440    maxSel.Bind(wx.EVT_SLIDER, OnMaxSlider)
441    maxVal = wx.TextCtrl(parent=self.dataDisplay,value='%.0f'%(data['range'][1][1]))
442    maxVal.Bind(wx.EVT_TEXT_ENTER,OnMaxVal)   
443    maxVal.Bind(wx.EVT_KILL_FOCUS,OnMaxVal)
444    maxSizer.Add(maxVal,0,wx.ALIGN_CENTER_VERTICAL)   
445    maxSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Min intensity'),0,
446        wx.ALIGN_CENTER_VERTICAL)
447    minSel = wx.Slider(parent=self.dataDisplay,style=wx.SL_HORIZONTAL,
448        value=int(100*(data['range'][1][0]-max(0.0,data['range'][0][0]))/DeltOne))
449    maxSizer.Add(minSel,1,wx.EXPAND)
450    minSel.Bind(wx.EVT_SLIDER, OnMinSlider)
451    minVal = wx.TextCtrl(parent=self.dataDisplay,value='%.0f'%(data['range'][1][0]))
452    minVal.Bind(wx.EVT_TEXT_ENTER,OnMinVal)   
453    minVal.Bind(wx.EVT_KILL_FOCUS,OnMinVal)
454    maxSizer.Add(minVal,0,wx.ALIGN_CENTER_VERTICAL)   
455    mainSizer.Add(maxSizer,0,wx.ALIGN_LEFT|wx.EXPAND)
456   
457    dataSizer = wx.FlexGridSizer(6,4,5,5)
458    dataSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Calibration coefficients'),0,
459        wx.ALIGN_CENTER_VERTICAL)   
460    dataSizer.Add((5,0),0)
461    dataSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Integration coefficients'),0,
462        wx.ALIGN_CENTER_VERTICAL)   
463    dataSizer.Add((5,0),0)
464   
465    dataSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Beam center X,Y'),0,
466        wx.ALIGN_CENTER_VERTICAL)
467    cent = data['center']
468    centText = wx.TextCtrl(parent=self.dataDisplay,value=("%8.3f,%8.3f" % (cent[0],cent[1])),style=wx.TE_READONLY)
469    centText.SetBackgroundColour(VERY_LIGHT_GREY)
470    dataSizer.Add(centText,0,wx.ALIGN_CENTER_VERTICAL)
471   
472    dataSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Inner/Outer 2-theta'),0,
473        wx.ALIGN_CENTER_VERTICAL)
474       
475    IOtth = data['IOtth']
476    littleSizer = wx.BoxSizer(wx.HORIZONTAL)
477    self.InnerTth = wx.TextCtrl(parent=self.dataDisplay,
478        value=("%8.3f" % (IOtth[0])),style=wx.TE_PROCESS_ENTER)
479    self.InnerTth.Bind(wx.EVT_TEXT_ENTER,OnIOtth)
480    self.InnerTth.Bind(wx.EVT_KILL_FOCUS,OnIOtth)
481    littleSizer.Add(self.InnerTth,0,wx.ALIGN_CENTER_VERTICAL)
482    self.OuterTth = wx.TextCtrl(parent=self.dataDisplay,
483        value=("%8.2f" % (IOtth[1])),style=wx.TE_PROCESS_ENTER)
484    self.OuterTth.Bind(wx.EVT_TEXT_ENTER,OnIOtth)
485    self.OuterTth.Bind(wx.EVT_KILL_FOCUS,OnIOtth)
486    littleSizer.Add(self.OuterTth,0,wx.ALIGN_CENTER_VERTICAL)
487    dataSizer.Add(littleSizer,0,)
488       
489    dataSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Wavelength'),0,
490        wx.ALIGN_CENTER_VERTICAL)
491    waveSel = wx.TextCtrl(parent=self.dataDisplay,value=("%6.5f" % (data['wavelength'])),
492        style=wx.TE_PROCESS_ENTER)
493    waveSel.Bind(wx.EVT_TEXT_ENTER,OnWavelength)
494    waveSel.Bind(wx.EVT_KILL_FOCUS,OnWavelength)
495    dataSizer.Add(waveSel,0,wx.ALIGN_CENTER_VERTICAL)
496         
497    dataSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Start/End azimuth'),0,
498        wx.ALIGN_CENTER_VERTICAL)
499    LRazim = data['LRazimuth']
500    littleSizer = wx.BoxSizer(wx.HORIZONTAL)
501    self.Lazim = wx.TextCtrl(parent=self.dataDisplay,
502        value=("%6d" % (LRazim[0])),style=wx.TE_PROCESS_ENTER)
503    self.Lazim.Bind(wx.EVT_TEXT_ENTER,OnLRazim)
504    self.Lazim.Bind(wx.EVT_KILL_FOCUS,OnLRazim)
505    littleSizer.Add(self.Lazim,0,wx.ALIGN_CENTER_VERTICAL)
506    self.Razim = wx.TextCtrl(parent=self.dataDisplay,
507        value=("%6d" % (LRazim[1])),style=wx.TE_PROCESS_ENTER)
508    self.Razim.Bind(wx.EVT_TEXT_ENTER,OnLRazim)
509    self.Razim.Bind(wx.EVT_KILL_FOCUS,OnLRazim)
510    if data['fullIntegrate']:
511        self.Razim.Enable(False)
512        self.Razim.SetBackgroundColour(VERY_LIGHT_GREY)
513        self.Razim.SetValue("%6d" % (LRazim[0]+360))
514    littleSizer.Add(self.Razim,0,wx.ALIGN_CENTER_VERTICAL)
515    dataSizer.Add(littleSizer,0,)
516       
517    dataSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Distance'),0,
518        wx.ALIGN_CENTER_VERTICAL)
519    distSel = wx.TextCtrl(parent=self.dataDisplay,value=("%8.3f"%(data['distance'])),style=wx.TE_READONLY)
520    distSel.SetBackgroundColour(VERY_LIGHT_GREY)
521    dataSizer.Add(distSel,0,wx.ALIGN_CENTER_VERTICAL)
522
523    dataSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' No. 2-theta/azimuth bins'),0,
524        wx.ALIGN_CENTER_VERTICAL)
525    littleSizer = wx.BoxSizer(wx.HORIZONTAL)
526    outChan = wx.TextCtrl(parent=self.dataDisplay,value=str(data['outChannels']),style=wx.TE_PROCESS_ENTER)
527    outChan.Bind(wx.EVT_TEXT_ENTER,OnNumOutChans)
528    outChan.Bind(wx.EVT_KILL_FOCUS,OnNumOutChans)
529    littleSizer.Add(outChan,0,wx.ALIGN_CENTER_VERTICAL)
530    outAzim = wx.TextCtrl(parent=self.dataDisplay,value=str(data['outAzimuths']),style=wx.TE_PROCESS_ENTER)
531    outAzim.Bind(wx.EVT_TEXT_ENTER,OnNumOutAzms)
532    outAzim.Bind(wx.EVT_KILL_FOCUS,OnNumOutAzms)
533    littleSizer.Add(outAzim,0,wx.ALIGN_CENTER_VERTICAL)
534    dataSizer.Add(littleSizer,0,)
535
536    dataSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Tilt angle'),0,
537        wx.ALIGN_CENTER_VERTICAL)
538    tiltSel = wx.TextCtrl(parent=self.dataDisplay,value=("%9.3f"%(data['tilt'])),style=wx.TE_READONLY)
539    tiltSel.SetBackgroundColour(VERY_LIGHT_GREY)
540    dataSizer.Add(tiltSel,0,wx.ALIGN_CENTER_VERTICAL)
541    showLines = wx.CheckBox(parent=self.dataDisplay,label='Show integration limits?')
542    dataSizer.Add(showLines,0,wx.ALIGN_CENTER_VERTICAL)
543    showLines.Bind(wx.EVT_CHECKBOX, OnShowLines)
544    showLines.SetValue(data['showLines'])
545    fullIntegrate = wx.CheckBox(parent=self.dataDisplay,label='Do full integration?')
546    dataSizer.Add(fullIntegrate,0,wx.ALIGN_CENTER_VERTICAL)
547    fullIntegrate.Bind(wx.EVT_CHECKBOX, OnFullIntegrate)
548    fullIntegrate.SetValue(data['fullIntegrate'])
549   
550    dataSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Tilt rotation'),0,
551        wx.ALIGN_CENTER_VERTICAL)
552    rotSel = wx.TextCtrl(parent=self.dataDisplay,value=("%9.3f"%(data['rotation']-90.)),style=wx.TE_READONLY)
553    rotSel.SetBackgroundColour(VERY_LIGHT_GREY)
554    dataSizer.Add(rotSel,0,wx.ALIGN_CENTER_VERTICAL)
555    setDefault = wx.CheckBox(parent=self.dataDisplay,label='Use as default for all images?')
556    dataSizer.Add(setDefault,0,wx.ALIGN_CENTER_VERTICAL)
557    setDefault.Bind(wx.EVT_CHECKBOX, OnSetDefault)
558    setDefault.SetValue(data['setDefault'])
559
560    mainSizer.Add((5,5),0)       
561    mainSizer.Add(dataSizer,0)
562    mainSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Calibration controls:'),0,
563        wx.ALIGN_CENTER_VERTICAL)
564    mainSizer.Add((5,5),0)
565    calibSizer = wx.FlexGridSizer(2,3,5,5)
566    comboSizer = wx.BoxSizer(wx.HORIZONTAL)   
567    comboSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Calibrant '),0,
568        wx.ALIGN_CENTER_VERTICAL)
569    calSel = wx.ComboBox(parent=self.dataDisplay,value=data['calibrant'],choices=calList,
570        style=wx.CB_READONLY|wx.CB_DROPDOWN|wx.CB_SORT)
571    calSel.Bind(wx.EVT_COMBOBOX, OnNewCalibrant)
572    comboSizer.Add(calSel,0,wx.ALIGN_CENTER_VERTICAL)
573    calibSizer.Add(comboSizer,0)
574   
575    comboSizer = wx.BoxSizer(wx.HORIZONTAL)   
576    comboSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Calib lines to skip   '),0,
577        wx.ALIGN_CENTER_VERTICAL)
578    calibSkip  = wx.ComboBox(parent=self.dataDisplay,value=str(data['calibskip']),choices=['0','1','2','3','4','5','6','7','8','9','10'],
579        style=wx.CB_READONLY|wx.CB_DROPDOWN)
580    calibSkip.Bind(wx.EVT_COMBOBOX, OnCalibSkip)
581    comboSizer.Add(calibSkip,0,wx.ALIGN_CENTER_VERTICAL)
582    calibSizer.Add(comboSizer,0)
583   
584    comboSizer = wx.BoxSizer(wx.HORIZONTAL)       
585    comboSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Min calib d-spacing '),0,
586        wx.ALIGN_CENTER_VERTICAL)
587    calibDmin = wx.TextCtrl(parent=self.dataDisplay,value=("%.2f" % (data['calibdmin'])),
588        style=wx.TE_PROCESS_ENTER)
589    calibDmin.Bind(wx.EVT_TEXT_ENTER,OnCalibDmin)
590    calibDmin.Bind(wx.EVT_KILL_FOCUS,OnCalibDmin)
591    comboSizer.Add(calibDmin,0,wx.ALIGN_CENTER_VERTICAL)
592    calibSizer.Add(comboSizer,0)
593   
594    comboSizer = wx.BoxSizer(wx.HORIZONTAL)
595    comboSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Min ring I/Ib '),0,
596        wx.ALIGN_CENTER_VERTICAL)
597    cutOff = wx.TextCtrl(parent=self.dataDisplay,value=("%.1f" % (data['cutoff'])),
598        style=wx.TE_PROCESS_ENTER)
599    cutOff.Bind(wx.EVT_TEXT_ENTER,OnCutOff)
600    cutOff.Bind(wx.EVT_KILL_FOCUS,OnCutOff)
601    comboSizer.Add(cutOff,0,wx.ALIGN_CENTER_VERTICAL)
602    calibSizer.Add(comboSizer,0)
603   
604    comboSizer = wx.BoxSizer(wx.HORIZONTAL)
605    comboSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Pixel search range '),0,
606        wx.ALIGN_CENTER_VERTICAL)
607    pixLimit = wx.ComboBox(parent=self.dataDisplay,value=str(data['pixLimit']),choices=['1','2','5','10','15','20'],
608        style=wx.CB_READONLY|wx.CB_DROPDOWN)
609    pixLimit.Bind(wx.EVT_COMBOBOX, OnPixLimit)
610    comboSizer.Add(pixLimit,0,wx.ALIGN_CENTER_VERTICAL)
611    calibSizer.Add(comboSizer,0)
612   
613    comboSizer = wx.BoxSizer(wx.HORIZONTAL)
614    setRings = wx.CheckBox(parent=self.dataDisplay,label='Show ring picks?')
615    comboSizer.Add(setRings,0)
616    setRings.Bind(wx.EVT_CHECKBOX, OnSetRings)
617    setRings.SetValue(data['setRings'])
618    calibSizer.Add(comboSizer,0)
619   
620    mainSizer.Add(calibSizer,0,wx.ALIGN_CENTER_VERTICAL)
621       
622    mainSizer.Layout()   
623    self.dataDisplay.SetSizer(mainSizer)
624    fitSize = mainSizer.Fit(self.dataFrame)
625    self.dataFrame.setSizePosLeft(fitSize)
626    self.dataDisplay.SetSize(fitSize)
627   
628def UpdateMasks(self,data):
629   
630    def OnTextMsg(event):
631        Obj = event.GetEventObject()
632        Obj.SetToolTipString('Drag this mask on 2D Powder Image with mouse to change ')
633       
634    def OnThreshold(event):
635        try:
636            lower = max(int(lowerThreshold.GetValue()),thresh[0][0])
637        except ValueError:
638            lower = thresh[0][0]
639        try:
640            upper = min(int(upperThreshold.GetValue()),thresh[0][1])
641        except ValueError:
642            upper = thresh[0][1]
643        data['Thresholds'][1] = [lower,upper]
644        lowerThreshold.SetValue("%8d" % (lower))
645        upperThreshold.SetValue("%8d" % (upper))
646        G2plt.PlotExposedImage(self,event=event)
647       
648    def OnSpotDiameter(event):
649        Obj = event.GetEventObject()
650        try:
651            diameter = min(100.,max(0.1,float(Obj.GetValue())))
652        except ValueError:
653            diameter = 1.0
654        Obj.SetValue("%.2f"%(diameter))
655        data['Points'][spotIds.index(Obj.GetId())][2] = diameter
656        G2plt.PlotExposedImage(self,event=event)
657       
658    def OnDeleteSpot(event):
659        Obj = event.GetEventObject()
660        del(data['Points'][delSpotId.index(Obj)])
661        UpdateMasks(self,data)           
662        G2plt.PlotExposedImage(self,event=event)
663       
664    def OnRingThickness(event):
665        Obj = event.GetEventObject()
666        try:
667            thick = min(1.0,max(0.001,float(Obj.GetValue())))
668        except ValueError:
669            thick = 0.1
670        Obj.SetValue("%.3f"%(thick))
671        data['Rings'][ringIds.index(Obj.GetId())][1] = thick
672        G2plt.PlotExposedImage(self,event=event)
673       
674    def OnDeleteRing(event):
675        Obj = event.GetEventObject()
676        del(data['Rings'][delRingId.index(Obj)])
677        UpdateMasks(self,data)           
678        G2plt.PlotExposedImage(self,event=event)
679
680    def OnArcThickness(event):
681        Obj = event.GetEventObject()
682        try:
683            thick = min(20.0,max(0.001,float(Obj.GetValue())))
684        except ValueError:
685            thick = 0.1
686        Obj.SetValue("%.3f"%(thick))
687        data['Arcs'][arcIds.index(Obj.GetId())][2] = thick
688        G2plt.PlotExposedImage(self,event=event)
689       
690    def OnDeleteArc(event):
691        Obj = event.GetEventObject()
692        del(data['Arcs'][delArcId.index(Obj)])
693        UpdateMasks(self,data)           
694        G2plt.PlotExposedImage(self,event=event)
695
696    def OnDeletePoly(event):
697        Obj = event.GetEventObject()
698        del(data['Polygons'][delPolyId.index(Obj)])
699        UpdateMasks(self,data)           
700        G2plt.PlotExposedImage(self,event=event)
701
702    def OnCopyMask(event):
703        import copy
704        TextList = [[False,'All IMG',0]]
705        Names = []
706        if self.PatternTree.GetCount():
707            id, cookie = self.PatternTree.GetFirstChild(self.root)
708            while id:
709                name = self.PatternTree.GetItemText(id)
710                Names.append(name)
711                if 'IMG' in name:
712                    if id == self.Image:
713                        Source = name
714                        Mask = copy.deepcopy(self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,id, 'Masks')))
715                        del Mask['Thresholds']
716                    else:
717                        TextList.append([False,name,id])
718                id, cookie = self.PatternTree.GetNextChild(self.root, cookie)
719            if len(TextList) == 1:
720                self.ErrorDialog('Nothing to copy mask to','There must be more than one "IMG" pattern')
721                return
722            dlg = self.CopyDialog(self,'Copy mask information','Copy mask from '+Source+' to:',TextList)
723            try:
724                if dlg.ShowModal() == wx.ID_OK:
725                    result = dlg.GetData()
726                    if result[0][0]:
727                        result = TextList[1:]
728                        for item in result: item[0] = True
729                    for i,item in enumerate(result):
730                        ifcopy,name,id = item
731                        if ifcopy:
732                            mask = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,id, 'Masks'))
733                            mask.update(Mask)                               
734                            self.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(self,id, 'Masks'),copy.deepcopy(mask))
735            finally:
736                dlg.Destroy()
737               
738    def OnSaveMask(event):
739        dlg = wx.FileDialog(self, 'Choose image mask file', '.', '', 
740            'image mask files (*.immask)|*.immask',wx.OPEN)
741        if self.dirname:
742            dlg.SetDirectory(self.dirname)
743        try:
744            if dlg.ShowModal() == wx.ID_OK:
745                filename = dlg.GetPath()
746                File = open(filename,'w')
747                save = {}
748                keys = ['Points','Rings','Arcs','Polygons','Thresholds']
749                for key in keys:
750                    File.write(key+':'+str(data[key])+'\n')
751                File.close()
752        finally:
753            dlg.Destroy()
754       
755    def OnLoadMask(event):
756        dlg = wx.FileDialog(self, 'Choose image mask file', '.', '', 
757            'image mask files (*.immask)|*.immask',wx.OPEN)
758        if self.dirname:
759            dlg.SetDirectory(self.dirname)
760        try:
761            if dlg.ShowModal() == wx.ID_OK:
762                filename = dlg.GetPath()
763                File = open(filename,'r')
764                save = {}
765                S = File.readline()
766                while S:
767                    if S[0] == '#':
768                        S = File.readline()
769                        continue
770                    [key,val] = S[:-1].split(':')
771                    if key in ['Points','Rings','Arcs','Polygons','Thresholds']:
772                        save[key] = eval(val)
773                    S = File.readline()
774                data.update(save)
775                UpdateMasks(self,data)           
776                G2plt.PlotExposedImage(self,event=event)
777               
778                File.close()
779        finally:
780            dlg.Destroy()
781       
782    if self.dataDisplay:
783        self.dataDisplay.Destroy()
784    self.dataFrame.SetMenuBar(self.dataFrame.MaskMenu)
785    self.dataFrame.Bind(wx.EVT_MENU, OnCopyMask, id=G2gd.wxID_MASKCOPY)
786    self.dataFrame.Bind(wx.EVT_MENU, OnLoadMask, id=G2gd.wxID_MASKLOAD)
787    self.dataFrame.Bind(wx.EVT_MENU, OnSaveMask, id=G2gd.wxID_MASKSAVE)   
788    if not self.dataFrame.GetStatusBar():
789        Status = self.dataFrame.CreateStatusBar()
790        Status.SetStatusText("To add mask: On 2D Powder Image, key a:arc, r:ring, s:spot, p:polygon")
791    self.dataDisplay = wx.Panel(self.dataFrame)
792    mainSizer = wx.BoxSizer(wx.VERTICAL)
793    mainSizer.Add((5,10),0)
794
795    thresh = data['Thresholds']         #min/max intensity range
796    spots = data['Points']               #x,y,radius in mm
797    rings = data['Rings']               #radius, thickness
798    polygons = data['Polygons']         #3+ x,y pairs
799    arcs = data['Arcs']                 #radius, start/end azimuth, thickness
800   
801    littleSizer = wx.FlexGridSizer(2,3,0,5)
802    littleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Lower/Upper limits '),0,
803        wx.ALIGN_CENTER_VERTICAL)
804    Text = wx.TextCtrl(self.dataDisplay,value=("%8d" % (thresh[0][0])),style=wx.TE_READONLY)
805    littleSizer.Add(Text,0,wx.ALIGN_CENTER_VERTICAL)
806    Text.SetBackgroundColour(VERY_LIGHT_GREY)
807    Text = wx.TextCtrl(self.dataDisplay,value=("%8d" % (thresh[0][1])),style=wx.TE_READONLY)
808    littleSizer.Add(Text,0,wx.ALIGN_CENTER_VERTICAL)
809    Text.SetBackgroundColour(VERY_LIGHT_GREY)
810    littleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Lower/Upper thresholds '),
811        0,wx.ALIGN_CENTER_VERTICAL)
812    lowerThreshold = wx.TextCtrl(parent=self.dataDisplay,
813        value=("%8d" % (thresh[1][0])),style=wx.TE_PROCESS_ENTER)
814    lowerThreshold.Bind(wx.EVT_TEXT_ENTER,OnThreshold)
815    lowerThreshold.Bind(wx.EVT_KILL_FOCUS,OnThreshold)
816    littleSizer.Add(lowerThreshold,0,wx.ALIGN_CENTER_VERTICAL)
817    upperThreshold = wx.TextCtrl(parent=self.dataDisplay,
818        value=("%8d" % (thresh[1][1])),style=wx.TE_PROCESS_ENTER)
819    upperThreshold.Bind(wx.EVT_TEXT_ENTER,OnThreshold)
820    upperThreshold.Bind(wx.EVT_KILL_FOCUS,OnThreshold)
821    littleSizer.Add(upperThreshold,0,wx.ALIGN_CENTER_VERTICAL)
822    mainSizer.Add(littleSizer,0,)
823    spotIds = []
824    delSpotId = []
825    if spots:
826        littleSizer = wx.FlexGridSizer(len(spots)+2,3,0,5)
827        littleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Spot masks:'),0,
828            wx.ALIGN_CENTER_VERTICAL)
829        littleSizer.Add((5,0),0)
830        littleSizer.Add((5,0),0)
831        littleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' position, mm'),0,
832            wx.ALIGN_CENTER_VERTICAL)
833        littleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' diameter, mm'),0,
834            wx.ALIGN_CENTER_VERTICAL)
835        littleSizer.Add((5,0),0)
836        for x,y,d in spots:
837            spotText = wx.TextCtrl(parent=self.dataDisplay,value=("%.2f,%.2f" % (x,y)),
838                style=wx.TE_READONLY)
839            spotText.SetBackgroundColour(VERY_LIGHT_GREY)
840            littleSizer.Add(spotText,0,wx.ALIGN_CENTER_VERTICAL)
841            spotText.Bind(wx.EVT_ENTER_WINDOW,OnTextMsg)
842            spotDiameter = wx.TextCtrl(parent=self.dataDisplay,value=("%.2f" % (d)),
843                style=wx.TE_PROCESS_ENTER)
844            littleSizer.Add(spotDiameter,0,wx.ALIGN_CENTER_VERTICAL)
845            spotDiameter.Bind(wx.EVT_TEXT_ENTER,OnSpotDiameter)
846            spotDiameter.Bind(wx.EVT_KILL_FOCUS,OnSpotDiameter)
847            spotIds.append(spotDiameter.GetId())
848            spotDelete = wx.CheckBox(parent=self.dataDisplay,label='delete?')
849            spotDelete.Bind(wx.EVT_CHECKBOX,OnDeleteSpot)
850            delSpotId.append(spotDelete)
851            littleSizer.Add(spotDelete,0,wx.ALIGN_CENTER_VERTICAL)
852        mainSizer.Add(littleSizer,0,)
853    ringIds = []
854    delRingId = []
855    if rings:
856        littleSizer = wx.FlexGridSizer(len(rings)+2,3,0,5)
857        littleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Ring masks:'),0,
858            wx.ALIGN_CENTER_VERTICAL)
859        littleSizer.Add((5,0),0)
860        littleSizer.Add((5,0),0)
861        littleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' 2-theta,deg'),0,
862            wx.ALIGN_CENTER_VERTICAL)
863        littleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' thickness, deg'),0,
864            wx.ALIGN_CENTER_VERTICAL)
865        littleSizer.Add((5,0),0)
866        for tth,thick in rings:
867            ringText = wx.TextCtrl(parent=self.dataDisplay,value=("%.3f" % (tth)),
868                style=wx.TE_READONLY)
869            ringText.SetBackgroundColour(VERY_LIGHT_GREY)
870            ringText.Bind(wx.EVT_ENTER_WINDOW,OnTextMsg)
871            littleSizer.Add(ringText,0,wx.ALIGN_CENTER_VERTICAL)
872            ringThick = wx.TextCtrl(parent=self.dataDisplay,value=("%.3f" % (thick)),
873                style=wx.TE_PROCESS_ENTER)
874            littleSizer.Add(ringThick,0,wx.ALIGN_CENTER_VERTICAL)
875            ringThick.Bind(wx.EVT_TEXT_ENTER,OnRingThickness)
876            ringThick.Bind(wx.EVT_KILL_FOCUS,OnRingThickness)
877            ringIds.append(ringThick.GetId())
878            ringDelete = wx.CheckBox(parent=self.dataDisplay,label='delete?')
879            ringDelete.Bind(wx.EVT_CHECKBOX,OnDeleteRing)
880            delRingId.append(ringDelete)
881            littleSizer.Add(ringDelete,0,wx.ALIGN_CENTER_VERTICAL)
882        mainSizer.Add(littleSizer,0,)
883    arcIds = []
884    delArcId = []
885    if arcs:
886        littleSizer = wx.FlexGridSizer(len(rings)+2,4,0,5)
887        littleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Arc masks:'),0,
888            wx.ALIGN_CENTER_VERTICAL)
889        littleSizer.Add((5,0),0)
890        littleSizer.Add((5,0),0)
891        littleSizer.Add((5,0),0)
892        littleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' 2-theta,deg'),0,
893            wx.ALIGN_CENTER_VERTICAL)
894        littleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' azimuth, deg'),0,
895            wx.ALIGN_CENTER_VERTICAL)
896        littleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' thickness, deg'),0,
897            wx.ALIGN_CENTER_VERTICAL)
898        littleSizer.Add((5,0),0)
899        for tth,azimuth,thick in arcs:
900            arcText = wx.TextCtrl(parent=self.dataDisplay,value=("%.3f" % (tth)),
901                style=wx.TE_READONLY)
902            arcText.SetBackgroundColour(VERY_LIGHT_GREY)
903            arcText.Bind(wx.EVT_ENTER_WINDOW,OnTextMsg)
904            littleSizer.Add(arcText,0,wx.ALIGN_CENTER_VERTICAL)
905            azmText = wx.TextCtrl(parent=self.dataDisplay,value=("%d,%d" % (azimuth[0],azimuth[1])),
906                style=wx.TE_READONLY)
907            azmText.SetBackgroundColour(VERY_LIGHT_GREY)
908            azmText.Bind(wx.EVT_ENTER_WINDOW,OnTextMsg)
909            littleSizer.Add(azmText,0,wx.ALIGN_CENTER_VERTICAL)
910            arcThick = wx.TextCtrl(parent=self.dataDisplay,value=("%.3f" % (thick)),
911                style=wx.TE_PROCESS_ENTER)
912            littleSizer.Add(arcThick,0,wx.ALIGN_CENTER_VERTICAL)
913            arcThick.Bind(wx.EVT_TEXT_ENTER,OnArcThickness)
914            arcThick.Bind(wx.EVT_KILL_FOCUS,OnArcThickness)
915            arcIds.append(arcThick.GetId())
916            arcDelete = wx.CheckBox(parent=self.dataDisplay,label='delete?')
917            arcDelete.Bind(wx.EVT_CHECKBOX,OnDeleteArc)
918            delArcId.append(arcDelete)
919            littleSizer.Add(arcDelete,0,wx.ALIGN_CENTER_VERTICAL)
920        mainSizer.Add(littleSizer,0,)
921    polyIds = []
922    delPolyId = []
923    if polygons:
924        littleSizer = wx.FlexGridSizer(len(polygons)+2,2,0,5)
925        littleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Polygon masks:'),0,
926            wx.ALIGN_CENTER_VERTICAL)
927        littleSizer.Add((5,0),0)
928        for polygon in polygons:
929            if polygon:
930                polyList = []
931                for x,y in polygon:
932                    polyList.append("%.2f, %.2f"%(x,y))
933                polyText = wx.ComboBox(self.dataDisplay,value=polyList[0],choices=polyList,style=wx.CB_READONLY)
934                littleSizer.Add(polyText,0,wx.ALIGN_CENTER_VERTICAL)
935                polyDelete = wx.CheckBox(parent=self.dataDisplay,label='delete?')
936                polyDelete.Bind(wx.EVT_CHECKBOX,OnDeletePoly)
937                delPolyId.append(polyDelete)
938                littleSizer.Add(polyDelete,0,wx.ALIGN_CENTER_VERTICAL)
939        mainSizer.Add(littleSizer,0,)
940    mainSizer.Layout()   
941    self.dataDisplay.SetSizer(mainSizer)
942    self.dataDisplay.SetSize(mainSizer.Fit(self.dataFrame))
943    self.dataFrame.setSizePosLeft(mainSizer.Fit(self.dataFrame))   
Note: See TracBrowser for help on using the repository browser.