source: trunk/GSASIIimgGUI.py @ 248

Last change on this file since 248 was 248, checked in by vondreele, 12 years ago

histogram2d.for - cleaned up
add azmthOff - as for a rotation of a 2D detector
fix image integration problems

  • Property svn:keywords set to Date Author Revision URL Id
File size: 39.0 KB
Line 
1#GSASII - image data display routines
2########### SVN repository information ###################
3# $Date: 2011-02-17 19:33:02 +0000 (Thu, 17 Feb 2011) $
4# $Author: vondreele $
5# $Revision: 248 $
6# $URL: trunk/GSASIIimgGUI.py $
7# $Id: GSASIIimgGUI.py 248 2011-02-17 19:33:02Z 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    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 right mouse button to select point.
197          Use left 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'),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']
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        TextList = []
665        Names = []
666        if self.PatternTree.GetCount():
667            id, cookie = self.PatternTree.GetFirstChild(self.root)
668            while id:
669                name = self.PatternTree.GetItemText(id)
670                Names.append(name)
671                if 'IMG' in name:
672                    if id == self.Image:
673                        Source = name
674                        mask = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,id, 'Masks'))
675                    else:
676                        TextList.append([False,name,id])
677                id, cookie = self.PatternTree.GetNextChild(self.root, cookie)
678            if not len(TextList):
679                self.ErrorDialog('Nothing to copy mask to','There must be more than one "IMG" pattern')
680                return
681            dlg = self.CopyDialog(self,'Copy mask information','Copy mask from '+Source+' to:',TextList)
682            try:
683                if dlg.ShowModal() == wx.ID_OK:
684                    result = dlg.GetData()
685                    for i,item in enumerate(result):
686                        ifcopy,name,id = item
687                        if ifcopy:                               
688                            self.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(self,id, 'Masks'),mask)
689            finally:
690                dlg.Destroy()
691       
692    if self.dataDisplay:
693        self.dataDisplay.Destroy()
694    self.dataFrame.SetMenuBar(self.dataFrame.MaskMenu)
695    self.dataFrame.Bind(wx.EVT_MENU, OnCopyMask, id=G2gd.wxID_MASKCOPY)
696    if not self.dataFrame.GetStatusBar():
697        Status = self.dataFrame.CreateStatusBar()
698        Status.SetStatusText("To add mask: On 2D Powder Image, key a:arc, r:ring, s:spot, p:polygon")
699    self.dataDisplay = wx.Panel(self.dataFrame)
700    mainSizer = wx.BoxSizer(wx.VERTICAL)
701    mainSizer.Add((5,10),0)
702
703    thresh = data['Thresholds']         #min/max intensity range
704    spots = data['Points']               #x,y,radius in mm
705    rings = data['Rings']               #radius, thickness
706    polygons = data['Polygons']         #3+ x,y pairs
707    arcs = data['Arcs']                 #radius, start/end azimuth, thickness
708   
709    littleSizer = wx.FlexGridSizer(2,3,0,5)
710    littleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Lower/Upper limits '),0,
711        wx.ALIGN_CENTER_VERTICAL)
712    Text = wx.TextCtrl(self.dataDisplay,value=("%8d" % (thresh[0][0])),style=wx.TE_READONLY)
713    littleSizer.Add(Text,0,wx.ALIGN_CENTER_VERTICAL)
714    Text.SetBackgroundColour(VERY_LIGHT_GREY)
715    Text = wx.TextCtrl(self.dataDisplay,value=("%8d" % (thresh[0][1])),style=wx.TE_READONLY)
716    littleSizer.Add(Text,0,wx.ALIGN_CENTER_VERTICAL)
717    Text.SetBackgroundColour(VERY_LIGHT_GREY)
718    littleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Lower/Upper thresholds '),
719        0,wx.ALIGN_CENTER_VERTICAL)
720    lowerThreshold = wx.TextCtrl(parent=self.dataDisplay,
721        value=("%8d" % (thresh[1][0])),style=wx.TE_PROCESS_ENTER)
722    lowerThreshold.Bind(wx.EVT_TEXT_ENTER,OnThreshold)
723    lowerThreshold.Bind(wx.EVT_KILL_FOCUS,OnThreshold)
724    littleSizer.Add(lowerThreshold,0,wx.ALIGN_CENTER_VERTICAL)
725    upperThreshold = wx.TextCtrl(parent=self.dataDisplay,
726        value=("%8d" % (thresh[1][1])),style=wx.TE_PROCESS_ENTER)
727    upperThreshold.Bind(wx.EVT_TEXT_ENTER,OnThreshold)
728    upperThreshold.Bind(wx.EVT_KILL_FOCUS,OnThreshold)
729    littleSizer.Add(upperThreshold,0,wx.ALIGN_CENTER_VERTICAL)
730    mainSizer.Add(littleSizer,0,)
731    spotIds = []
732    delSpotId = []
733    if spots:
734        littleSizer = wx.FlexGridSizer(len(spots)+2,3,0,5)
735        littleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Spot masks:'),0,
736            wx.ALIGN_CENTER_VERTICAL)
737        littleSizer.Add((5,0),0)
738        littleSizer.Add((5,0),0)
739        littleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' position, mm'),0,
740            wx.ALIGN_CENTER_VERTICAL)
741        littleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' diameter, mm'),0,
742            wx.ALIGN_CENTER_VERTICAL)
743        littleSizer.Add((5,0),0)
744        for x,y,d in spots:
745            spotText = wx.TextCtrl(parent=self.dataDisplay,value=("%.2f,%.2f" % (x,y)),
746                style=wx.TE_READONLY)
747            spotText.SetBackgroundColour(VERY_LIGHT_GREY)
748            littleSizer.Add(spotText,0,wx.ALIGN_CENTER_VERTICAL)
749            spotText.Bind(wx.EVT_ENTER_WINDOW,OnTextMsg)
750            spotDiameter = wx.TextCtrl(parent=self.dataDisplay,value=("%.2f" % (d)),
751                style=wx.TE_PROCESS_ENTER)
752            littleSizer.Add(spotDiameter,0,wx.ALIGN_CENTER_VERTICAL)
753            spotDiameter.Bind(wx.EVT_TEXT_ENTER,OnSpotDiameter)
754            spotDiameter.Bind(wx.EVT_KILL_FOCUS,OnSpotDiameter)
755            spotIds.append(spotDiameter.GetId())
756            spotDelete = wx.CheckBox(parent=self.dataDisplay,label='delete?')
757            spotDelete.Bind(wx.EVT_CHECKBOX,OnDeleteSpot)
758            delSpotId.append(spotDelete)
759            littleSizer.Add(spotDelete,0,wx.ALIGN_CENTER_VERTICAL)
760        mainSizer.Add(littleSizer,0,)
761    ringIds = []
762    delRingId = []
763    if rings:
764        littleSizer = wx.FlexGridSizer(len(rings)+2,3,0,5)
765        littleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Ring masks:'),0,
766            wx.ALIGN_CENTER_VERTICAL)
767        littleSizer.Add((5,0),0)
768        littleSizer.Add((5,0),0)
769        littleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' 2-theta,deg'),0,
770            wx.ALIGN_CENTER_VERTICAL)
771        littleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' thickness, deg'),0,
772            wx.ALIGN_CENTER_VERTICAL)
773        littleSizer.Add((5,0),0)
774        for tth,thick in rings:
775            ringText = wx.TextCtrl(parent=self.dataDisplay,value=("%.3f" % (tth)),
776                style=wx.TE_READONLY)
777            ringText.SetBackgroundColour(VERY_LIGHT_GREY)
778            ringText.Bind(wx.EVT_ENTER_WINDOW,OnTextMsg)
779            littleSizer.Add(ringText,0,wx.ALIGN_CENTER_VERTICAL)
780            ringThick = wx.TextCtrl(parent=self.dataDisplay,value=("%.3f" % (thick)),
781                style=wx.TE_PROCESS_ENTER)
782            littleSizer.Add(ringThick,0,wx.ALIGN_CENTER_VERTICAL)
783            ringThick.Bind(wx.EVT_TEXT_ENTER,OnRingThickness)
784            ringThick.Bind(wx.EVT_KILL_FOCUS,OnRingThickness)
785            ringIds.append(ringThick.GetId())
786            ringDelete = wx.CheckBox(parent=self.dataDisplay,label='delete?')
787            ringDelete.Bind(wx.EVT_CHECKBOX,OnDeleteRing)
788            delRingId.append(ringDelete)
789            littleSizer.Add(ringDelete,0,wx.ALIGN_CENTER_VERTICAL)
790        mainSizer.Add(littleSizer,0,)
791    arcIds = []
792    delArcId = []
793    if arcs:
794        littleSizer = wx.FlexGridSizer(len(rings)+2,4,0,5)
795        littleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Arc masks:'),0,
796            wx.ALIGN_CENTER_VERTICAL)
797        littleSizer.Add((5,0),0)
798        littleSizer.Add((5,0),0)
799        littleSizer.Add((5,0),0)
800        littleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' 2-theta,deg'),0,
801            wx.ALIGN_CENTER_VERTICAL)
802        littleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' azimuth, deg'),0,
803            wx.ALIGN_CENTER_VERTICAL)
804        littleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' thickness, deg'),0,
805            wx.ALIGN_CENTER_VERTICAL)
806        littleSizer.Add((5,0),0)
807        for tth,azimuth,thick in arcs:
808            arcText = wx.TextCtrl(parent=self.dataDisplay,value=("%.3f" % (tth)),
809                style=wx.TE_READONLY)
810            arcText.SetBackgroundColour(VERY_LIGHT_GREY)
811            arcText.Bind(wx.EVT_ENTER_WINDOW,OnTextMsg)
812            littleSizer.Add(arcText,0,wx.ALIGN_CENTER_VERTICAL)
813            azmText = wx.TextCtrl(parent=self.dataDisplay,value=("%d,%d" % (azimuth[0],azimuth[1])),
814                style=wx.TE_READONLY)
815            azmText.SetBackgroundColour(VERY_LIGHT_GREY)
816            azmText.Bind(wx.EVT_ENTER_WINDOW,OnTextMsg)
817            littleSizer.Add(azmText,0,wx.ALIGN_CENTER_VERTICAL)
818            arcThick = wx.TextCtrl(parent=self.dataDisplay,value=("%.3f" % (thick)),
819                style=wx.TE_PROCESS_ENTER)
820            littleSizer.Add(arcThick,0,wx.ALIGN_CENTER_VERTICAL)
821            arcThick.Bind(wx.EVT_TEXT_ENTER,OnArcThickness)
822            arcThick.Bind(wx.EVT_KILL_FOCUS,OnArcThickness)
823            arcIds.append(arcThick.GetId())
824            arcDelete = wx.CheckBox(parent=self.dataDisplay,label='delete?')
825            arcDelete.Bind(wx.EVT_CHECKBOX,OnDeleteArc)
826            delArcId.append(arcDelete)
827            littleSizer.Add(arcDelete,0,wx.ALIGN_CENTER_VERTICAL)
828        mainSizer.Add(littleSizer,0,)
829    polyIds = []
830    delPolyId = []
831    if polygons:
832        littleSizer = wx.FlexGridSizer(len(polygons)+2,2,0,5)
833        littleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Polygon masks:'),0,
834            wx.ALIGN_CENTER_VERTICAL)
835        littleSizer.Add((5,0),0)
836        for polygon in polygons:
837            if polygon:
838                polyList = []
839                for x,y in polygon:
840                    polyList.append("%.2f, %.2f"%(x,y))
841                polyText = wx.ComboBox(self.dataDisplay,value=polyList[0],choices=polyList,style=wx.CB_READONLY)
842                littleSizer.Add(polyText,0,wx.ALIGN_CENTER_VERTICAL)
843                polyDelete = wx.CheckBox(parent=self.dataDisplay,label='delete?')
844                polyDelete.Bind(wx.EVT_CHECKBOX,OnDeletePoly)
845                delPolyId.append(polyDelete)
846                littleSizer.Add(polyDelete,0,wx.ALIGN_CENTER_VERTICAL)
847        mainSizer.Add(littleSizer,0,)
848    mainSizer.Layout()   
849    self.dataDisplay.SetSizer(mainSizer)
850    self.dataDisplay.SetSize(mainSizer.Fit(self.dataFrame))
851    self.dataFrame.setSizePosLeft(mainSizer.Fit(self.dataFrame))   
Note: See TracBrowser for help on using the repository browser.