source: trunk/GSASIIimgGUI.py @ 239

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

add 'any image file' to image file menu
add calibration skip & dmin to image data dictionary
fix to ellipse fitting
fix Pilatus reading - OK for 100K, not sure for 2M
now a image sizexy - 2 items for x & y sizes

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