source: trunk/GSASIIimgGUI.py @ 254

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

removed "Save Integration"
rearranged stuff in the Image Controls window

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