source: trunk/GSASIIimgGUI.py @ 257

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

change plotting during calibration - now at end - faster
make image plotting optional - saves a little here & there

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