source: trunk/GSASIIimgGUI.py @ 440

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

fix the mustrain ve microstrain title problem = GSASII.py
take wx,CallAfter? back out of most places - caused problems
get aniso size/mustrain ellipsoid around the right way to match ellipsoid model - exchanged sin & cos.

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