source: trunk/GSASIIimgGUI.py @ 399

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

Implement sequential refinement
remove print "load" & "save" for each item in Tree
revise application of azimuth offset - azimuths are now all "true" with correction

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