source: trunk/GSASIIimgGUI.py @ 442

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

fix to mask bug in image integration with background subtraction

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