| [1996] | 1 | from asap.asapplotter import asapplotter
 | 
|---|
 | 2 | from asap.logging import asaplog, asaplog_post_dec
 | 
|---|
 | 3 | 
 | 
|---|
 | 4 | from asap.parameters import rcParams
 | 
|---|
 | 5 | from asap.selector import selector
 | 
|---|
 | 6 | from asap.scantable import scantable
 | 
|---|
 | 7 | import matplotlib.axes
 | 
|---|
 | 8 | from matplotlib.font_manager import FontProperties
 | 
|---|
 | 9 | from matplotlib.text import Text
 | 
|---|
 | 10 | 
 | 
|---|
 | 11 | class 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
 | 
|---|
| [2606] | 34 |         self._showflagged = False
 | 
|---|
| [2605] | 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 | 
 | 
|---|
| [2606] | 53 |     def set_showflagged(self, show):
 | 
|---|
| [2605] | 54 |         """ Whether or not plotting flagged data"""
 | 
|---|
 | 55 |         if type(show) == bool:
 | 
|---|
| [2606] | 56 |             self._showflagged = show
 | 
|---|
 | 57 |             print "self._showflagged =", str(show)
 | 
|---|
 | 58 |         else:
 | 
|---|
 | 59 |             raise TypeError, "Input parameter should be a bool."
 | 
|---|
| [2605] | 60 | 
 | 
|---|
| [1996] | 61 |     @asaplog_post_dec
 | 
|---|
 | 62 |     def _invalid_func(self, name):
 | 
|---|
 | 63 |         msg = "Invalid function 'flagplotter."+name+"'"
 | 
|---|
| [2001] | 64 |         #raise AttributeError(msg)
 | 
|---|
| [1996] | 65 |         asaplog.push(msg)
 | 
|---|
 | 66 |         asaplog.post('ERROR')
 | 
|---|
 | 67 | 
 | 
|---|
| [2001] | 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 | 
 | 
|---|
| [2605] | 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 | 
 | 
|---|
| [2001] | 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')
 | 
|---|
| [2117] | 91 | 
 | 
|---|
| [2001] | 92 |     def plottp(self,*args,**kwargs):
 | 
|---|
 | 93 |         """ This function is not available for the class flagplotter """
 | 
|---|
 | 94 |         self._invalid_func(name='plottp')
 | 
|---|
 | 95 | 
 | 
|---|
| [1996] | 96 |     def save_data(self, name=None, format=None, overwrite=False):
 | 
|---|
| [2001] | 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 |         """
 | 
|---|
| [2451] | 120 |         if not self._data:
 | 
|---|
 | 121 |             raise RuntimeError("No scantable has been set yet.")
 | 
|---|
| [1996] | 122 |         # simply calls scantable.save
 | 
|---|
 | 123 |         self._data.save(name,format,overwrite)
 | 
|---|
| [2115] | 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
 | 
|---|
| [2606] | 135 |         if not self._showflagged:
 | 
|---|
| [2605] | 136 |             self.set_legend(mode=None,refresh=False)
 | 
|---|
 | 137 |         elif not self._legendloc:
 | 
|---|
 | 138 |             self.set_legend(mode=1,refresh=False)
 | 
|---|
| [2115] | 139 |         asapplotter.plot(self,scan)
 | 
|---|
 | 140 |     plot.__doc__ = asapplotter.plot.__doc__
 | 
|---|
 | 141 | 
 | 
|---|
| [2175] | 142 |     @asaplog_post_dec
 | 
|---|
 | 143 |     def _plot(self, scan):
 | 
|---|
| [2606] | 144 |         self._plot_with_flag(scan,self._showflagged)
 | 
|---|
 | 145 |         #asapplotter._plot(self,scan)
 | 
|---|
| [2175] | 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 | 
 | 
|---|
| [2605] | 160 | 
 | 
|---|
 | 161 |     @asaplog_post_dec
 | 
|---|
| [2606] | 162 |     def _plot_with_flag(self, scan, showflag=False):
 | 
|---|
| [2605] | 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
 | 
|---|
| [2606] | 186 |         allylim = []
 | 
|---|
 | 187 |         allxlim = []
 | 
|---|
 | 188 |         
 | 
|---|
| [2605] | 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)
 | 
|---|
| [2606] | 213 |             # Check for FLAGROW column
 | 
|---|
| [2605] | 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
 | 
|---|
| [2606] | 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)
 | 
|---|
| [2605] | 241 |             if showflag:
 | 
|---|
 | 242 |                 self._plotter.set_line(label="flagged")
 | 
|---|
| [2606] | 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
 | 
|---|
| [2605] | 254 |             if (panelcount == n) or (r == nr-1):
 | 
|---|
 | 255 |                 break
 | 
|---|
 | 256 |             r+=1 # next row
 | 
|---|
 | 257 | 
 | 
|---|
| [2606] | 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 | 
 | 
|---|
| [2605] | 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 | 
 | 
|---|
| [2115] | 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
 | 
|---|