source: trunk/GSASIIimgGUI.py @ 246

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

fix copy controls for images - needed deepcopy
multi frame GE detector images now automatically summed when read.
also earlier commit - image calibration will compute a "suggested" new wavelength - not imposed however as it may be wrong.

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