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
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.