source: trunk/GSASIIimgGUI.py @ 256

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

remove popup message box for 2D image calibration
add delete line with R mouse button in powder patterns
fix image controls sizer issues

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