source: trunk/python/flagplotter.py @ 2606

Last change on this file since 2606 was 2606, checked in by Kana Sugimoto, 12 years ago

New Development: No

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

Ready for Test: Yes

Interface Changes: No

What Interface Changed:

Test Programs:

Put in Release Notes: No

Module(s): flagplotter, sdflag

Description: fixed misc bugs in flagplotter.


File size: 11.8 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._showflagged = 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_showflagged(self, show):
54        """ Whether or not plotting flagged data"""
55        if type(show) == bool:
56            self._showflagged = show
57            print "self._showflagged =", str(show)
58        else:
59            raise TypeError, "Input parameter should be a bool."
60
61    @asaplog_post_dec
62    def _invalid_func(self, name):
63        msg = "Invalid function 'flagplotter."+name+"'"
64        #raise AttributeError(msg)
65        asaplog.push(msg)
66        asaplog.post('ERROR')
67
68    def set_panelling(self,which='r'):
69        """ This function is not available for the class flagplotter """
70        if which.lower().startswith('r'):
71            return
72        msg = "Pannel setting is fixed to row mode in 'flagplotter'"
73        asaplog.push(msg)
74        asaplog.post('ERROR')
75        self._panelling = 'r'
76
77    def set_range(self,xstart=None,xend=None,ystart=None,yend=None,refresh=False, offset=None):
78        """ This function is not available for the class flagplotter """
79        msg = "Plot range setting is not allowed in 'flagplotter'"
80        asaplog.push(msg)
81        asaplog.post('ERROR')
82        self._panelling = 'r'
83
84    def plotazel(self,*args,**kwargs):
85        """ This function is not available for the class flagplotter """
86        self._invalid_func(name='plotazel')
87   
88    def plotpointing(self,*args,**kwargs):
89        """ This function is not available for the class flagplotter """
90        self._invalid_func(name='plotpointing')
91
92    def plottp(self,*args,**kwargs):
93        """ This function is not available for the class flagplotter """
94        self._invalid_func(name='plottp')
95
96    def save_data(self, name=None, format=None, overwrite=False):
97        """
98        Store the plotted scantable on disk.
99        This function simply redirects call to scantable.save()
100       
101        Parameters:
102   
103            name:        the name of the outputfile. For format "ASCII"
104                         this is the root file name (data in 'name'.txt
105                         and header in 'name'_header.txt)
106   
107            format:      an optional file format. Default is ASAP.
108                         Allowed are:
109                            * 'ASAP' (save as ASAP [aips++] Table),
110                            * 'SDFITS' (save as SDFITS file)
111                            * 'ASCII' (saves as ascii text file)
112                            * 'MS2' (saves as an casacore MeasurementSet V2)
113                            * 'FITS' (save as image FITS - not readable by class)
114                            * 'CLASS' (save as FITS readable by CLASS)
115   
116            overwrite:   If the file should be overwritten if it exists.
117                         The default False is to return with warning
118                         without writing the output. USE WITH CARE.
119        """
120        if not self._data:
121            raise RuntimeError("No scantable has been set yet.")
122        # simply calls scantable.save
123        self._data.save(name,format,overwrite)
124
125    def set_data(self, scan, refresh=True):
126        if self._is_new_scan(scan):
127            self._ismodified = False
128        asapplotter.set_data(self, scan, refresh)
129    set_data.__doc__ = asapplotter.set_data.__doc__
130
131    @asaplog_post_dec
132    def plot(self, scan=None):
133        if self._is_new_scan(scan):
134            self._ismodified = False
135        if not self._showflagged:
136            self.set_legend(mode=None,refresh=False)
137        elif not self._legendloc:
138            self.set_legend(mode=1,refresh=False)
139        asapplotter.plot(self,scan)
140    plot.__doc__ = asapplotter.plot.__doc__
141
142    @asaplog_post_dec
143    def _plot(self, scan):
144        self._plot_with_flag(scan,self._showflagged)
145        #asapplotter._plot(self,scan)
146        # rescale x-range of subplots 5% margins
147        ganged = (self._plotter.axes._sharex != None)
148        if ganged:
149            np = 1
150        else:
151            np = len(self._plotter.subplots)
152        for ip in xrange(np):
153            ax = self._plotter.subplots[ip]['axes']
154            lim0 = ax.get_xlim()
155            offset = (lim0[1]-lim0[0])*0.05
156            ax.set_xlim(lim0[0]-offset,lim0[1]+offset)
157            del ax, lim0, offset
158    _plot.__doc__ = asapplotter._plot.__doc__
159
160
161    @asaplog_post_dec
162    def _plot_with_flag(self, scan, showflag=False):
163        # total number of panles to plot as a whole
164        nptot = scan.nrow()
165        # remaining panels to plot
166        n = nptot - self._ipanel - 1
167        ganged = False
168        maxpanel = 25
169
170        if n > 1:
171            ganged = rcParams['plotter.ganged']
172            if self._rows and self._cols:
173                n = min(n,self._rows*self._cols)
174                self._plotter.set_panels(rows=self._rows,cols=self._cols,
175                                         nplots=n,margin=self._margins,ganged=ganged)
176            else:
177                n = min(n,maxpanel)
178                self._plotter.set_panels(rows=n,cols=0,nplots=n,margin=self._margins,ganged=ganged)
179        else:
180            self._plotter.set_panels(margin=self._margins)
181        #r = 0
182        r = self._startrow
183        # total row number of scantable
184        nr = scan.nrow()
185        panelcount = 0
186        allylim = []
187        allxlim = []
188       
189        while r < nr:
190            # always plot to new panel
191            self._plotter.subplot(panelcount)
192            self._plotter.palette(0)
193            # title and axes labels
194            xlab = self._abcissa and self._abcissa[panelcount] \
195                       or scan._getabcissalabel()
196            if self._offset and not self._abcissa:
197                xlab += " (relative)"
198            ylab = self._ordinate and self._ordinate[panelcount] \
199                   or scan._get_ordinate_label()
200            self._plotter.set_axes('xlabel', xlab)
201            self._plotter.set_axes('ylabel', ylab)
202            lbl = self._get_label(scan, r, mode='title', userlabel=self._title)
203            if type(lbl) in (list, tuple):
204                if 0 <= panelcount < len(lbl):
205                    lbl = lbl[panelcount]
206                else:
207                    # get default label
208                    lbl = self._get_label(scan, r, 'title')
209            self._plotter.set_axes('title',lbl)
210            panelcount += 1
211            # Now get data to plot
212            y = scan._getspectrum(r)
213            # Check for FLAGROW column
214            mr = scan._getflagrow(r)
215            from numpy import ma, array
216            if mr:
217                ys = ma.masked_array(y,mask=mr)
218                if showflag:
219                    yf = ma.masked_array(y, mask=(not mr))
220            else:
221                m = scan._getmask(r)
222                from numpy import logical_not, logical_and
223                if self._maskselection and len(self._usermask) == len(m):
224                    if d[self._stacking](r) in self._maskselection[self._stacking]:
225                        m = logical_and(m, self._usermask)
226                ys = ma.masked_array(y,mask=logical_not(array(m,copy=False)))
227                if showflag:
228                    yf = ma.masked_array(y,mask=m)
229
230            x = array(scan._getabcissa(r))
231            if self._offset:
232                x += self._offset
233            #llbl = self._get_label(scan, r, mode='legend', userlabel=self._lmap)
234            #if type(llbl) in (list, tuple):
235            #    llbl = llbl[0]
236            #self._plotter.set_line(label=llbl)
237            self._plotter.set_line(label="data")
238            #plotit = self._plotter.plot
239            #if self._hist: plotit = self._plotter.hist
240            self._plotter.plot(x,ys)
241            if showflag:
242                self._plotter.set_line(label="flagged")
243                self._plotter.plot(x,yf)
244                ylim = self._minmaxy or [min(y),max(y)]
245                xlim= self._minmaxx or [min(x),max(x)]
246            elif mr or ys.mask.all():
247                ylim = self._minmaxy or []
248                xlim = self._minmaxx or []
249            else:
250                ylim = self._minmaxy or [ma.minimum(ys),ma.maximum(ys)]
251                xlim= self._minmaxx or [min(x),max(x)]
252            allylim += ylim
253            allxlim += xlim
254            if (panelcount == n) or (r == nr-1):
255                break
256            r+=1 # next row
257
258        # Set x- and y- limts of subplots
259        if ganged:
260            xlim = None
261            ylim = None
262            if len(allylim) > 0:
263                allylim.sort()
264                ylim = allylim[0],allylim[-1]
265            if len(allxlim) > 0:
266                allxlim.sort()
267                xlim = allxlim[0],allxlim[-1]
268            self._plotter.set_limits(xlim=xlim,ylim=ylim)
269
270        # save the current counter for multi-page plotting
271        self._startrow = r+1
272        self._ipanel += panelcount
273        if self.casabar_exists():
274            if self._ipanel >= nptot-1:
275                self._plotter.figmgr.casabar.disable_next()
276            else:
277                self._plotter.figmgr.casabar.enable_next()
278            if self._ipanel + 1 - panelcount > 0:
279                self._plotter.figmgr.casabar.enable_prev()
280            else:
281                self._plotter.figmgr.casabar.disable_prev()
282
283               
284
285    def _get_label(self, scan, row, mode='title', userlabel=None):
286        if isinstance(userlabel, list) and len(userlabel) == 0:
287            userlabel = " "
288        elif not mode.upper().startswith('T'):
289            pms = dict(zip(self._selection.get_pols(), \
290                           self._selection.get_poltypes()))
291            if len(pms):
292                poleval = scan._getpollabel(scan.getpol(row), \
293                                            pms[scan.getpol(row)])
294            else:
295                poleval = scan._getpollabel(scan.getpol(row),scan.poltype())
296            label = "IF%d, POL %s, Scan%d" % \
297                    (scan.getif(row),poleval,scan.getscan(row))
298        else:
299            label = "row %d" % (row)
300           
301        return userlabel or label
302       
303
304    def _is_new_scan(self,scan):
305        if isinstance(scan, scantable):
306            if self._data is not None:
307                if scan != self._data:
308                    return True
309            else:
310                return True
311        return False
Note: See TracBrowser for help on using the repository browser.