source: trunk/GSASIIimgGUI.py @ 115

Last change on this file since 115 was 115, checked in by vondreel, 13 years ago

implement "KILL_FOCUS" for all TextCtrl? windows

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