source: trunk/GSASIIimgGUI.py @ 245

Last change on this file since 245 was 245, checked in by vondreele, 11 years ago
  • Property svn:keywords set to Date Author Revision URL Id
File size: 38.3 KB
Line 
1#GSASII - image data display routines
2########### SVN repository information ###################
3# $Date: 2011-02-13 22:57:10 +0000 (Sun, 13 Feb 2011) $
4# $Author: vondreele $
5# $Revision: 245 $
6# $URL: trunk/GSASIIimgGUI.py $
7# $Id: GSASIIimgGUI.py 245 2011-02-13 22:57:10Z 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 = max(float(self.InnerTth.GetValue()),0.001)
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.3f" % (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                            Npix,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['size'] = oldData['size']                               
296                            Data['ring'] = []
297                            Data['rings'] = []
298                            Data['ellipses'] = []
299                            self.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(self,id, 'Image Controls'),Data)
300            finally:
301                dlg.Destroy()
302               
303    def OnSaveControls(event):
304        dlg = wx.FileDialog(self, 'Choose image controls file', '.', '', 
305            'image control files (*.imctrl)|*.imctrl',wx.OPEN)
306        if self.dirname:
307            dlg.SetDirectory(self.dirname)
308        try:
309            if dlg.ShowModal() == wx.ID_OK:
310                filename = dlg.GetPath()
311                File = open(filename,'w')
312                save = {}
313                keys = ['type','wavelength','calibrant','distance','center','tilt','rotation']
314                for key in keys:
315                    File.write(key+':'+str(data[key])+'\n')
316                File.close()
317        finally:
318            dlg.Destroy()
319       
320    def OnLoadControls(event):
321        dlg = wx.FileDialog(self, 'Choose image controls file', '.', '', 
322            'image control files (*.imctrl)|*.imctrl',wx.OPEN)
323        if self.dirname:
324            dlg.SetDirectory(self.dirname)
325        try:
326            if dlg.ShowModal() == wx.ID_OK:
327                filename = dlg.GetPath()
328                File = open(filename,'r')
329                save = {}
330                S = File.readline()
331                while S:
332                    if S[0] == '#':
333                        S = File.readline()
334                        continue
335                    [key,val] = S[:-1].split(':')
336                    if key in ['type','calibrant']:
337                        save[key] = val
338                    elif key in ['wavelength','distance','tilt','rotation']:
339                        save[key] = float(val)
340                    elif key in ['center',]:
341                        vals = val.strip('[] ').split()
342                        save[key] = [float(vals[0]),float(vals[1])]                   
343                    S = File.readline()
344                data.update(save)
345                calSel.SetValue(data['calibrant']) 
346                waveSel.SetValue("%6.5f" % (data['wavelength']))
347                cent = data['center']
348                centText.SetValue(("%8.3f,%8.3f" % (cent[0],cent[1])))
349                distSel.SetValue("%8.3f"%(data['distance']))
350                tiltSel.SetValue("%9.3f"%(data['tilt']))           
351                rotSel.SetValue("%9.3f"%(data['rotation']))
352                File.close()
353        finally:
354            dlg.Destroy()
355                                       
356    colorList = [m for m in mpl.cm.datad.keys() if not m.endswith("_r")]
357    calList = [m for m in calFile.Calibrants.keys()]
358    typeList = ['PWDR - powder diffraction data','SASD - small angle scattering data',
359        'REFL - reflectometry data']
360    if not data.get('type'):                        #patch for old project files
361        data['type'] = 'PWDR'
362    typeDict = {'PWDR':typeList[0],'SASD':typeList[1],'REFL':typeList[2]}
363    if self.dataDisplay:
364        self.dataDisplay.Destroy()
365    self.dataFrame.SetMenuBar(self.dataFrame.ImageMenu)
366    if not self.dataFrame.GetStatusBar():
367        Status = self.dataFrame.CreateStatusBar()
368    self.dataFrame.Bind(wx.EVT_MENU, OnCalibrate, id=G2gd.wxID_IMCALIBRATE)
369    self.dataFrame.Bind(wx.EVT_MENU, OnClearCalib, id=G2gd.wxID_IMCLEARCALIB)
370    if not data['rings']:
371        self.dataFrame.ImageEdit.Enable(id=G2gd.wxID_IMCLEARCALIB,enable=False)   
372    self.dataFrame.Bind(wx.EVT_MENU, OnIntegrate, id=G2gd.wxID_IMINTEGRATE)
373    self.dataFrame.Bind(wx.EVT_MENU, OnIntegrateAll, id=G2gd.wxID_INTEGRATEALL)
374    self.dataFrame.Bind(wx.EVT_MENU, OnSaveIntegrate, id=G2gd.wxID_SAVEINTG)
375    self.dataFrame.Bind(wx.EVT_MENU, OnCopyControls, id=G2gd.wxID_IMCOPYCONTROLS)
376    self.dataFrame.Bind(wx.EVT_MENU, OnSaveControls, id=G2gd.wxID_IMSAVECONTROLS)
377    self.dataFrame.Bind(wx.EVT_MENU, OnLoadControls, id=G2gd.wxID_IMLOADCONTROLS)
378    self.dataFrame.ImageEdit.Enable(id=G2gd.wxID_SAVEINTG,enable=False)   
379    self.dataDisplay = wx.Panel(self.dataFrame)
380    mainSizer = wx.BoxSizer(wx.VERTICAL)
381    mainSizer.Add((5,10),0)
382   
383    typeSizer = wx.BoxSizer(wx.HORIZONTAL)
384    typeSizer.Add(wx.StaticText(parent=self.dataDisplay,label='Type of image data: '),0,
385        wx.ALIGN_CENTER_VERTICAL)
386    typeSel = wx.ComboBox(parent=self.dataDisplay,value=typeDict[data['type']],choices=typeList,
387        style=wx.CB_READONLY|wx.CB_DROPDOWN)
388    typeSel.SetValue(data['type'])
389    typeSel.Bind(wx.EVT_COMBOBOX, OnDataType)
390    typeSizer.Add(typeSel,0,wx.ALIGN_CENTER_VERTICAL)
391    mainSizer.Add(typeSizer,0,wx.ALIGN_CENTER_HORIZONTAL)
392           
393    maxSizer = wx.FlexGridSizer(2,2,0,5)
394    maxSizer.AddGrowableCol(1,1)
395    sqrtDeltZero = math.sqrt(data['range'][0][1]-max(0.0,data['range'][0][0]))
396    DeltOne = data['range'][1][1]-max(0.0,data['range'][0][0])
397    sqrtDeltOne = math.sqrt(DeltOne)
398    maxSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Max intensity'),0,
399        wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
400    maxSel = wx.Slider(parent=self.dataDisplay,style=wx.SL_HORIZONTAL,
401        value=int(100*sqrtDeltOne/sqrtDeltZero))
402    maxSizer.Add(maxSel,1,wx.EXPAND|wx.RIGHT)
403    maxSel.Bind(wx.EVT_SLIDER, OnMaxSlider)   
404    maxSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Min intensity'),0,
405        wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
406    minSel = wx.Slider(parent=self.dataDisplay,style=wx.SL_HORIZONTAL,
407        value=int(100*(data['range'][1][0]-max(0.0,data['range'][0][0]))/DeltOne))
408    maxSizer.Add(minSel,1,wx.EXPAND|wx.RIGHT)
409    minSel.Bind(wx.EVT_SLIDER, OnMinSlider)
410    mainSizer.Add(maxSizer,1,wx.EXPAND|wx.RIGHT)
411   
412    comboSizer = wx.BoxSizer(wx.HORIZONTAL)
413    comboSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Color bar '),0,
414        wx.ALIGN_CENTER_VERTICAL)
415    colSel = wx.ComboBox(parent=self.dataDisplay,value=data['color'],choices=colorList,
416        style=wx.CB_READONLY|wx.CB_DROPDOWN|wx.CB_SORT)
417    colSel.Bind(wx.EVT_COMBOBOX, OnNewColorBar)
418    comboSizer.Add(colSel,0,wx.ALIGN_CENTER_VERTICAL)
419   
420    comboSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Calibrant '),0,
421        wx.ALIGN_CENTER_VERTICAL)
422    calSel = wx.ComboBox(parent=self.dataDisplay,value=data['calibrant'],choices=calList,
423        style=wx.CB_READONLY|wx.CB_DROPDOWN|wx.CB_SORT)
424    calSel.Bind(wx.EVT_COMBOBOX, OnNewCalibrant)
425    comboSizer.Add(calSel,0,wx.ALIGN_CENTER_VERTICAL)
426    mainSizer.Add(comboSizer,0,wx.ALIGN_CENTER_HORIZONTAL)
427    mainSizer.Add((10,10),0)
428       
429    comboSizer = wx.BoxSizer(wx.HORIZONTAL)
430    comboSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Pixel search range '),0,
431        wx.ALIGN_CENTER_VERTICAL)
432    pixLimit = wx.ComboBox(parent=self.dataDisplay,value=str(data['pixLimit']),choices=['1','2','5','10','15','20'],
433        style=wx.CB_READONLY|wx.CB_DROPDOWN)
434    pixLimit.Bind(wx.EVT_COMBOBOX, OnPixLimit)
435    comboSizer.Add(pixLimit,0,wx.ALIGN_CENTER_VERTICAL)
436    comboSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Min ring I/Ib '),0,
437        wx.ALIGN_CENTER_VERTICAL)
438    cutOff = wx.TextCtrl(parent=self.dataDisplay,value=("%.1f" % (data['cutoff'])),
439        style=wx.TE_PROCESS_ENTER)
440    cutOff.Bind(wx.EVT_TEXT_ENTER,OnCutOff)
441    cutOff.Bind(wx.EVT_KILL_FOCUS,OnCutOff)
442    comboSizer.Add(cutOff,0,wx.ALIGN_CENTER_VERTICAL)
443    comboSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Calib lines to skip '),0,
444        wx.ALIGN_CENTER_VERTICAL)
445    calibSkip  = wx.ComboBox(parent=self.dataDisplay,value=str(data['calibskip']),choices=['0','1','2','3','4','5','6','7','8','9','10'],
446        style=wx.CB_READONLY|wx.CB_DROPDOWN)
447    calibSkip.Bind(wx.EVT_COMBOBOX, OnCalibSkip)
448    comboSizer.Add(calibSkip,0,wx.ALIGN_CENTER_VERTICAL)
449    comboSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Min calib d-spacing '),0,
450        wx.ALIGN_CENTER_VERTICAL)
451    calibDmin = wx.TextCtrl(parent=self.dataDisplay,value=("%.1f" % (data['calibdmin'])),
452        style=wx.TE_PROCESS_ENTER)
453    calibDmin.Bind(wx.EVT_TEXT_ENTER,OnCalibDmin)
454    calibDmin.Bind(wx.EVT_KILL_FOCUS,OnCalibDmin)
455    comboSizer.Add(calibDmin,0,wx.ALIGN_CENTER_VERTICAL)
456
457    mainSizer.Add(comboSizer,0,wx.ALIGN_CENTER_HORIZONTAL)
458    mainSizer.Add((5,5),0)
459         
460    dataSizer = wx.FlexGridSizer(6,4,5,5)
461    dataSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Calibration coefficients'),0,
462        wx.ALIGN_CENTER_VERTICAL)   
463    dataSizer.Add((5,0),0)
464    dataSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Integration coefficients'),0,
465        wx.ALIGN_CENTER_VERTICAL)   
466    dataSizer.Add((5,0),0)
467   
468    dataSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Beam center X,Y'),0,
469        wx.ALIGN_CENTER_VERTICAL)
470    cent = data['center']
471    centText = wx.TextCtrl(parent=self.dataDisplay,value=("%8.3f,%8.3f" % (cent[0],cent[1])),style=wx.TE_READONLY)
472    centText.SetBackgroundColour(VERY_LIGHT_GREY)
473    dataSizer.Add(centText,0,wx.ALIGN_CENTER_VERTICAL)
474   
475    dataSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Inner/Outer 2-theta'),0,
476        wx.ALIGN_CENTER_VERTICAL)
477       
478    IOtth = data['IOtth']
479    littleSizer = wx.BoxSizer(wx.HORIZONTAL)
480    self.InnerTth = wx.TextCtrl(parent=self.dataDisplay,
481        value=("%8.3f" % (IOtth[0])),style=wx.TE_PROCESS_ENTER)
482    self.InnerTth.Bind(wx.EVT_TEXT_ENTER,OnIOtth)
483    self.InnerTth.Bind(wx.EVT_KILL_FOCUS,OnIOtth)
484    littleSizer.Add(self.InnerTth,0,wx.ALIGN_CENTER_VERTICAL)
485    self.OuterTth = wx.TextCtrl(parent=self.dataDisplay,
486        value=("%8.2f" % (IOtth[1])),style=wx.TE_PROCESS_ENTER)
487    self.OuterTth.Bind(wx.EVT_TEXT_ENTER,OnIOtth)
488    self.OuterTth.Bind(wx.EVT_KILL_FOCUS,OnIOtth)
489    littleSizer.Add(self.OuterTth,0,wx.ALIGN_CENTER_VERTICAL)
490    dataSizer.Add(littleSizer,0,)
491       
492    dataSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Wavelength'),0,
493        wx.ALIGN_CENTER_VERTICAL)
494    waveSel = wx.TextCtrl(parent=self.dataDisplay,value=("%6.5f" % (data['wavelength'])),
495        style=wx.TE_PROCESS_ENTER)
496    waveSel.Bind(wx.EVT_TEXT_ENTER,OnWavelength)
497    waveSel.Bind(wx.EVT_KILL_FOCUS,OnWavelength)
498    dataSizer.Add(waveSel,0,wx.ALIGN_CENTER_VERTICAL)
499         
500    dataSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Start/End azimuth'),0,
501        wx.ALIGN_CENTER_VERTICAL)
502    LRazim = data['LRazimuth']
503    littleSizer = wx.BoxSizer(wx.HORIZONTAL)
504    self.Lazim = wx.TextCtrl(parent=self.dataDisplay,
505        value=("%6d" % (LRazim[0])),style=wx.TE_PROCESS_ENTER)
506    self.Lazim.Bind(wx.EVT_TEXT_ENTER,OnLRazim)
507    self.Lazim.Bind(wx.EVT_KILL_FOCUS,OnLRazim)
508    littleSizer.Add(self.Lazim,0,wx.ALIGN_CENTER_VERTICAL)
509    self.Razim = wx.TextCtrl(parent=self.dataDisplay,
510        value=("%6d" % (LRazim[1])),style=wx.TE_PROCESS_ENTER)
511    self.Razim.Bind(wx.EVT_TEXT_ENTER,OnLRazim)
512    self.Razim.Bind(wx.EVT_KILL_FOCUS,OnLRazim)
513    littleSizer.Add(self.Razim,0,wx.ALIGN_CENTER_VERTICAL)
514    dataSizer.Add(littleSizer,0,)
515       
516    dataSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Distance'),0,
517        wx.ALIGN_CENTER_VERTICAL)
518    distSel = wx.TextCtrl(parent=self.dataDisplay,value=("%8.3f"%(data['distance'])),style=wx.TE_READONLY)
519    distSel.SetBackgroundColour(VERY_LIGHT_GREY)
520    dataSizer.Add(distSel,0,wx.ALIGN_CENTER_VERTICAL)
521
522    dataSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' No. 2-theta/azimuth bins'),0,
523        wx.ALIGN_CENTER_VERTICAL)
524    littleSizer = wx.BoxSizer(wx.HORIZONTAL)
525    outChan = wx.TextCtrl(parent=self.dataDisplay,value=str(data['outChannels']),style=wx.TE_PROCESS_ENTER)
526    outChan.Bind(wx.EVT_TEXT_ENTER,OnNumOutChans)
527    outChan.Bind(wx.EVT_KILL_FOCUS,OnNumOutChans)
528    littleSizer.Add(outChan,0,wx.ALIGN_CENTER_VERTICAL)
529    outAzim = wx.TextCtrl(parent=self.dataDisplay,value=str(data['outAzimuths']),style=wx.TE_PROCESS_ENTER)
530    outAzim.Bind(wx.EVT_TEXT_ENTER,OnNumOutAzms)
531    outAzim.Bind(wx.EVT_KILL_FOCUS,OnNumOutAzms)
532    littleSizer.Add(outAzim,0,wx.ALIGN_CENTER_VERTICAL)
533    dataSizer.Add(littleSizer,0,)
534
535    dataSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Tilt angle'),0,
536        wx.ALIGN_CENTER_VERTICAL)
537    tiltSel = wx.TextCtrl(parent=self.dataDisplay,value=("%9.3f"%(data['tilt'])),style=wx.TE_READONLY)
538    tiltSel.SetBackgroundColour(VERY_LIGHT_GREY)
539    dataSizer.Add(tiltSel,0,wx.ALIGN_CENTER_VERTICAL)
540    showLines = wx.CheckBox(parent=self.dataDisplay,label='Show integration limits?')
541    dataSizer.Add(showLines,0)
542    showLines.Bind(wx.EVT_CHECKBOX, OnShowLines)
543    showLines.SetValue(data['showLines'])
544    fullIntegrate = wx.CheckBox(parent=self.dataDisplay,label='Do full integration?')
545    dataSizer.Add(fullIntegrate,0)
546    fullIntegrate.Bind(wx.EVT_CHECKBOX, OnFullIntegrate)
547    fullIntegrate.SetValue(data['fullIntegrate'])
548   
549    dataSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Tilt rotation'),0,
550        wx.ALIGN_CENTER_VERTICAL)
551    rotSel = wx.TextCtrl(parent=self.dataDisplay,value=("%9.3f"%(data['rotation'])),style=wx.TE_READONLY)
552    rotSel.SetBackgroundColour(VERY_LIGHT_GREY)
553    dataSizer.Add(rotSel,0,wx.ALIGN_CENTER_VERTICAL)
554    setDefault = wx.CheckBox(parent=self.dataDisplay,label='Use as default for all images?')
555    dataSizer.Add(setDefault,0)
556    setDefault.Bind(wx.EVT_CHECKBOX, OnSetDefault)
557    setDefault.SetValue(data['setDefault'])
558    setRings = wx.CheckBox(parent=self.dataDisplay,label='Show ring picks?')
559    dataSizer.Add(setRings,0)
560    setRings.Bind(wx.EVT_CHECKBOX, OnSetRings)
561    setRings.SetValue(data['setRings'])
562       
563    mainSizer.Add(dataSizer,0)
564   
565    mainSizer.Layout()   
566    self.dataDisplay.SetSizer(mainSizer)
567    self.dataDisplay.SetSize(mainSizer.Fit(self.dataFrame))
568    self.dataFrame.setSizePosLeft(mainSizer.Fit(self.dataFrame))
569   
570def UpdateMasks(self,data):
571   
572    def OnTextMsg(event):
573        Obj = event.GetEventObject()
574        Obj.SetToolTipString('Drag this mask on 2D Powder Image with mouse to change ')
575       
576    def OnThreshold(event):
577        try:
578            lower = max(int(lowerThreshold.GetValue()),thresh[0][0])
579        except ValueError:
580            lower = thresh[0][0]
581        try:
582            upper = min(int(upperThreshold.GetValue()),thresh[0][1])
583        except ValueError:
584            upper = thresh[0][1]
585        data['Thresholds'][1] = [lower,upper]
586        lowerThreshold.SetValue("%8d" % (lower))
587        upperThreshold.SetValue("%8d" % (upper))
588        G2plt.PlotExposedImage(self,event=event)
589       
590    def OnSpotDiameter(event):
591        Obj = event.GetEventObject()
592        try:
593            diameter = min(100.,max(0.1,float(Obj.GetValue())))
594        except ValueError:
595            diameter = 1.0
596        Obj.SetValue("%.2f"%(diameter))
597        data['Points'][spotIds.index(Obj.GetId())][2] = diameter
598        G2plt.PlotExposedImage(self,event=event)
599       
600    def OnDeleteSpot(event):
601        Obj = event.GetEventObject()
602        del(data['Points'][delSpotId.index(Obj)])
603        UpdateMasks(self,data)           
604        G2plt.PlotExposedImage(self,event=event)
605       
606    def OnRingThickness(event):
607        Obj = event.GetEventObject()
608        try:
609            thick = min(1.0,max(0.001,float(Obj.GetValue())))
610        except ValueError:
611            thick = 0.1
612        Obj.SetValue("%.3f"%(thick))
613        data['Rings'][ringIds.index(Obj.GetId())][1] = thick
614        G2plt.PlotExposedImage(self,event=event)
615       
616    def OnDeleteRing(event):
617        Obj = event.GetEventObject()
618        del(data['Rings'][delRingId.index(Obj)])
619        UpdateMasks(self,data)           
620        G2plt.PlotExposedImage(self,event=event)
621
622    def OnArcThickness(event):
623        Obj = event.GetEventObject()
624        try:
625            thick = min(20.0,max(0.001,float(Obj.GetValue())))
626        except ValueError:
627            thick = 0.1
628        Obj.SetValue("%.3f"%(thick))
629        data['Arcs'][arcIds.index(Obj.GetId())][2] = thick
630        G2plt.PlotExposedImage(self,event=event)
631       
632    def OnDeleteArc(event):
633        Obj = event.GetEventObject()
634        del(data['Arcs'][delArcId.index(Obj)])
635        UpdateMasks(self,data)           
636        G2plt.PlotExposedImage(self,event=event)
637
638    def OnDeletePoly(event):
639        Obj = event.GetEventObject()
640        del(data['Polygons'][delPolyId.index(Obj)])
641        UpdateMasks(self,data)           
642        G2plt.PlotExposedImage(self,event=event)
643
644    def OnCopyMask(event):
645        TextList = []
646        Names = []
647        if self.PatternTree.GetCount():
648            id, cookie = self.PatternTree.GetFirstChild(self.root)
649            while id:
650                name = self.PatternTree.GetItemText(id)
651                Names.append(name)
652                if 'IMG' in name:
653                    if id == self.Image:
654                        Source = name
655                        mask = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,id, 'Masks'))
656                    else:
657                        TextList.append([False,name,id])
658                id, cookie = self.PatternTree.GetNextChild(self.root, cookie)
659            if not len(TextList):
660                self.ErrorDialog('Nothing to copy mask to','There must be more than one "IMG" pattern')
661                return
662            dlg = self.CopyDialog(self,'Copy mask information','Copy mask from '+Source+' to:',TextList)
663            try:
664                if dlg.ShowModal() == wx.ID_OK:
665                    result = dlg.GetData()
666                    for i,item in enumerate(result):
667                        ifcopy,name,id = item
668                        if ifcopy:                               
669                            self.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(self,id, 'Masks'),mask)
670            finally:
671                dlg.Destroy()
672       
673    if self.dataDisplay:
674        self.dataDisplay.Destroy()
675    self.dataFrame.SetMenuBar(self.dataFrame.MaskMenu)
676    self.dataFrame.Bind(wx.EVT_MENU, OnCopyMask, id=G2gd.wxID_MASKCOPY)
677    if not self.dataFrame.GetStatusBar():
678        Status = self.dataFrame.CreateStatusBar()
679        Status.SetStatusText("To add mask: On 2D Powder Image, key a:arc, r:ring, s:spot, p:polygon")
680    self.dataDisplay = wx.Panel(self.dataFrame)
681    mainSizer = wx.BoxSizer(wx.VERTICAL)
682    mainSizer.Add((5,10),0)
683
684    thresh = data['Thresholds']         #min/max intensity range
685    spots = data['Points']               #x,y,radius in mm
686    rings = data['Rings']               #radius, thickness
687    polygons = data['Polygons']         #3+ x,y pairs
688    arcs = data['Arcs']                 #radius, start/end azimuth, thickness
689   
690    littleSizer = wx.FlexGridSizer(2,3,0,5)
691    littleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Lower/Upper limits '),0,
692        wx.ALIGN_CENTER_VERTICAL)
693    Text = wx.TextCtrl(self.dataDisplay,value=("%8d" % (thresh[0][0])),style=wx.TE_READONLY)
694    littleSizer.Add(Text,0,wx.ALIGN_CENTER_VERTICAL)
695    Text.SetBackgroundColour(VERY_LIGHT_GREY)
696    Text = wx.TextCtrl(self.dataDisplay,value=("%8d" % (thresh[0][1])),style=wx.TE_READONLY)
697    littleSizer.Add(Text,0,wx.ALIGN_CENTER_VERTICAL)
698    Text.SetBackgroundColour(VERY_LIGHT_GREY)
699    littleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Lower/Upper thresholds '),
700        0,wx.ALIGN_CENTER_VERTICAL)
701    lowerThreshold = wx.TextCtrl(parent=self.dataDisplay,
702        value=("%8d" % (thresh[1][0])),style=wx.TE_PROCESS_ENTER)
703    lowerThreshold.Bind(wx.EVT_TEXT_ENTER,OnThreshold)
704    lowerThreshold.Bind(wx.EVT_KILL_FOCUS,OnThreshold)
705    littleSizer.Add(lowerThreshold,0,wx.ALIGN_CENTER_VERTICAL)
706    upperThreshold = wx.TextCtrl(parent=self.dataDisplay,
707        value=("%8d" % (thresh[1][1])),style=wx.TE_PROCESS_ENTER)
708    upperThreshold.Bind(wx.EVT_TEXT_ENTER,OnThreshold)
709    upperThreshold.Bind(wx.EVT_KILL_FOCUS,OnThreshold)
710    littleSizer.Add(upperThreshold,0,wx.ALIGN_CENTER_VERTICAL)
711    mainSizer.Add(littleSizer,0,)
712    spotIds = []
713    delSpotId = []
714    if spots:
715        littleSizer = wx.FlexGridSizer(len(spots)+2,3,0,5)
716        littleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Spot masks:'),0,
717            wx.ALIGN_CENTER_VERTICAL)
718        littleSizer.Add((5,0),0)
719        littleSizer.Add((5,0),0)
720        littleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' position, mm'),0,
721            wx.ALIGN_CENTER_VERTICAL)
722        littleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' diameter, mm'),0,
723            wx.ALIGN_CENTER_VERTICAL)
724        littleSizer.Add((5,0),0)
725        for x,y,d in spots:
726            spotText = wx.TextCtrl(parent=self.dataDisplay,value=("%.2f,%.2f" % (x,y)),
727                style=wx.TE_READONLY)
728            spotText.SetBackgroundColour(VERY_LIGHT_GREY)
729            littleSizer.Add(spotText,0,wx.ALIGN_CENTER_VERTICAL)
730            spotText.Bind(wx.EVT_ENTER_WINDOW,OnTextMsg)
731            spotDiameter = wx.TextCtrl(parent=self.dataDisplay,value=("%.2f" % (d)),
732                style=wx.TE_PROCESS_ENTER)
733            littleSizer.Add(spotDiameter,0,wx.ALIGN_CENTER_VERTICAL)
734            spotDiameter.Bind(wx.EVT_TEXT_ENTER,OnSpotDiameter)
735            spotDiameter.Bind(wx.EVT_KILL_FOCUS,OnSpotDiameter)
736            spotIds.append(spotDiameter.GetId())
737            spotDelete = wx.CheckBox(parent=self.dataDisplay,label='delete?')
738            spotDelete.Bind(wx.EVT_CHECKBOX,OnDeleteSpot)
739            delSpotId.append(spotDelete)
740            littleSizer.Add(spotDelete,0,wx.ALIGN_CENTER_VERTICAL)
741        mainSizer.Add(littleSizer,0,)
742    ringIds = []
743    delRingId = []
744    if rings:
745        littleSizer = wx.FlexGridSizer(len(rings)+2,3,0,5)
746        littleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Ring masks:'),0,
747            wx.ALIGN_CENTER_VERTICAL)
748        littleSizer.Add((5,0),0)
749        littleSizer.Add((5,0),0)
750        littleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' 2-theta,deg'),0,
751            wx.ALIGN_CENTER_VERTICAL)
752        littleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' thickness, deg'),0,
753            wx.ALIGN_CENTER_VERTICAL)
754        littleSizer.Add((5,0),0)
755        for tth,thick in rings:
756            ringText = wx.TextCtrl(parent=self.dataDisplay,value=("%.3f" % (tth)),
757                style=wx.TE_READONLY)
758            ringText.SetBackgroundColour(VERY_LIGHT_GREY)
759            ringText.Bind(wx.EVT_ENTER_WINDOW,OnTextMsg)
760            littleSizer.Add(ringText,0,wx.ALIGN_CENTER_VERTICAL)
761            ringThick = wx.TextCtrl(parent=self.dataDisplay,value=("%.3f" % (thick)),
762                style=wx.TE_PROCESS_ENTER)
763            littleSizer.Add(ringThick,0,wx.ALIGN_CENTER_VERTICAL)
764            ringThick.Bind(wx.EVT_TEXT_ENTER,OnRingThickness)
765            ringThick.Bind(wx.EVT_KILL_FOCUS,OnRingThickness)
766            ringIds.append(ringThick.GetId())
767            ringDelete = wx.CheckBox(parent=self.dataDisplay,label='delete?')
768            ringDelete.Bind(wx.EVT_CHECKBOX,OnDeleteRing)
769            delRingId.append(ringDelete)
770            littleSizer.Add(ringDelete,0,wx.ALIGN_CENTER_VERTICAL)
771        mainSizer.Add(littleSizer,0,)
772    arcIds = []
773    delArcId = []
774    if arcs:
775        littleSizer = wx.FlexGridSizer(len(rings)+2,4,0,5)
776        littleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Arc masks:'),0,
777            wx.ALIGN_CENTER_VERTICAL)
778        littleSizer.Add((5,0),0)
779        littleSizer.Add((5,0),0)
780        littleSizer.Add((5,0),0)
781        littleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' 2-theta,deg'),0,
782            wx.ALIGN_CENTER_VERTICAL)
783        littleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' azimuth, deg'),0,
784            wx.ALIGN_CENTER_VERTICAL)
785        littleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' thickness, deg'),0,
786            wx.ALIGN_CENTER_VERTICAL)
787        littleSizer.Add((5,0),0)
788        for tth,azimuth,thick in arcs:
789            arcText = wx.TextCtrl(parent=self.dataDisplay,value=("%.3f" % (tth)),
790                style=wx.TE_READONLY)
791            arcText.SetBackgroundColour(VERY_LIGHT_GREY)
792            arcText.Bind(wx.EVT_ENTER_WINDOW,OnTextMsg)
793            littleSizer.Add(arcText,0,wx.ALIGN_CENTER_VERTICAL)
794            azmText = wx.TextCtrl(parent=self.dataDisplay,value=("%d,%d" % (azimuth[0],azimuth[1])),
795                style=wx.TE_READONLY)
796            azmText.SetBackgroundColour(VERY_LIGHT_GREY)
797            azmText.Bind(wx.EVT_ENTER_WINDOW,OnTextMsg)
798            littleSizer.Add(azmText,0,wx.ALIGN_CENTER_VERTICAL)
799            arcThick = wx.TextCtrl(parent=self.dataDisplay,value=("%.3f" % (thick)),
800                style=wx.TE_PROCESS_ENTER)
801            littleSizer.Add(arcThick,0,wx.ALIGN_CENTER_VERTICAL)
802            arcThick.Bind(wx.EVT_TEXT_ENTER,OnArcThickness)
803            arcThick.Bind(wx.EVT_KILL_FOCUS,OnArcThickness)
804            arcIds.append(arcThick.GetId())
805            arcDelete = wx.CheckBox(parent=self.dataDisplay,label='delete?')
806            arcDelete.Bind(wx.EVT_CHECKBOX,OnDeleteArc)
807            delArcId.append(arcDelete)
808            littleSizer.Add(arcDelete,0,wx.ALIGN_CENTER_VERTICAL)
809        mainSizer.Add(littleSizer,0,)
810    polyIds = []
811    delPolyId = []
812    if polygons:
813        littleSizer = wx.FlexGridSizer(len(polygons)+2,2,0,5)
814        littleSizer.Add(wx.StaticText(parent=self.dataDisplay,label=' Polygon masks:'),0,
815            wx.ALIGN_CENTER_VERTICAL)
816        littleSizer.Add((5,0),0)
817        for polygon in polygons:
818            if polygon:
819                polyList = []
820                for x,y in polygon:
821                    polyList.append("%.2f, %.2f"%(x,y))
822                polyText = wx.ComboBox(self.dataDisplay,value=polyList[0],choices=polyList,style=wx.CB_READONLY)
823                littleSizer.Add(polyText,0,wx.ALIGN_CENTER_VERTICAL)
824                polyDelete = wx.CheckBox(parent=self.dataDisplay,label='delete?')
825                polyDelete.Bind(wx.EVT_CHECKBOX,OnDeletePoly)
826                delPolyId.append(polyDelete)
827                littleSizer.Add(polyDelete,0,wx.ALIGN_CENTER_VERTICAL)
828        mainSizer.Add(littleSizer,0,)
829    mainSizer.Layout()   
830    self.dataDisplay.SetSizer(mainSizer)
831    self.dataDisplay.SetSize(mainSizer.Fit(self.dataFrame))
832    self.dataFrame.setSizePosLeft(mainSizer.Fit(self.dataFrame))   
Note: See TracBrowser for help on using the repository browser.