source: trunk/GSASIIimgGUI.py @ 264

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

begin implementation of pdf generation - work in progress
modify image to have azimuth=0 as vertical "up"
add textctrls for max and min image intensity
fix to some lattice parameter defaults for some Laue groups

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