source: trunk/python/flagplotter.py@ 2605

Last change on this file since 2605 was 2605, checked in by Kana Sugimoto, 13 years ago

New Development: Yes

JIRA Issue: Yes (CAS-3616/Trac-274)

Ready for Test: Yes

Interface Changes: Yes

What Interface Changed: a new method flagplotter._plot_with_flag()

and flagplotter.set_showflag().

Test Programs:

Put in Release Notes: No

Module(s): flagplotter, sdflag

Description:

The initial attempt to enable plotting flagged data in interactive flagging.
flagplotter module now uses their own plotting method, _plot_with_flag(),
to plot flagged data.
Also a minor fix to legend position in custom toolbar.


File size: 10.7 KB
Line 
1from asap.asapplotter import asapplotter
2from asap.logging import asaplog, asaplog_post_dec
3
4from asap.parameters import rcParams
5from asap.selector import selector
6from asap.scantable import scantable
7import matplotlib.axes
8from matplotlib.font_manager import FontProperties
9from matplotlib.text import Text
10
11class flagplotter(asapplotter):
12 """
13 The flag plotter
14 Only row based panneling is allowed.
15
16 Example:
17 scan = asa p.scantable(filename='your_filename',average=False)
18 guiflagger = asap.flagplotter(visible=True)
19 guiflagger.plot(scan)
20 ### flag/Unflag data graphically.
21 guiflagger.save_data(name='flagged_file.asap',format='ASAP')
22
23 NOTICE:
24 The flagged data is not saved until you explicitly run scantable.save
25 """
26 def __init__(self, visible=None, **kwargs):
27 self._scan = None
28 asapplotter.__init__(self,visible=visible, **kwargs)
29 self._assert_plotter(action='reload')
30 self._plotter._set_window_title('Flag Plotter')
31 self._panelling = 'r'
32 self.set_stacking('scan')
33 self._ismodified = False
34 self._showflag = True #False
35 self.set_colors("blue gray",False)
36
37 def _new_custombar(self):
38 backend = matplotlib.get_backend()
39 # Flag plotter relys on supported GUI backends
40 if not self._visible:
41 asaplog.push("GUI backend is not available")
42 asaplog.post("ERROR")
43 elif backend == "TkAgg":
44 from asap.customgui_tkagg import CustomFlagToolbarTkAgg
45 return CustomFlagToolbarTkAgg(self)
46 elif backend == "Qt4Agg":
47 from asap.customgui_qt4agg import CustomFlagToolbarQT4Agg
48 return CustomFlagToolbarQT4Agg(self)
49 else:
50 asaplog.push("Unsupported backend for interactive flagging. Use either TkAgg or PyQt4Agg")
51 asaplog.post("ERROR")
52
53 def set_showflag(self, show):
54 """ Whether or not plotting flagged data"""
55 if type(show) == bool:
56 self._showflag = show
57
58 @asaplog_post_dec
59 def _invalid_func(self, name):
60 msg = "Invalid function 'flagplotter."+name+"'"
61 #raise AttributeError(msg)
62 asaplog.push(msg)
63 asaplog.post('ERROR')
64
65 def set_panelling(self,which='r'):
66 """ This function is not available for the class flagplotter """
67 if which.lower().startswith('r'):
68 return
69 msg = "Pannel setting is fixed to row mode in 'flagplotter'"
70 asaplog.push(msg)
71 asaplog.post('ERROR')
72 self._panelling = 'r'
73
74 def set_range(self,xstart=None,xend=None,ystart=None,yend=None,refresh=False, offset=None):
75 """ This function is not available for the class flagplotter """
76 msg = "Plot range setting is not allowed in 'flagplotter'"
77 asaplog.push(msg)
78 asaplog.post('ERROR')
79 self._panelling = 'r'
80
81 def plotazel(self,*args,**kwargs):
82 """ This function is not available for the class flagplotter """
83 self._invalid_func(name='plotazel')
84
85 def plotpointing(self,*args,**kwargs):
86 """ This function is not available for the class flagplotter """
87 self._invalid_func(name='plotpointing')
88
89 def plottp(self,*args,**kwargs):
90 """ This function is not available for the class flagplotter """
91 self._invalid_func(name='plottp')
92
93 def save_data(self, name=None, format=None, overwrite=False):
94 """
95 Store the plotted scantable on disk.
96 This function simply redirects call to scantable.save()
97
98 Parameters:
99
100 name: the name of the outputfile. For format "ASCII"
101 this is the root file name (data in 'name'.txt
102 and header in 'name'_header.txt)
103
104 format: an optional file format. Default is ASAP.
105 Allowed are:
106 * 'ASAP' (save as ASAP [aips++] Table),
107 * 'SDFITS' (save as SDFITS file)
108 * 'ASCII' (saves as ascii text file)
109 * 'MS2' (saves as an casacore MeasurementSet V2)
110 * 'FITS' (save as image FITS - not readable by class)
111 * 'CLASS' (save as FITS readable by CLASS)
112
113 overwrite: If the file should be overwritten if it exists.
114 The default False is to return with warning
115 without writing the output. USE WITH CARE.
116 """
117 if not self._data:
118 raise RuntimeError("No scantable has been set yet.")
119 # simply calls scantable.save
120 self._data.save(name,format,overwrite)
121
122 def set_data(self, scan, refresh=True):
123 if self._is_new_scan(scan):
124 self._ismodified = False
125 asapplotter.set_data(self, scan, refresh)
126 set_data.__doc__ = asapplotter.set_data.__doc__
127
128 @asaplog_post_dec
129 def plot(self, scan=None):
130 if self._is_new_scan(scan):
131 self._ismodified = False
132 if not self._showflag:
133 self.set_legend(mode=None,refresh=False)
134 elif not self._legendloc:
135 self.set_legend(mode=1,refresh=False)
136 asapplotter.plot(self,scan)
137 plot.__doc__ = asapplotter.plot.__doc__
138
139 @asaplog_post_dec
140 def _plot(self, scan):
141 self._plot_with_flag(scan,self._showflag)
142 # rescale x-range of subplots 5% margins
143 ganged = (self._plotter.axes._sharex != None)
144 if ganged:
145 np = 1
146 else:
147 np = len(self._plotter.subplots)
148 for ip in xrange(np):
149 ax = self._plotter.subplots[ip]['axes']
150 lim0 = ax.get_xlim()
151 offset = (lim0[1]-lim0[0])*0.05
152 ax.set_xlim(lim0[0]-offset,lim0[1]+offset)
153 del ax, lim0, offset
154 _plot.__doc__ = asapplotter._plot.__doc__
155
156
157 @asaplog_post_dec
158 def _plot_with_flag(self, scan, showflag=True):
159 # total number of panles to plot as a whole
160 nptot = scan.nrow()
161 # remaining panels to plot
162 n = nptot - self._ipanel - 1
163 ganged = False
164 maxpanel = 25
165
166 if n > 1:
167 ganged = rcParams['plotter.ganged']
168 if self._rows and self._cols:
169 n = min(n,self._rows*self._cols)
170 self._plotter.set_panels(rows=self._rows,cols=self._cols,
171 nplots=n,margin=self._margins,ganged=ganged)
172 else:
173 n = min(n,maxpanel)
174 self._plotter.set_panels(rows=n,cols=0,nplots=n,margin=self._margins,ganged=ganged)
175 else:
176 self._plotter.set_panels(margin=self._margins)
177 #r = 0
178 r = self._startrow
179 # total row number of scantable
180 nr = scan.nrow()
181 panelcount = 0
182
183 while r < nr:
184 # always plot to new panel
185 self._plotter.subplot(panelcount)
186 self._plotter.palette(0)
187 # title and axes labels
188 xlab = self._abcissa and self._abcissa[panelcount] \
189 or scan._getabcissalabel()
190 if self._offset and not self._abcissa:
191 xlab += " (relative)"
192 ylab = self._ordinate and self._ordinate[panelcount] \
193 or scan._get_ordinate_label()
194 self._plotter.set_axes('xlabel', xlab)
195 self._plotter.set_axes('ylabel', ylab)
196 lbl = self._get_label(scan, r, mode='title', userlabel=self._title)
197 if type(lbl) in (list, tuple):
198 if 0 <= panelcount < len(lbl):
199 lbl = lbl[panelcount]
200 else:
201 # get default label
202 lbl = self._get_label(scan, r, 'title')
203 self._plotter.set_axes('title',lbl)
204 panelcount += 1
205 # Now get data to plot
206 y = scan._getspectrum(r)
207 #flag row
208 mr = scan._getflagrow(r)
209 from numpy import ma, array
210 if mr:
211 ys = ma.masked_array(y,mask=mr)
212 if showflag:
213 yf = ma.masked_array(y, mask=(not mr))
214 else:
215 m = scan._getmask(r)
216 from numpy import logical_not, logical_and
217 if self._maskselection and len(self._usermask) == len(m):
218 if d[self._stacking](r) in self._maskselection[self._stacking]:
219 m = logical_and(m, self._usermask)
220 ys = ma.masked_array(y,mask=logical_not(array(m,copy=False)))
221 if showflag:
222 yf = ma.masked_array(y,mask=m)
223
224 x = array(scan._getabcissa(r))
225 if self._offset:
226 x += self._offset
227 llbl = self._get_label(scan, r, mode='legend', userlabel=self._lmap)
228 if type(llbl) in (list, tuple):
229 llbl = llbl[0]
230 self._plotter.set_line(label=llbl)
231 plotit = self._plotter.plot
232 if self._hist: plotit = self._plotter.hist
233 plotit(x,ys)
234 if showflag:
235 self._plotter.set_line(label="flagged")
236 plotit(x,yf)
237 if (panelcount == n) or (r == nr-1):
238 break
239 r+=1 # next row
240
241
242 # save the current counter for multi-page plotting
243 self._startrow = r+1
244 self._ipanel += panelcount
245 if self.casabar_exists():
246 if self._ipanel >= nptot-1:
247 self._plotter.figmgr.casabar.disable_next()
248 else:
249 self._plotter.figmgr.casabar.enable_next()
250 if self._ipanel + 1 - panelcount > 0:
251 self._plotter.figmgr.casabar.enable_prev()
252 else:
253 self._plotter.figmgr.casabar.disable_prev()
254
255
256
257 def _get_label(self, scan, row, mode='title', userlabel=None):
258 if isinstance(userlabel, list) and len(userlabel) == 0:
259 userlabel = " "
260 elif not mode.upper().startswith('T'):
261 pms = dict(zip(self._selection.get_pols(), \
262 self._selection.get_poltypes()))
263 if len(pms):
264 poleval = scan._getpollabel(scan.getpol(row), \
265 pms[scan.getpol(row)])
266 else:
267 poleval = scan._getpollabel(scan.getpol(row),scan.poltype())
268 label = "IF%d, POL %s, Scan%d" % \
269 (scan.getif(row),poleval,scan.getscan(row))
270 else:
271 label = "row %d" % (row)
272
273 return userlabel or label
274
275
276 def _is_new_scan(self,scan):
277 if isinstance(scan, scantable):
278 if self._data is not None:
279 if scan != self._data:
280 return True
281 else:
282 return True
283 return False
Note: See TracBrowser for help on using the repository browser.