source: trunk/GSASIIimgGUI.py @ 238

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

add new image data types SXAS & REFL
make image controls save file a user editable text file

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