source: trunk/GSASIIimgGUI.py @ 406

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

implement background subtraction during image integration
implement copy for instrument parms & background
continue constraint GUI development
make sure proper updates in refinement/seq refinement

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