| 1 | from asap import rcParams, print_log, selector
 | 
|---|
| 2 | from numarray import logical_and
 | 
|---|
| 3 | 
 | 
|---|
| 4 | class asapplotter:
 | 
|---|
| 5 |     """
 | 
|---|
| 6 |     The ASAP plotter.
 | 
|---|
| 7 |     By default the plotter is set up to plot polarisations
 | 
|---|
| 8 |     'colour stacked' and scantables across panels.
 | 
|---|
| 9 |     Note:
 | 
|---|
| 10 |         Currenly it only plots 'spectra' not Tsys or
 | 
|---|
| 11 |         other variables.
 | 
|---|
| 12 |     """
 | 
|---|
| 13 |     def __init__(self, visible=None):
 | 
|---|
| 14 |         self._visible = rcParams['plotter.gui']
 | 
|---|
| 15 |         if visible is not None:
 | 
|---|
| 16 |             self._visible = visible
 | 
|---|
| 17 |         self._plotter = self._newplotter()
 | 
|---|
| 18 | 
 | 
|---|
| 19 | 
 | 
|---|
| 20 |         self._panelling = None
 | 
|---|
| 21 |         self._stacking = None
 | 
|---|
| 22 |         self.set_panelling()
 | 
|---|
| 23 |         self.set_stacking()
 | 
|---|
| 24 |         self._rows = None
 | 
|---|
| 25 |         self._cols = None
 | 
|---|
| 26 |         self._autoplot = False
 | 
|---|
| 27 |         self._minmaxx = None
 | 
|---|
| 28 |         self._minmaxy = None
 | 
|---|
| 29 |         self._datamask = None
 | 
|---|
| 30 |         self._data = None
 | 
|---|
| 31 |         self._lmap = None
 | 
|---|
| 32 |         self._title = None
 | 
|---|
| 33 |         self._ordinate = None
 | 
|---|
| 34 |         self._abcissa = None
 | 
|---|
| 35 |         self._abcunit = None
 | 
|---|
| 36 |         self._usermask = []
 | 
|---|
| 37 |         self._maskselection = None
 | 
|---|
| 38 |         self._selection = selector()
 | 
|---|
| 39 | 
 | 
|---|
| 40 |     def _translate(self, instr):
 | 
|---|
| 41 |         keys = "s b i p t".split()
 | 
|---|
| 42 |         if isinstance(instr, str):
 | 
|---|
| 43 |             for key in keys:
 | 
|---|
| 44 |                 if instr.lower().startswith(key):
 | 
|---|
| 45 |                     return key
 | 
|---|
| 46 |         return None
 | 
|---|
| 47 | 
 | 
|---|
| 48 |     def _newplotter(self):
 | 
|---|
| 49 |         if self._visible:
 | 
|---|
| 50 |             from asap.asaplotgui import asaplotgui as asaplot
 | 
|---|
| 51 |         else:
 | 
|---|
| 52 |             from asap.asaplot import asaplot
 | 
|---|
| 53 |         return asaplot()
 | 
|---|
| 54 | 
 | 
|---|
| 55 | 
 | 
|---|
| 56 |     def plot(self, scan=None):
 | 
|---|
| 57 |         """
 | 
|---|
| 58 |         Plot a scantable.
 | 
|---|
| 59 |         Parameters:
 | 
|---|
| 60 |             scan:   a scantable
 | 
|---|
| 61 |         Note:
 | 
|---|
| 62 |             If a scantable was specified in a previous call
 | 
|---|
| 63 |             to plot, no argument has to be given to 'replot'
 | 
|---|
| 64 |             NO checking is done that the abcissas of the scantable
 | 
|---|
| 65 |             are consistent e.g. all 'channel' or all 'velocity' etc.
 | 
|---|
| 66 |         """
 | 
|---|
| 67 |         if self._plotter.is_dead:
 | 
|---|
| 68 |             self._plotter = self._newplotter()
 | 
|---|
| 69 |         self._plotter.hold()
 | 
|---|
| 70 |         self._plotter.clear()
 | 
|---|
| 71 |         from asap import scantable
 | 
|---|
| 72 |         if not self._data and not scan:
 | 
|---|
| 73 |             print "please provide a scantable to plot"
 | 
|---|
| 74 |         if isinstance(scan, scantable):
 | 
|---|
| 75 |             if self._data is not None:
 | 
|---|
| 76 |                 if scan != self._data:
 | 
|---|
| 77 |                     self._data = scan
 | 
|---|
| 78 |                     # reset
 | 
|---|
| 79 |                     self._reset()
 | 
|---|
| 80 |             else:
 | 
|---|
| 81 |                 self._data = scan
 | 
|---|
| 82 |                 self._reset()
 | 
|---|
| 83 |         # ranges become invalid when unit changes
 | 
|---|
| 84 |         if self._abcunit and self._abcunit != self._data.get_unit():
 | 
|---|
| 85 |             self._minmaxx = None
 | 
|---|
| 86 |             self._minmaxy = None
 | 
|---|
| 87 |             self._abcunit = self._data.get_unit()
 | 
|---|
| 88 |             self._datamask = None
 | 
|---|
| 89 |         self._plot(self._data)
 | 
|---|
| 90 |         if self._minmaxy is not None:
 | 
|---|
| 91 |             print "setting limits"
 | 
|---|
| 92 |             self._plotter.set_limits(ylim=self._minmaxy)
 | 
|---|
| 93 |         self._plotter.release()
 | 
|---|
| 94 |         print_log()
 | 
|---|
| 95 |         return
 | 
|---|
| 96 | 
 | 
|---|
| 97 |     def set_mode(self, stacking=None, panelling=None):
 | 
|---|
| 98 |         """
 | 
|---|
| 99 |         Set the plots look and feel, i.e. what you want to see on the plot.
 | 
|---|
| 100 |         Parameters:
 | 
|---|
| 101 |             stacking:     tell the plotter which variable to plot
 | 
|---|
| 102 |                           as line color overlays (default 'pol')
 | 
|---|
| 103 |             panelling:    tell the plotter which variable to plot
 | 
|---|
| 104 |                           across multiple panels (default 'scan'
 | 
|---|
| 105 |         Note:
 | 
|---|
| 106 |             Valid modes are:
 | 
|---|
| 107 |                  'beam' 'Beam' 'b':     Beams
 | 
|---|
| 108 |                  'if' 'IF' 'i':         IFs
 | 
|---|
| 109 |                  'pol' 'Pol' 'p':       Polarisations
 | 
|---|
| 110 |                  'scan' 'Scan' 's':     Scans
 | 
|---|
| 111 |                  'time' 'Time' 't':     Times
 | 
|---|
| 112 |         """
 | 
|---|
| 113 |         msg = "Invalid mode"
 | 
|---|
| 114 |         if not self.set_panelling(panelling) or \
 | 
|---|
| 115 |                not self.set_stacking(stacking):
 | 
|---|
| 116 |             if rcParams['verbose']:
 | 
|---|
| 117 |                 print msg
 | 
|---|
| 118 |                 return
 | 
|---|
| 119 |             else:
 | 
|---|
| 120 |                 raise TypeError(msg)
 | 
|---|
| 121 |         if self._data: self.plot(self._data)
 | 
|---|
| 122 |         return
 | 
|---|
| 123 | 
 | 
|---|
| 124 |     def set_panelling(self, what=None):
 | 
|---|
| 125 |         mode = what
 | 
|---|
| 126 |         if mode is None:
 | 
|---|
| 127 |              mode = rcParams['plotter.panelling']
 | 
|---|
| 128 |         md = self._translate(mode)
 | 
|---|
| 129 |         if md:
 | 
|---|
| 130 |             self._panelling = md
 | 
|---|
| 131 |             self._title = None
 | 
|---|
| 132 |             return True
 | 
|---|
| 133 |         return False
 | 
|---|
| 134 | 
 | 
|---|
| 135 |     def set_layout(self,rows=None,cols=None):
 | 
|---|
| 136 |         """
 | 
|---|
| 137 |         Set the multi-panel layout, i.e. how many rows and columns plots
 | 
|---|
| 138 |         are visible.
 | 
|---|
| 139 |         Parameters:
 | 
|---|
| 140 |              rows:   The number of rows of plots
 | 
|---|
| 141 |              cols:   The number of columns of plots
 | 
|---|
| 142 |         Note:
 | 
|---|
| 143 |              If no argument is given, the potter reverts to its auto-plot
 | 
|---|
| 144 |              behaviour.
 | 
|---|
| 145 |         """
 | 
|---|
| 146 |         self._rows = rows
 | 
|---|
| 147 |         self._cols = cols
 | 
|---|
| 148 |         if self._data: self.plot(self._data)
 | 
|---|
| 149 |         return
 | 
|---|
| 150 | 
 | 
|---|
| 151 |     def set_stacking(self, what=None):
 | 
|---|
| 152 |         mode = what
 | 
|---|
| 153 |         if mode is None:
 | 
|---|
| 154 |              mode = rcParams['plotter.stacking']
 | 
|---|
| 155 |         md = self._translate(mode)
 | 
|---|
| 156 |         if md:
 | 
|---|
| 157 |             self._stacking = md
 | 
|---|
| 158 |             self._lmap = None
 | 
|---|
| 159 |             return True
 | 
|---|
| 160 |         return False
 | 
|---|
| 161 | 
 | 
|---|
| 162 |     def set_range(self,xstart=None,xend=None,ystart=None,yend=None):
 | 
|---|
| 163 |         """
 | 
|---|
| 164 |         Set the range of interest on the abcissa of the plot
 | 
|---|
| 165 |         Parameters:
 | 
|---|
| 166 |             [x,y]start,[x,y]end:  The start and end points of the 'zoom' window
 | 
|---|
| 167 |         Note:
 | 
|---|
| 168 |             These become non-sensical when the unit changes.
 | 
|---|
| 169 |             use plotter.set_range() without parameters to reset
 | 
|---|
| 170 | 
 | 
|---|
| 171 |         """
 | 
|---|
| 172 |         if xstart is None and xend is None:
 | 
|---|
| 173 |             self._minmaxx = None
 | 
|---|
| 174 |         else:
 | 
|---|
| 175 |             self._minmaxx = [xstart,xend]
 | 
|---|
| 176 |         if ystart is None and yend is None:
 | 
|---|
| 177 |             self._minmaxy = None
 | 
|---|
| 178 |         else:
 | 
|---|
| 179 |             self._minmaxy = [ystart,yend]
 | 
|---|
| 180 |         if self._data: self.plot(self._data)
 | 
|---|
| 181 |         return
 | 
|---|
| 182 | 
 | 
|---|
| 183 |     def set_legend(self, mp=None):
 | 
|---|
| 184 |         """
 | 
|---|
| 185 |         Specify a mapping for the legend instead of using the default
 | 
|---|
| 186 |         indices:
 | 
|---|
| 187 |         Parameters:
 | 
|---|
| 188 |              mp:    a list of 'strings'. This should have the same length
 | 
|---|
| 189 |                     as the number of elements on the legend and then maps
 | 
|---|
| 190 |                     to the indeces in order. It is possible to uses latex
 | 
|---|
| 191 |                     math expression. These have to be enclosed in r'', e.g. r'$x^{2}$'
 | 
|---|
| 192 | 
 | 
|---|
| 193 |         Example:
 | 
|---|
| 194 |              If the data has two IFs/rest frequencies with index 0 and 1
 | 
|---|
| 195 |              for CO and SiO:
 | 
|---|
| 196 |              plotter.set_stacking('i')
 | 
|---|
| 197 |              plotter.set_legend(['CO','SiO'])
 | 
|---|
| 198 |              plotter.plot()
 | 
|---|
| 199 |              plotter.set_legend([r'$^{12}CO$', r'SiO'])
 | 
|---|
| 200 |         """
 | 
|---|
| 201 |         self._lmap = mp
 | 
|---|
| 202 |         if self._data: self.plot(self._data)
 | 
|---|
| 203 |         return
 | 
|---|
| 204 | 
 | 
|---|
| 205 |     def set_title(self, title=None):
 | 
|---|
| 206 |         """
 | 
|---|
| 207 |         Set the title of the plot. If multiple panels are plotted,
 | 
|---|
| 208 |         multiple titles have to be specified.
 | 
|---|
| 209 |         Example:
 | 
|---|
| 210 |              # two panels are visible on the plotter
 | 
|---|
| 211 |              plotter.set_title(["First Panel","Second Panel"])
 | 
|---|
| 212 |         """
 | 
|---|
| 213 |         self._title = title
 | 
|---|
| 214 |         if self._data: self.plot(self._data)
 | 
|---|
| 215 |         return
 | 
|---|
| 216 | 
 | 
|---|
| 217 |     def set_ordinate(self, ordinate=None):
 | 
|---|
| 218 |         """
 | 
|---|
| 219 |         Set the y-axis label of the plot. If multiple panels are plotted,
 | 
|---|
| 220 |         multiple labels have to be specified.
 | 
|---|
| 221 |         Example:
 | 
|---|
| 222 |              # two panels are visible on the plotter
 | 
|---|
| 223 |              plotter.set_ordinate(["First Y-Axis","Second Y-Axis"])
 | 
|---|
| 224 |         """
 | 
|---|
| 225 |         self._ordinate = ordinate
 | 
|---|
| 226 |         if self._data: self.plot(self._data)
 | 
|---|
| 227 |         return
 | 
|---|
| 228 | 
 | 
|---|
| 229 |     def set_abcissa(self, abcissa=None):
 | 
|---|
| 230 |         """
 | 
|---|
| 231 |         Set the x-axis label of the plot. If multiple panels are plotted,
 | 
|---|
| 232 |         multiple labels have to be specified.
 | 
|---|
| 233 |         Example:
 | 
|---|
| 234 |              # two panels are visible on the plotter
 | 
|---|
| 235 |              plotter.set_ordinate(["First X-Axis","Second X-Axis"])
 | 
|---|
| 236 |         """
 | 
|---|
| 237 |         self._abcissa = abcissa
 | 
|---|
| 238 |         if self._data: self.plot(self._data)
 | 
|---|
| 239 |         return
 | 
|---|
| 240 | 
 | 
|---|
| 241 |     def set_colors(self, colormap):
 | 
|---|
| 242 |         """
 | 
|---|
| 243 |         Set the colors to be used. The plotter will cycle through
 | 
|---|
| 244 |         these colors when lines are overlaid (stacking mode).
 | 
|---|
| 245 |         Example:
 | 
|---|
| 246 |              plotter.set_colors("red green blue")
 | 
|---|
| 247 |              # If for example four lines are overlaid e.g I Q U V
 | 
|---|
| 248 |              # 'I' will be 'red', 'Q' will be 'green', U will be 'blue'
 | 
|---|
| 249 |              # and 'V' will be 'red' again.
 | 
|---|
| 250 |         """
 | 
|---|
| 251 |         if isinstance(colormap,str):
 | 
|---|
| 252 |             colormap = colormap.split()
 | 
|---|
| 253 |         self._plotter.palette(0,colormap=colormap)
 | 
|---|
| 254 |         if self._data: self.plot(self._data)
 | 
|---|
| 255 | 
 | 
|---|
| 256 |     def set_linestyles(self, linestyles):
 | 
|---|
| 257 |         """
 | 
|---|
| 258 |         Set the linestyles to be used. The plotter will cycle through
 | 
|---|
| 259 |         these linestyles when lines are overlaid (stacking mode) AND
 | 
|---|
| 260 |         only one color has been set.
 | 
|---|
| 261 |         Parameters:
 | 
|---|
| 262 |              linestyles:     a list of linestyles to use.
 | 
|---|
| 263 |                              'line', 'dashed', 'dotted', 'dashdot',
 | 
|---|
| 264 |                              'dashdotdot' and 'dashdashdot' are
 | 
|---|
| 265 |                              possible
 | 
|---|
| 266 | 
 | 
|---|
| 267 |         Example:
 | 
|---|
| 268 |              plotter.set_colors("black")
 | 
|---|
| 269 |              plotter.set_linestyles("line dashed dotted dashdot")
 | 
|---|
| 270 |              # If for example four lines are overlaid e.g I Q U V
 | 
|---|
| 271 |              # 'I' will be 'solid', 'Q' will be 'dashed',
 | 
|---|
| 272 |              # U will be 'dotted' and 'V' will be 'dashdot'.
 | 
|---|
| 273 |         """
 | 
|---|
| 274 |         if isinstance(linestyles,str):
 | 
|---|
| 275 |             linestyles = linestyles.split()
 | 
|---|
| 276 |         self._plotter.palette(color=0,linestyle=0,linestyles=linestyles)
 | 
|---|
| 277 |         if self._data: self.plot(self._data)
 | 
|---|
| 278 | 
 | 
|---|
| 279 |     def save(self, filename=None, orientation=None, dpi=None):
 | 
|---|
| 280 |         """
 | 
|---|
| 281 |         Save the plot to a file. The know formats are 'png', 'ps', 'eps'.
 | 
|---|
| 282 |         Parameters:
 | 
|---|
| 283 |              filename:    The name of the output file. This is optional
 | 
|---|
| 284 |                           and autodetects the image format from the file
 | 
|---|
| 285 |                           suffix. If non filename is specified a file
 | 
|---|
| 286 |                           called 'yyyymmdd_hhmmss.png' is created in the
 | 
|---|
| 287 |                           current directory.
 | 
|---|
| 288 |              orientation: optional parameter for postscript only (not eps).
 | 
|---|
| 289 |                           'landscape', 'portrait' or None (default) are valid.
 | 
|---|
| 290 |                           If None is choosen for 'ps' output, the plot is
 | 
|---|
| 291 |                           automatically oriented to fill the page.
 | 
|---|
| 292 |              dpi:         The dpi of the output non-ps plot
 | 
|---|
| 293 |         """
 | 
|---|
| 294 |         self._plotter.save(filename,orientation,dpi)
 | 
|---|
| 295 |         return
 | 
|---|
| 296 | 
 | 
|---|
| 297 | 
 | 
|---|
| 298 |     def set_mask(self, mask=None, selection=None):
 | 
|---|
| 299 |         """
 | 
|---|
| 300 |         Set a plotting mask for a specific polarization.
 | 
|---|
| 301 |         This is useful for masking out "noise" Pangle outside a source.
 | 
|---|
| 302 |         Parameters:
 | 
|---|
| 303 |              mask:           a mask from scantable.create_mask
 | 
|---|
| 304 |              selection:      the spectra to apply the mask to.
 | 
|---|
| 305 |         Example:
 | 
|---|
| 306 |              select = selector()
 | 
|---|
| 307 |              select.setpolstrings("Pangle")
 | 
|---|
| 308 |              plotter.set_mask(mymask, select)
 | 
|---|
| 309 |         """
 | 
|---|
| 310 |         if not self._data:
 | 
|---|
| 311 |             msg = "Can only set mask after a first call to plot()"
 | 
|---|
| 312 |             if rcParams['verbose']:
 | 
|---|
| 313 |                 print msg
 | 
|---|
| 314 |                 return
 | 
|---|
| 315 |             else:
 | 
|---|
| 316 |                 raise RuntimeError(msg)
 | 
|---|
| 317 |         if len(mask):
 | 
|---|
| 318 |             if isinstance(mask, list) or isinstance(mask, tuple):
 | 
|---|
| 319 |                 self._usermask = array(mask)
 | 
|---|
| 320 |             else:
 | 
|---|
| 321 |                 self._usermask = mask
 | 
|---|
| 322 |         if mask is None and selection is None:
 | 
|---|
| 323 |             self._usermask = []
 | 
|---|
| 324 |             self._maskselection = None
 | 
|---|
| 325 |         if isinstance(selection, selector):
 | 
|---|
| 326 |             self._maskselection = {'b': selection.get_beams(),
 | 
|---|
| 327 |                                    's': selection.get_scans(),
 | 
|---|
| 328 |                                    'i': selection.get_ifs(),
 | 
|---|
| 329 |                                    'p': selection.get_pols(),
 | 
|---|
| 330 |                                    't': [] }
 | 
|---|
| 331 |         else:
 | 
|---|
| 332 |             self._maskselection = None
 | 
|---|
| 333 |         self.plot(self._data)
 | 
|---|
| 334 | 
 | 
|---|
| 335 |     def _slice_indeces(self, data):
 | 
|---|
| 336 |         mn = self._minmaxx[0]
 | 
|---|
| 337 |         mx = self._minmaxx[1]
 | 
|---|
| 338 |         asc = data[0] < data[-1]
 | 
|---|
| 339 |         start=0
 | 
|---|
| 340 |         end = len(data)-1
 | 
|---|
| 341 |         inc = 1
 | 
|---|
| 342 |         if not asc:
 | 
|---|
| 343 |             start = len(data)-1
 | 
|---|
| 344 |             end = 0
 | 
|---|
| 345 |             inc = -1
 | 
|---|
| 346 |         # find min index
 | 
|---|
| 347 |         while data[start] < mn:
 | 
|---|
| 348 |             start+= inc
 | 
|---|
| 349 |         # find max index
 | 
|---|
| 350 |         while data[end] > mx:
 | 
|---|
| 351 |             end-=inc
 | 
|---|
| 352 |         end +=1
 | 
|---|
| 353 |         if start > end:
 | 
|---|
| 354 |             return end,start
 | 
|---|
| 355 |         return start,end
 | 
|---|
| 356 | 
 | 
|---|
| 357 |     def _reset(self):
 | 
|---|
| 358 |         self._usermask = []
 | 
|---|
| 359 |         self._usermaskspectra = None
 | 
|---|
| 360 |         self.set_selection(None, False)
 | 
|---|
| 361 | 
 | 
|---|
| 362 |     def _plot(self, scan):
 | 
|---|
| 363 |         savesel = scan.get_selection()
 | 
|---|
| 364 |         sel = savesel +  self._selection
 | 
|---|
| 365 |         d0 = {'s': 'SCANNO', 'b': 'BEAMNO', 'i':'IFNO',
 | 
|---|
| 366 |               'p': 'POLNO', 'c': 'CYCLENO', 't' : 'TIME' }
 | 
|---|
| 367 |         order = [d0[self._panelling],d0[self._stacking]]
 | 
|---|
| 368 |         sel.set_order(order)
 | 
|---|
| 369 |         scan.set_selection(sel)
 | 
|---|
| 370 |         d = {'b': scan.getbeam, 's': scan.getscan,
 | 
|---|
| 371 |              'i': scan.getif, 'p': scan.getpol, 't': scan._gettime }
 | 
|---|
| 372 | 
 | 
|---|
| 373 |         polmodes = dict(zip(self._selection.get_pols(),self._selection.get_poltypes()))
 | 
|---|
| 374 |         n,nstack = self._get_selected_n(scan)
 | 
|---|
| 375 |         maxpanel, maxstack = 9,4
 | 
|---|
| 376 |         if n > maxpanel or nstack > maxstack:
 | 
|---|
| 377 |             from asap import asaplog
 | 
|---|
| 378 |             msg ="Scan to be plotted contains more than %d selections.\n" \
 | 
|---|
| 379 |                   "Selecting first %d selections..." % (maxpanel,maxpanel)
 | 
|---|
| 380 |             asaplog.push(msg)
 | 
|---|
| 381 |             print_log()
 | 
|---|
| 382 |             n = min(n,maxpanel)
 | 
|---|
| 383 |             nstack = min(n,maxstack)
 | 
|---|
| 384 | 
 | 
|---|
| 385 |         if n > 1:
 | 
|---|
| 386 |             ganged = rcParams['plotter.ganged']
 | 
|---|
| 387 |             if self._rows and self._cols:
 | 
|---|
| 388 |                 n = min(n,self._rows*self._cols)
 | 
|---|
| 389 |                 self._plotter.set_panels(rows=self._rows,cols=self._cols,
 | 
|---|
| 390 |                                          nplots=n,ganged=ganged)
 | 
|---|
| 391 |             else:
 | 
|---|
| 392 |                 self._plotter.set_panels(rows=n,cols=0,nplots=n,ganged=ganged)
 | 
|---|
| 393 |         else:
 | 
|---|
| 394 |             self._plotter.set_panels()
 | 
|---|
| 395 |         r=0
 | 
|---|
| 396 |         nr = scan.nrow()
 | 
|---|
| 397 |         a0,b0 = -1,-1
 | 
|---|
| 398 |         allxlim = []
 | 
|---|
| 399 |         newpanel=True
 | 
|---|
| 400 |         panelcount,stackcount = 0,0
 | 
|---|
| 401 |         while r < nr:
 | 
|---|
| 402 |             a = d[self._panelling](r)
 | 
|---|
| 403 |             b = d[self._stacking](r)
 | 
|---|
| 404 | #             print r
 | 
|---|
| 405 | #             print "  a: ",a,a0,panelcount,n
 | 
|---|
| 406 | #             print "  b: ",b,b0,stackcount,nstack
 | 
|---|
| 407 |             if a > a0 and panelcount < n:
 | 
|---|
| 408 |                 if n > 1:
 | 
|---|
| 409 |                     self._plotter.subplot(panelcount)
 | 
|---|
| 410 |                     #pindex += 1
 | 
|---|
| 411 |                 self._plotter.palette(0)
 | 
|---|
| 412 |                 #title
 | 
|---|
| 413 |                 xlab = self._abcissa and self._abcissa[panelcount] \
 | 
|---|
| 414 |                        or scan._getabcissalabel()
 | 
|---|
| 415 |                 ylab = self._ordinate and self._ordinate[panelcount] \
 | 
|---|
| 416 |                        or scan._get_ordinate_label()
 | 
|---|
| 417 |                 self._plotter.set_axes('xlabel',xlab)
 | 
|---|
| 418 |                 self._plotter.set_axes('ylabel',ylab)
 | 
|---|
| 419 |                 lbl = self._get_label(scan, r, self._panelling, self._title)
 | 
|---|
| 420 |                 if isinstance(lbl, list) or isinstance(lbl, tuple):
 | 
|---|
| 421 |                     if 0 <= panelcount < len(lbl):
 | 
|---|
| 422 |                         lbl = lbl[panelcount]
 | 
|---|
| 423 |                     else:
 | 
|---|
| 424 |                         # get default label
 | 
|---|
| 425 |                         lbl = self._get_label(scan, r, self._panelling, None)
 | 
|---|
| 426 |                 self._plotter.set_axes('title',lbl)
 | 
|---|
| 427 |                 newpanel = True
 | 
|---|
| 428 |                 stackcount =0
 | 
|---|
| 429 |                 panelcount += 1
 | 
|---|
| 430 |             if (b > b0 or newpanel) and stackcount < nstack:
 | 
|---|
| 431 |                 y = []
 | 
|---|
| 432 |                 if len(polmodes):
 | 
|---|
| 433 |                     y = scan._getspectrum(r, polmodes[scan.getpol(r)])
 | 
|---|
| 434 |                 else:
 | 
|---|
| 435 |                     y = scan._getspectrum(r)
 | 
|---|
| 436 |                 m = scan._getmask(r)
 | 
|---|
| 437 |                 if self._maskselection and len(self._usermask) == len(m):
 | 
|---|
| 438 |                     if d[self._stacking](r) in self._maskselection[self._stacking]:
 | 
|---|
| 439 |                         print "debug"
 | 
|---|
| 440 |                         m = logical_and(m, self._usermask)
 | 
|---|
| 441 |                 x = scan._getabcissa(r)
 | 
|---|
| 442 |                 if self._minmaxx is not None:
 | 
|---|
| 443 |                     s,e = self._slice_indeces(x)
 | 
|---|
| 444 |                     x = x[s:e]
 | 
|---|
| 445 |                     y = y[s:e]
 | 
|---|
| 446 |                     m = m[s:e]
 | 
|---|
| 447 |                 if len(x) > 1024 and True:#rcParams['plotter.decimate']:
 | 
|---|
| 448 |                     fac = len(x)/1024
 | 
|---|
| 449 |                     x = x[::fac]
 | 
|---|
| 450 |                     m = m[::fac]
 | 
|---|
| 451 |                     y = y[::fac]
 | 
|---|
| 452 |                 llbl = self._get_label(scan, r, self._stacking, self._lmap)
 | 
|---|
| 453 |                 if isinstance(llbl, list) or isinstance(llbl, tuple):
 | 
|---|
| 454 |                     if 0 <= stackcount < len(llbl):
 | 
|---|
| 455 |                         # use user label
 | 
|---|
| 456 |                         llbl = llbl[stackcount]
 | 
|---|
| 457 |                     else:
 | 
|---|
| 458 |                         # get default label
 | 
|---|
| 459 |                         llbl = self._get_label(scan, r, self._stacking, None)
 | 
|---|
| 460 |                 self._plotter.set_line(label=llbl)
 | 
|---|
| 461 |                 self._plotter.plot(x,y,m)
 | 
|---|
| 462 |                 xlim= self._minmaxx or [min(x),max(x)]
 | 
|---|
| 463 |                 allxlim += xlim
 | 
|---|
| 464 |                 stackcount += 1
 | 
|---|
| 465 |                 # last in colour stack -> autoscale x
 | 
|---|
| 466 |                 if stackcount == nstack:
 | 
|---|
| 467 |                     allxlim.sort()
 | 
|---|
| 468 |                     self._plotter.axes.set_xlim([allxlim[0],allxlim[-1]])
 | 
|---|
| 469 |                     # clear
 | 
|---|
| 470 |                     allxlim =[]
 | 
|---|
| 471 | 
 | 
|---|
| 472 |             newpanel = False
 | 
|---|
| 473 |             a0=a
 | 
|---|
| 474 |             b0=b
 | 
|---|
| 475 |             # ignore following rows
 | 
|---|
| 476 |             if (panelcount == n) and (stackcount == nstack):
 | 
|---|
| 477 |                 pass#break
 | 
|---|
| 478 |             r+=1 # next row
 | 
|---|
| 479 |         #reset the selector to the scantable's original
 | 
|---|
| 480 |         scan.set_selection(savesel)
 | 
|---|
| 481 | 
 | 
|---|
| 482 |     def set_selection(self, selection=None, refresh=True):
 | 
|---|
| 483 |         self._selection = isinstance(selection,selector) and selection or selector()
 | 
|---|
| 484 |         d0 = {'s': 'SCANNO', 'b': 'BEAMNO', 'i':'IFNO',
 | 
|---|
| 485 |               'p': 'POLNO', 'c': 'CYCLENO', 't' : 'TIME' }
 | 
|---|
| 486 |         order = [d0[self._panelling],d0[self._stacking]]
 | 
|---|
| 487 |         self._selection.set_order(order)
 | 
|---|
| 488 |         if self._data and refresh: self.plot(self._data)
 | 
|---|
| 489 | 
 | 
|---|
| 490 |     def _get_selected_n(self, scan):
 | 
|---|
| 491 |         d1 = {'b': scan.nbeam, 's': scan.nscan,
 | 
|---|
| 492 |              'i': scan.nif, 'p': scan.npol, 't': scan.ncycle }
 | 
|---|
| 493 |         d2 = { 'b': len(self._selection.get_beams()),
 | 
|---|
| 494 |                's': len(self._selection.get_scans()),
 | 
|---|
| 495 |                'i': len(self._selection.get_ifs()),
 | 
|---|
| 496 |                'p': len(self._selection.get_pols()),
 | 
|---|
| 497 |                't': len(self._selection.get_cycles()) }
 | 
|---|
| 498 |         n =  d2[self._panelling] or d1[self._panelling]()
 | 
|---|
| 499 |         nstack = d2[self._stacking] or d1[self._stacking]()
 | 
|---|
| 500 |         return n,nstack
 | 
|---|
| 501 | 
 | 
|---|
| 502 |     def _get_label(self, scan, row, mode, userlabel=None):
 | 
|---|
| 503 |         pms = dict(zip(self._selection.get_pols(),self._selection.get_poltypes()))
 | 
|---|
| 504 |         if len(pms):
 | 
|---|
| 505 |             poleval = scan._getpollabel(scan.getpol(row),pms[scan.getpol(row)])
 | 
|---|
| 506 |         else:
 | 
|---|
| 507 |             poleval = scan._getpollabel(scan.getpol(row),scan.poltype())
 | 
|---|
| 508 |         d = {'b': "Beam "+str(scan.getbeam(row)),
 | 
|---|
| 509 |              's': scan._getsourcename(row),
 | 
|---|
| 510 |              'i': "IF"+str(scan.getif(row)),
 | 
|---|
| 511 |              'p': poleval,
 | 
|---|
| 512 |              't': scan._gettime(row) }
 | 
|---|
| 513 |         return userlabel or d[mode]
 | 
|---|