source: trunk/GSASIIimgGUI.py @ 397

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

collect default settings for Sample in one routine
add recalibrate routine for images
azimuths from image integration are now the center angle of each azimuth bin
put in 1/2 pixel offset in image calibration/integration calcs

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