| [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
 | 
|---|
| [1996] | 34 | 
 | 
|---|
| [2173] | 35 |     def _new_custombar(self):
 | 
|---|
| [2117] | 36 |         backend = matplotlib.get_backend()
 | 
|---|
| [2173] | 37 |         # Flag plotter relys on supported GUI backends
 | 
|---|
 | 38 |         if not self._visible:
 | 
|---|
 | 39 |             asaplog.push("GUI backend is not available")
 | 
|---|
 | 40 |             asaplog.post("ERROR")
 | 
|---|
 | 41 |         elif backend == "TkAgg":
 | 
|---|
| [2155] | 42 |             from asap.customgui_tkagg import CustomFlagToolbarTkAgg
 | 
|---|
| [1996] | 43 |             return CustomFlagToolbarTkAgg(self)
 | 
|---|
| [2173] | 44 |         elif backend == "Qt4Agg":
 | 
|---|
 | 45 |             from asap.customgui_qt4agg import CustomFlagToolbarQT4Agg
 | 
|---|
 | 46 |             return CustomFlagToolbarQT4Agg(self)
 | 
|---|
 | 47 |         else:
 | 
|---|
 | 48 |             asaplog.push("Unsupported backend for interactive flagging. Use either TkAgg or PyQt4Agg")
 | 
|---|
 | 49 |             asaplog.post("ERROR")
 | 
|---|
| [1996] | 50 | 
 | 
|---|
 | 51 |     @asaplog_post_dec
 | 
|---|
 | 52 |     def _invalid_func(self, name):
 | 
|---|
 | 53 |         msg = "Invalid function 'flagplotter."+name+"'"
 | 
|---|
| [2001] | 54 |         #raise AttributeError(msg)
 | 
|---|
| [1996] | 55 |         asaplog.push(msg)
 | 
|---|
 | 56 |         asaplog.post('ERROR')
 | 
|---|
 | 57 | 
 | 
|---|
| [2001] | 58 |     def set_panelling(self,which='r'):
 | 
|---|
 | 59 |         """ This function is not available for the class flagplotter """
 | 
|---|
 | 60 |         if which.lower().startswith('r'):
 | 
|---|
 | 61 |             return
 | 
|---|
 | 62 |         msg = "Pannel setting is fixed to row mode in 'flagplotter'"
 | 
|---|
 | 63 |         asaplog.push(msg)
 | 
|---|
 | 64 |         asaplog.post('ERROR')
 | 
|---|
 | 65 |         self._panelling = 'r'
 | 
|---|
 | 66 | 
 | 
|---|
 | 67 |     def plotazel(self,*args,**kwargs):
 | 
|---|
 | 68 |         """ This function is not available for the class flagplotter """
 | 
|---|
 | 69 |         self._invalid_func(name='plotazel')
 | 
|---|
 | 70 |     
 | 
|---|
 | 71 |     def plotpointing(self,*args,**kwargs):
 | 
|---|
 | 72 |         """ This function is not available for the class flagplotter """
 | 
|---|
 | 73 |         self._invalid_func(name='plotpointing')
 | 
|---|
| [2117] | 74 | 
 | 
|---|
| [2001] | 75 |     def plottp(self,*args,**kwargs):
 | 
|---|
 | 76 |         """ This function is not available for the class flagplotter """
 | 
|---|
 | 77 |         self._invalid_func(name='plottp')
 | 
|---|
 | 78 | 
 | 
|---|
| [1996] | 79 |     def save_data(self, name=None, format=None, overwrite=False):
 | 
|---|
| [2001] | 80 |         """
 | 
|---|
 | 81 |         Store the plotted scantable on disk.
 | 
|---|
 | 82 |         This function simply redirects call to scantable.save()
 | 
|---|
 | 83 |         
 | 
|---|
 | 84 |         Parameters:
 | 
|---|
 | 85 |     
 | 
|---|
 | 86 |             name:        the name of the outputfile. For format "ASCII"
 | 
|---|
 | 87 |                          this is the root file name (data in 'name'.txt
 | 
|---|
 | 88 |                          and header in 'name'_header.txt)
 | 
|---|
 | 89 |     
 | 
|---|
 | 90 |             format:      an optional file format. Default is ASAP.
 | 
|---|
 | 91 |                          Allowed are:
 | 
|---|
 | 92 |                             * 'ASAP' (save as ASAP [aips++] Table),
 | 
|---|
 | 93 |                             * 'SDFITS' (save as SDFITS file)
 | 
|---|
 | 94 |                             * 'ASCII' (saves as ascii text file)
 | 
|---|
 | 95 |                             * 'MS2' (saves as an casacore MeasurementSet V2)
 | 
|---|
 | 96 |                             * 'FITS' (save as image FITS - not readable by class)
 | 
|---|
 | 97 |                             * 'CLASS' (save as FITS readable by CLASS)
 | 
|---|
 | 98 |     
 | 
|---|
 | 99 |             overwrite:   If the file should be overwritten if it exists.
 | 
|---|
 | 100 |                          The default False is to return with warning
 | 
|---|
 | 101 |                          without writing the output. USE WITH CARE.
 | 
|---|
 | 102 |         """
 | 
|---|
| [2451] | 103 |         if not self._data:
 | 
|---|
 | 104 |             raise RuntimeError("No scantable has been set yet.")
 | 
|---|
| [1996] | 105 |         # simply calls scantable.save
 | 
|---|
 | 106 |         self._data.save(name,format,overwrite)
 | 
|---|
| [2115] | 107 | 
 | 
|---|
 | 108 |     def set_data(self, scan, refresh=True):
 | 
|---|
 | 109 |         if self._is_new_scan(scan):
 | 
|---|
 | 110 |             self._ismodified = False
 | 
|---|
 | 111 |         asapplotter.set_data(self, scan, refresh)
 | 
|---|
 | 112 |     set_data.__doc__ = asapplotter.set_data.__doc__
 | 
|---|
 | 113 | 
 | 
|---|
 | 114 |     @asaplog_post_dec
 | 
|---|
 | 115 |     def plot(self, scan=None):
 | 
|---|
 | 116 |         if self._is_new_scan(scan):
 | 
|---|
 | 117 |             self._ismodified = False
 | 
|---|
 | 118 |         asapplotter.plot(self,scan)
 | 
|---|
 | 119 |     plot.__doc__ = asapplotter.plot.__doc__
 | 
|---|
 | 120 | 
 | 
|---|
| [2175] | 121 |     @asaplog_post_dec
 | 
|---|
 | 122 |     def _plot(self, scan):
 | 
|---|
 | 123 |         asapplotter._plot(self,scan)
 | 
|---|
 | 124 |         # rescale x-range of subplots 5% margins
 | 
|---|
 | 125 |         ganged = (self._plotter.axes._sharex != None)
 | 
|---|
 | 126 |         if ganged:
 | 
|---|
 | 127 |             np = 1
 | 
|---|
 | 128 |         else:
 | 
|---|
 | 129 |             np = len(self._plotter.subplots)
 | 
|---|
 | 130 |         for ip in xrange(np):
 | 
|---|
 | 131 |             ax = self._plotter.subplots[ip]['axes']
 | 
|---|
 | 132 |             lim0 = ax.get_xlim()
 | 
|---|
 | 133 |             offset = (lim0[1]-lim0[0])*0.05
 | 
|---|
 | 134 |             ax.set_xlim(lim0[0]-offset,lim0[1]+offset)
 | 
|---|
 | 135 |             del ax, lim0, offset
 | 
|---|
 | 136 |     _plot.__doc__ = asapplotter._plot.__doc__
 | 
|---|
 | 137 | 
 | 
|---|
| [2115] | 138 |     def _is_new_scan(self,scan):
 | 
|---|
 | 139 |         if isinstance(scan, scantable):
 | 
|---|
 | 140 |             if self._data is not None:
 | 
|---|
 | 141 |                 if scan != self._data:
 | 
|---|
 | 142 |                     return True
 | 
|---|
 | 143 |             else:
 | 
|---|
 | 144 |                 return True
 | 
|---|
 | 145 |         return False
 | 
|---|