source: trunk/python/flagplotter.py @ 2605

Last change on this file since 2605 was 2605, checked in by Kana Sugimoto, 12 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
RevLine 
[1996]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:
[2001]17       scan = asa p.scantable(filename='your_filename',average=False)
[1996]18       guiflagger = asap.flagplotter(visible=True)
19       guiflagger.plot(scan)
20       ### flag/Unflag data graphically.
[2001]21       guiflagger.save_data(name='flagged_file.asap',format='ASAP')
[1996]22   
23    NOTICE:
24       The flagged data is not saved until you explicitly run scantable.save
25    """
26    def __init__(self, visible=None, **kwargs):
[2117]27        self._scan = None
[1996]28        asapplotter.__init__(self,visible=visible, **kwargs)
[2453]29        self._assert_plotter(action='reload')
[2173]30        self._plotter._set_window_title('Flag Plotter')
[1996]31        self._panelling = 'r'
[2001]32        self.set_stacking('scan')
[2115]33        self._ismodified = False
[2605]34        self._showflag = True #False
35        self.set_colors("blue gray",False)
[1996]36
[2173]37    def _new_custombar(self):
[2117]38        backend = matplotlib.get_backend()
[2173]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":
[2155]44            from asap.customgui_tkagg import CustomFlagToolbarTkAgg
[1996]45            return CustomFlagToolbarTkAgg(self)
[2173]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")
[1996]52
[2605]53    def set_showflag(self, show):
54        """ Whether or not plotting flagged data"""
55        if type(show) == bool:
56            self._showflag = show
57
[1996]58    @asaplog_post_dec
59    def _invalid_func(self, name):
60        msg = "Invalid function 'flagplotter."+name+"'"
[2001]61        #raise AttributeError(msg)
[1996]62        asaplog.push(msg)
63        asaplog.post('ERROR')
64
[2001]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
[2605]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
[2001]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')
[2117]88
[2001]89    def plottp(self,*args,**kwargs):
90        """ This function is not available for the class flagplotter """
91        self._invalid_func(name='plottp')
92
[1996]93    def save_data(self, name=None, format=None, overwrite=False):
[2001]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        """
[2451]117        if not self._data:
118            raise RuntimeError("No scantable has been set yet.")
[1996]119        # simply calls scantable.save
120        self._data.save(name,format,overwrite)
[2115]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
[2605]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)
[2115]136        asapplotter.plot(self,scan)
137    plot.__doc__ = asapplotter.plot.__doc__
138
[2175]139    @asaplog_post_dec
140    def _plot(self, scan):
[2605]141        self._plot_with_flag(scan,self._showflag)
[2175]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
[2605]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
[2115]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.