source: branches/GUIdev/OutputGUI/Skymap.py

Last change on this file was 1344, checked in by KelvinHsu, 10 years ago

Initial Commit

File size: 12.2 KB
Line 
1#-------------------------------------------------------------------------------
2# Name:        Skymap
3# Purpose:
4#
5# Author:      Kelvin
6#
7# Created:     02/01/2014
8#-------------------------------------------------------------------------------
9
10import matplotlib.pyplot as plt
11import matplotlib.cm as cm
12
13from matplotlib.figure import Figure
14from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
15
16from numpy import *
17
18from PyQt4 import QtGui, QtCore
19
20"""Skymap Class Definition"""
21# This defines the figure canvas of the skymap.
22class Skymap(FigureCanvas):
23
24    graphSignal = QtCore.pyqtSignal()
25   
26    def __init__(self, Results, maskImage, finalImage, momentMaps = None):
27
28        self.Results = Results
29
30        # Create the figure containing our final image
31        self.fig = Figure()
32
33        # Initialise the parent class
34        FigureCanvas.__init__(self, self.fig)
35
36        self.ax = self.fig.add_subplot(111)
37
38        QtGui.QToolTip.setFont(QtGui.QFont('SansSerif', 10))
39
40        self.maskImage = maskImage
41        self.finalImage = finalImage
42
43        if momentMaps != None:
44
45            self.momentMaps = momentMaps
46
47        [self.lenY, self.lenX] = finalImage.shape
48
49        self.highlightedObj = 0
50        self.outlinedObj = 0
51
52        self.colorChoice = 0
53
54        self.colorfulChoices = [cm.gray, cm.spectral, cm.copper, cm.hot, cm.jet]
55
56        self.totalChoices = len(self.colorfulChoices)
57
58        self.color = self.colorfulChoices[self.colorChoice]
59
60        self.globalpeakflux = max(finalImage.flatten())
61        self.peakflux = self.globalpeakflux
62
63        self.draw()
64        self.show()
65
66    def drawImage(self):
67
68        self.ax.cla()
69        self.ax.imshow(self.finalImage, cmap = self.color, interpolation = 'nearest')
70        self.ax.set_ylim(0, self.lenY)
71
72        self.ax.set_xlabel('X Pixel')
73        self.ax.set_ylabel('Y Pixel')
74
75        self.draw()
76
77    def enableInteractivity(self):
78
79        self.highlightLink = self.mpl_connect('button_press_event', self.tryHightlight)
80        self.outlineLink = self.mpl_connect('motion_notify_event', self.tryOutline)
81        self.outlineAllLink = self.mpl_connect('button_press_event', self.tryOutlineAll)
82        self.changeColorLink = self.mpl_connect('scroll_event', self.changeColor)
83
84    def disableInteractivity(self):
85       
86        self.mpl_disconnect(self.highlightLink)     
87        self.mpl_disconnect(self.outlineLink)   
88        self.mpl_disconnect(self.outlineAllLink)   
89        self.mpl_disconnect(self.changeColorLink)   
90
91    def changeColor(self, event):
92
93        self.colorChoice = (self.colorChoice + int(event.step)) % self.totalChoices
94
95        self.color = self.colorfulChoices[self.colorChoice]
96
97        self.ax.imshow(self.finalImage, cmap = self.color, vmax = self.peakflux, interpolation = 'nearest')
98        self.draw()
99
100    def tryHightlight(self, event):
101
102        if event.button != 1:
103            return
104
105        # If there is a valid (x,y) coordinate, meaning that the cursor is in the figure, then get it. Otherwise do nothing.
106        try:
107            (x, y) = (int(event.xdata), int(event.ydata))
108        except Exception:
109            return
110
111        # If there is nothing to highlight, do nothing.
112        if self.maskImage[y][x] == 0:
113            self.clearHighlight()
114            return
115
116        # Otherwise, if there is something to highlight, then:
117        else:
118
119            # Determine which object it is
120            ObjID = int(self.maskImage[y][x])
121
122            # If it is already highlighted, do nothing.
123            if ObjID == self.highlightedObj:
124                return
125
126            # Otherwise, it's not highlighted yet, we will highlight this Object instead.
127            else:
128                self.clearHighlight()
129                self.highlightObject(ObjID)
130                self.graphSignal.emit()
131                print("Clicked at at (x, y) = (" + str(x) + "," + str(y) + ")")
132                print("Object ID: " + str(self.highlightedObj))
133
134    # Remember to clear the image first before highlighting a new object!
135    def highlightObject(self, ObjID):
136
137        if ObjID <= 0:
138            return
139
140        highlightMask = zeros([self.lenY, self.lenX])
141        highlightMask[self.maskImage == ObjID] = 1
142
143        self.currentContourfill = self.ax.contourf(highlightMask, [0.5, 1], colors = 'white')
144        self.highlightedObj = ObjID
145
146        self.ax.set_ylim(0, self.lenY)
147
148        self.ax.set_xlabel('X Pixel')
149        self.ax.set_ylabel('Y Pixel')
150        self.draw()
151       
152    def clearHighlight(self):
153
154        self.clearImage()
155
156        if self.outlinedObj == -1:
157            self.outlineAll()
158        else:
159            self.outlineObject(self.outlinedObj)
160
161        self.highlightedObj = 0
162
163    def tryOutline(self, event):
164
165        # If there is a valid (x,y) coordinate, meaning that the cursor is in the figure, then get it. Otherwise do nothing.
166        try:
167            (x, y) = (int(event.xdata), int(event.ydata))
168        except Exception:
169           
170            if self.outlinedObj > 0:
171                self.clearOutline()
172            return
173
174        try:
175            # If there is nothing to outline, do nothing.
176            if self.maskImage[y][x] == 0:
177
178                if self.outlinedObj > 0:
179                    self.clearOutline()
180                return
181
182            # Otherwise, if there is something to outline, then:
183            else:
184
185                # Determine which object it is
186                ObjID = int(self.maskImage[y][x])
187
188                # If it is already outlined, do nothing.
189                if ObjID == self.outlinedObj or self.outlinedObj == -1:
190                    return
191
192                # Otherwise, it's not outlined yet, we will outline this Object instead.
193                else:
194                    self.clearOutline()
195                    self.outlineObject(ObjID)
196
197        except IndexError:
198            pass
199
200    # Remember to clear the image first before highlighting a new object!
201    def outlineObject(self, ObjID):
202
203        if ObjID <= 0:
204            return
205
206        outlineMask = zeros([self.lenY, self.lenX])
207        outlineMask[self.maskImage == ObjID] = 1
208
209        self.setToolTip('Object Source ' + str(ObjID))
210
211        contour = self.ax.contour(outlineMask, [0.5], linewidths = 2, colors = 'green')
212        self.outlinedObj = ObjID
213
214        self.ax.set_xlabel('X Pixel')
215        self.ax.set_ylabel('Y Pixel')       
216        self.ax.set_ylim(0, self.lenY)
217        self.draw()
218
219    def clearOutline(self):
220
221        self.clearImage()
222        self.highlightObject(self.highlightedObj)
223
224        self.outlinedObj = 0
225
226    def tryOutlineAll(self, event):
227       
228        # If the button is not the right key, remember to connect the outline link in case it was disconnected.
229        if event.button != 3:
230            self.outlineLink = self.mpl_connect('motion_notify_event', self.tryOutline)
231            return
232
233        # If it has not all outlined, disconnect the outline link and outline everything.
234        if self.outlinedObj != -1:
235            self.mpl_disconnect(self.outlineLink)
236            self.outlineAll()
237
238        # If it has all been outlined, reconnect the outline link.
239        else:
240            self.outlineLink = self.mpl_connect('motion_notify_event', self.tryOutline)
241            self.clearOutline()
242
243    def outlineAll(self):
244
245        outlineMask = zeros([self.lenY, self.lenX])
246        outlineMask[self.maskImage > 0] = 1
247       
248        if self.Results.totalDetections > 0:   
249            self.setToolTip('Object Sources 1 to ' + str(self.Results.totalDetections))
250        else:
251            self.setToolTip('No Objects')
252
253        contour = self.ax.contour(outlineMask, [0.5], linewidths = 2, colors = 'green')
254        self.outlinedObj = -1
255       
256        self.ax.set_ylim(0, self.lenY)
257        self.draw()
258
259    def clearImage(self):
260        self.ax.cla()
261        self.ax.imshow(self.finalImage, cmap = self.color, interpolation = 'nearest')
262        self.ax.set_xlabel('X Pixel')
263        self.ax.set_ylabel('Y Pixel')
264        self.ax.set_ylim(0, self.lenY)
265        self.draw()
266
267
268#class MomentMap(Skymap):
269
270#    def __init__(self, momentMaps):
271
272#        # Create the figure containing our final image
273#        self.fig = Figure()
274
275#        # Initialise the parent class
276#        FigureCanvas.__init__(self, self.fig)
277
278#        self.ax = self.fig.add_subplot(111)
279
280#        QtGui.QToolTip.setFont(QtGui.QFont('SansSerif', 10))
281
282#        self.maskImage = maskImage
283#        self.finalImage = finalImage
284       
285#        [self.lenY, self.lenX] = finalImage.shape
286
287#        self.highlightedObj = 0
288#        self.outlinedObj = 0
289
290#        self.colorChoice = 0
291
292#        self.colorfulChoices = [cm.gray, cm.spectral, cm.copper, cm.hot, cm.jet]
293
294#        self.totalChoices = len(self.colorfulChoices)
295
296#        self.color = self.colorfulChoices[self.colorChoice]
297
298#        self.draw()
299#        self.show()
300
301
302class MomentMap(Skymap):
303
304    def __init__(self, Results, maskImage, finalImage, momentMaps):
305
306        Skymap.__init__(self, Results, maskImage, finalImage, momentMaps)
307
308        self.currentObjID = 0
309
310        self.changeColorLink = self.mpl_connect('scroll_event', self.changeColor)
311
312        self.zoomOutLink = self.mpl_connect('button_press_event', self.zoomOut)
313        self.zoomInLink = self.mpl_connect('button_press_event', self.zoomIn)
314        self.scaleColorLink = self.mpl_connect('button_press_event', self.scaleColor)
315
316        #self.zoomStatus = 'in'
317
318        self.momentTitle = self.fig.suptitle("Moment Map")
319
320        self.ax.set_xlabel('X Pixel')
321        self.ax.set_ylabel('Y Pixel')
322
323        self.sourcepeakflux = self.globalpeakflux
324   
325    def scaleColor(self, event):
326
327        if event.button != 2:
328            return
329
330        if self.peakflux == self.globalpeakflux:
331            self.peakflux = self.sourcepeakflux
332            self.setToolTip('Flux scale calibrated to source %d'%self.currentObjID)
333
334        elif self.peakflux == self.sourcepeakflux:
335            self.peakflux = self.globalpeakflux
336            self.setToolTip('Flux scale calibrated to all sources within the same velocity range')
337
338        self.drawImage()
339
340    def zoomOut(self, event):
341
342        if event.button != 3:
343            return
344
345        self.xmin = 0
346        self.xmax = self.lenX
347        self.ymin = 0
348        self.ymax = self.lenY
349        self.drawImage()
350
351        #self.enableInteractivity()
352
353    def zoomIn(self, event):
354
355        if event.button != 1:
356            return
357
358        #self.disableInteractivity()
359        #self.changeColorLink = self.mpl_connect('scroll_event', self.changeColor)
360        self.setCurrentObjID(self.currentObjID)
361        self.drawImage()
362
363    def setCurrentObjID(self, ObjID):
364
365        self.currentObjID = ObjID
366        self.finalImage = self.momentMaps[ObjID]
367
368        if self.currentObjID > 0:
369
370            ObjStats = self.Results.SkyObjects[self.currentObjID].stats
371
372            x1 = ObjStats['X1']
373            x2 = ObjStats['X2']
374            y1 = ObjStats['Y1']
375            y2 = ObjStats['Y2']
376
377            xspace = 5
378            yspace = 5
379
380            self.xmin = max(0, x1 - xspace)
381            self.xmax = min(x2 + xspace, self.lenX)
382            self.ymin = max(0, y1 - yspace)
383            self.ymax = min(y2 + yspace, self.lenY)
384
385            self.xpeak = ObjStats['X_peak']
386            self.ypeak = ObjStats['Y_peak']
387
388            self.sourcepeakflux = self.finalImage[self.ypeak, self.xpeak]
389
390            self.peakflux = self.sourcepeakflux
391            self.setToolTip('Flux scale calibrated to source %d'%self.currentObjID)
392
393    def drawImage(self):
394
395        if self.currentObjID <= 0:
396            return
397
398        self.ax.cla()
399        self.momentTitle.set_text("Moment Map of Source " + str(self.currentObjID))
400        self.ax.imshow(self.finalImage, cmap = self.color, vmax = self.peakflux, interpolation = 'nearest')
401        self.ax.set_ylim(self.ymin, self.ymax)
402        self.ax.set_xlim(self.xmin, self.xmax)
403
404        self.ax.set_xlabel('X Pixel')
405        self.ax.set_ylabel('Y Pixel')       
406        self.draw()
Note: See TracBrowser for help on using the repository browser.