source: trunk/GSASIIimgGUI.py @ 253

Last change on this file since 253 was 253, checked in by toby, 12 years ago

fix mouse labeling; makefile cleaning (not done)

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