source: trunk/python/asapplotter.py @ 1217

Last change on this file since 1217 was 1217, checked in by mar637, 18 years ago

Merge from Release2.1.0b tag

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 28.6 KB
Line 
1from asap import rcParams, print_log, selector
2from asap import NUM
3import matplotlib.axes
4import sre
5
6class asapplotter:
7    """
8    The ASAP plotter.
9    By default the plotter is set up to plot polarisations
10    'colour stacked' and scantables across panels.
11    Note:
12        Currenly it only plots 'spectra' not Tsys or
13        other variables.
14    """
15    def __init__(self, visible=None):
16        self._visible = rcParams['plotter.gui']
17        if visible is not None:
18            self._visible = visible
19        self._plotter = self._newplotter()
20
21        self._panelling = None
22        self._stacking = None
23        self.set_panelling()
24        self.set_stacking()
25        self._rows = None
26        self._cols = None
27        self._autoplot = False
28        self._minmaxx = None
29        self._minmaxy = None
30        self._datamask = None
31        self._data = None
32        self._lmap = None
33        self._title = None
34        self._ordinate = None
35        self._abcissa = None
36        self._abcunit = None
37        self._usermask = []
38        self._maskselection = None
39        self._selection = selector()
40        self._hist = rcParams['plotter.histogram']
41
42    def _translate(self, instr):
43        keys = "s b i p t".split()
44        if isinstance(instr, str):
45            for key in keys:
46                if instr.lower().startswith(key):
47                    return key
48        return None
49
50    def _newplotter(self):
51        if self._visible:
52            from asap.asaplotgui import asaplotgui as asaplot
53        else:
54            from asap.asaplot import asaplot
55        return asaplot()
56
57
58    def plot(self, scan=None):
59        """
60        Plot a scantable.
61        Parameters:
62            scan:   a scantable
63        Note:
64            If a scantable was specified in a previous call
65            to plot, no argument has to be given to 'replot'
66            NO checking is done that the abcissas of the scantable
67            are consistent e.g. all 'channel' or all 'velocity' etc.
68        """
69        if self._plotter.is_dead:
70            self._plotter = self._newplotter()
71        self._plotter.hold()
72        self._plotter.clear()
73        from asap import scantable
74        if not self._data and not scan:
75            msg = "Input is not a scantable"
76            if rcParams['verbose']:
77                print msg
78                return
79            raise TypeError(msg)
80        if isinstance(scan, scantable):
81            if self._data is not None:
82                if scan != self._data:
83                    self._data = scan
84                    # reset
85                    self._reset()
86            else:
87                self._data = scan
88                self._reset()
89        # ranges become invalid when unit changes
90        if self._abcunit and self._abcunit != self._data.get_unit():
91            self._minmaxx = None
92            self._minmaxy = None
93            self._abcunit = self._data.get_unit()
94            self._datamask = None
95        self._plot(self._data)
96        if self._minmaxy is not None:
97            self._plotter.set_limits(ylim=self._minmaxy)
98        self._plotter.release()
99        self._plotter.tidy()
100        self._plotter.show(hardrefresh=False)
101        print_log()
102        return
103
104
105    # forwards to matplotlib axes
106    def text(self, *args, **kwargs):
107        self._axes_callback("text", *args, **kwargs)
108    text. __doc__ = matplotlib.axes.Axes.text.__doc__
109    def arrow(self, *args, **kwargs):
110        self._axes_callback("arrow", *args, **kwargs)
111    arrow. __doc__ = matplotlib.axes.Axes.arrow.__doc__
112    def axvline(self, *args, **kwargs):
113        self._axes_callback("axvline", *args, **kwargs)
114    axvline. __doc__ = matplotlib.axes.Axes.axvline.__doc__
115    def axhline(self, *args, **kwargs):
116        self._axes_callback("axhline", *args, **kwargs)
117    axhline. __doc__ = matplotlib.axes.Axes.axhline.__doc__
118    def axvspan(self, *args, **kwargs):
119        self._axes_callback("axvspan", *args, **kwargs)
120        # hack to preventy mpl from redrawing the patch
121        # it seem to convert the patch into lines on every draw.
122        # This doesn't happen in a test script???
123        del self._plotter.axes.patches[-1]
124    axvspan. __doc__ = matplotlib.axes.Axes.axvspan.__doc__
125    def axhspan(self, *args, **kwargs):
126        self._axes_callback("ahvspan", *args, **kwargs)
127        # hack to preventy mpl from redrawing the patch
128        # it seem to convert the patch into lines on every draw.
129        # This doesn't happen in a test script???
130        del self._plotter.axes.patches[-1]
131    axhspan. __doc__ = matplotlib.axes.Axes.axhspan.__doc__
132
133    def _axes_callback(self, axesfunc, *args, **kwargs):
134        panel = 0
135        if kwargs.has_key("panel"):
136            panel = kwargs.pop("panel")
137        coords = None
138        if kwargs.has_key("coords"):
139            coords = kwargs.pop("coords")
140            if coords.lower() == 'world':
141                kwargs["transform"] = self._plotter.axes.transData
142            elif coords.lower() == 'relative':
143                kwargs["transform"] = self._plotter.axes.transAxes
144        self._plotter.subplot(panel)
145        self._plotter.axes.set_autoscale_on(False)
146        getattr(self._plotter.axes, axesfunc)(*args, **kwargs)
147        self._plotter.show(False)
148        self._plotter.axes.set_autoscale_on(True)
149    # end matplotlib.axes fowarding functions
150
151    def set_mode(self, stacking=None, panelling=None):
152        """
153        Set the plots look and feel, i.e. what you want to see on the plot.
154        Parameters:
155            stacking:     tell the plotter which variable to plot
156                          as line colour overlays (default 'pol')
157            panelling:    tell the plotter which variable to plot
158                          across multiple panels (default 'scan'
159        Note:
160            Valid modes are:
161                 'beam' 'Beam' 'b':     Beams
162                 'if' 'IF' 'i':         IFs
163                 'pol' 'Pol' 'p':       Polarisations
164                 'scan' 'Scan' 's':     Scans
165                 'time' 'Time' 't':     Times
166        """
167        msg = "Invalid mode"
168        if not self.set_panelling(panelling) or \
169               not self.set_stacking(stacking):
170            if rcParams['verbose']:
171                print msg
172                return
173            else:
174                raise TypeError(msg)
175        if self._data: self.plot(self._data)
176        return
177
178    def set_panelling(self, what=None):
179        mode = what
180        if mode is None:
181             mode = rcParams['plotter.panelling']
182        md = self._translate(mode)
183        if md:
184            self._panelling = md
185            self._title = None
186            return True
187        return False
188
189    def set_layout(self,rows=None,cols=None):
190        """
191        Set the multi-panel layout, i.e. how many rows and columns plots
192        are visible.
193        Parameters:
194             rows:   The number of rows of plots
195             cols:   The number of columns of plots
196        Note:
197             If no argument is given, the potter reverts to its auto-plot
198             behaviour.
199        """
200        self._rows = rows
201        self._cols = cols
202        if self._data: self.plot(self._data)
203        return
204
205    def set_stacking(self, what=None):
206        mode = what
207        if mode is None:
208             mode = rcParams['plotter.stacking']
209        md = self._translate(mode)
210        if md:
211            self._stacking = md
212            self._lmap = None
213            return True
214        return False
215
216    def set_range(self,xstart=None,xend=None,ystart=None,yend=None):
217        """
218        Set the range of interest on the abcissa of the plot
219        Parameters:
220            [x,y]start,[x,y]end:  The start and end points of the 'zoom' window
221        Note:
222            These become non-sensical when the unit changes.
223            use plotter.set_range() without parameters to reset
224
225        """
226        if xstart is None and xend is None:
227            self._minmaxx = None
228        else:
229            self._minmaxx = [xstart,xend]
230        if ystart is None and yend is None:
231            self._minmaxy = None
232        else:
233            self._minmaxy = [ystart,yend]
234        if self._data: self.plot(self._data)
235        return
236
237    def set_legend(self, mp=None, fontsize = None, mode = 0):
238        """
239        Specify a mapping for the legend instead of using the default
240        indices:
241        Parameters:
242            mp:        a list of 'strings'. This should have the same length
243                       as the number of elements on the legend and then maps
244                       to the indeces in order. It is possible to uses latex
245                       math expression. These have to be enclosed in r'',
246                       e.g. r'$x^{2}$'
247            fontsize:  The font size of the label (default None)
248            mode:      where to display the legend
249                       Any other value for loc else disables the legend:
250                        0: auto
251                        1: upper right
252                        2: upper left
253                        3: lower left
254                        4: lower right
255                        5: right
256                        6: center left
257                        7: center right
258                        8: lower center
259                        9: upper center
260                        10: center
261
262        Example:
263             If the data has two IFs/rest frequencies with index 0 and 1
264             for CO and SiO:
265             plotter.set_stacking('i')
266             plotter.set_legend(['CO','SiO'])
267             plotter.plot()
268             plotter.set_legend([r'$^{12}CO$', r'SiO'])
269        """
270        self._lmap = mp
271        self._plotter.legend(mode)
272        if isinstance(fontsize, int):
273            from matplotlib import rc as rcp
274            rcp('legend', fontsize=fontsize)
275        if self._data:
276            self.plot(self._data)
277        return
278
279    def set_title(self, title=None, fontsize=None):
280        """
281        Set the title of the plot. If multiple panels are plotted,
282        multiple titles have to be specified.
283        Example:
284             # two panels are visible on the plotter
285             plotter.set_title(["First Panel","Second Panel"])
286        """
287        self._title = title
288        if isinstance(fontsize, int):
289            from matplotlib import rc as rcp
290            rcp('axes', titlesize=fontsize)
291        if self._data: self.plot(self._data)
292        return
293
294    def set_ordinate(self, ordinate=None, fontsize=None):
295        """
296        Set the y-axis label of the plot. If multiple panels are plotted,
297        multiple labels have to be specified.
298        Parameters:
299            ordinate:    a list of ordinate labels. None (default) let
300                         data determine the labels
301        Example:
302             # two panels are visible on the plotter
303             plotter.set_ordinate(["First Y-Axis","Second Y-Axis"])
304        """
305        self._ordinate = ordinate
306        if isinstance(fontsize, int):
307            from matplotlib import rc as rcp
308            rcp('axes', labelsize=fontsize)
309            rcp('ytick', labelsize=fontsize)
310        if self._data: self.plot(self._data)
311        return
312
313    def set_abcissa(self, abcissa=None, fontsize=None):
314        """
315        Set the x-axis label of the plot. If multiple panels are plotted,
316        multiple labels have to be specified.
317        Parameters:
318            abcissa:     a list of abcissa labels. None (default) let
319                         data determine the labels
320        Example:
321             # two panels are visible on the plotter
322             plotter.set_ordinate(["First X-Axis","Second X-Axis"])
323        """
324        self._abcissa = abcissa
325        if isinstance(fontsize, int):
326            from matplotlib import rc as rcp
327            rcp('axes', labelsize=fontsize)
328            rcp('xtick', labelsize=fontsize)
329        if self._data: self.plot(self._data)
330        return
331
332    def set_colors(self, colmap):
333        """
334        Set the colours to be used. The plotter will cycle through
335        these colours when lines are overlaid (stacking mode).
336        Parameters:
337            colmap:     a list of colour names
338        Example:
339             plotter.set_colors("red green blue")
340             # If for example four lines are overlaid e.g I Q U V
341             # 'I' will be 'red', 'Q' will be 'green', U will be 'blue'
342             # and 'V' will be 'red' again.
343        """
344        if isinstance(colmap,str):
345            colmap = colmap.split()
346        self._plotter.palette(0, colormap=colmap)
347        if self._data: self.plot(self._data)
348
349    # alias for english speakers
350    set_colours = set_colors
351
352    def set_histogram(self, hist=True, linewidth=None):
353        """
354        Enable/Disable histogram-like plotting.
355        Parameters:
356            hist:        True (default) or False. The fisrt default
357                         is taken from the .asaprc setting
358                         plotter.histogram
359        """
360        self._hist = hist
361        if isinstance(linewidth, float) or isinstance(linewidth, int):
362            from matplotlib import rc as rcp
363            rcp('lines', linewidth=linewidth)
364        if self._data: self.plot(self._data)
365
366    def set_linestyles(self, linestyles=None, linewidth=None):
367        """
368        Set the linestyles to be used. The plotter will cycle through
369        these linestyles when lines are overlaid (stacking mode) AND
370        only one color has been set.
371        Parameters:
372             linestyles:     a list of linestyles to use.
373                             'line', 'dashed', 'dotted', 'dashdot',
374                             'dashdotdot' and 'dashdashdot' are
375                             possible
376
377        Example:
378             plotter.set_colors("black")
379             plotter.set_linestyles("line dashed dotted dashdot")
380             # If for example four lines are overlaid e.g I Q U V
381             # 'I' will be 'solid', 'Q' will be 'dashed',
382             # U will be 'dotted' and 'V' will be 'dashdot'.
383        """
384        if isinstance(linestyles,str):
385            linestyles = linestyles.split()
386        self._plotter.palette(color=0,linestyle=0,linestyles=linestyles)
387        if isinstance(linewidth, float) or isinstance(linewidth, int):
388            from matplotlib import rc as rcp
389            rcp('lines', linewidth=linewidth)
390        if self._data: self.plot(self._data)
391
392    def set_font(self, family=None, style=None, weight=None, size=None):
393        """
394        Set font properties.
395        Parameters:
396            family:    one of 'sans-serif', 'serif', 'cursive', 'fantasy', 'monospace'
397            style:     one of 'normal' (or 'roman'), 'italic'  or 'oblique'
398            weight:    one of 'normal or 'bold'
399            size:      the 'general' font size, individual elements can be adjusted
400                       seperately
401        """
402        from matplotlib import rc as rcp
403        if isinstance(family, str):
404            rcp('font', family=family)
405        if isinstance(style, str):
406            rcp('font', style=style)
407        if isinstance(weight, str):
408            rcp('font', weight=weight)
409        if isinstance(size, float) or isinstance(size, int):
410            rcp('font', size=size)
411        if self._data: self.plot(self._data)
412
413    def plot_lines(self, linecat=None, doppler=0.0, deltachan=10, rotate=0.0,
414                   location=None):
415        """
416        Plot a line catalog.
417        Parameters:
418            linecat:      the linecatalog to plot
419            doppler:      the velocity shift to apply to the frequencies
420            deltachan:    the number of channels to include each side of the
421                          line to determine a local maximum/minimum
422            rotate:       the rotation for the text label
423            location:     the location of the line annotation from the 'top',
424                          'bottom' or alternate (None - the default)
425        Notes:
426        If the spectrum is flagged no line will be drawn in that location.
427        """
428        if not self._data: return
429        from asap._asap import linecatalog
430        if not isinstance(linecat, linecatalog): return
431        if not self._data.get_unit().endswith("GHz"): return
432        #self._plotter.hold()
433        from matplotlib.numerix import ma
434        for j in range(len(self._plotter.subplots)):
435            self._plotter.subplot(j)
436            lims = self._plotter.axes.get_xlim()
437            for row in range(linecat.nrow()):
438                restf = linecat.get_frequency(row)/1000.0
439                c = 299792.458
440                freq = restf*(1.0-doppler/c)
441                if lims[0] < freq < lims[1]:
442                    if location is None:
443                        loc = 'bottom'
444                        if row%2: loc='top'
445                    else: loc = location
446                    maxys = []
447                    for line in self._plotter.axes.lines:
448                        v = line._x
449                        asc = v[0] < v[-1]
450
451                        idx = None
452                        if not asc:
453                            if v[len(v)-1] <= freq <= v[0]:
454                                i = len(v)-1
455                                while i>=0 and v[i] < freq:
456                                    idx = i
457                                    i-=1
458                        else:
459                           if v[0] <= freq <= v[len(v)-1]:
460                                i = 0
461                                while  i<len(v) and v[i] < freq:
462                                    idx = i
463                                    i+=1
464                        if idx is not None:
465                            lower = idx - deltachan
466                            upper = idx + deltachan
467                            if lower < 0: lower = 0
468                            if upper > len(v): upper = len(v)
469                            s = slice(lower, upper)
470                            y = line._y[s]
471                            maxy = ma.maximum(y)
472                            if isinstance( maxy, float):
473                                maxys.append(maxy)
474                    if len(maxys):
475                        peak = max(maxys)
476                        if peak > self._plotter.axes.get_ylim()[1]:
477                            loc = 'bottom'
478                    else:
479                        continue
480                    self._plotter.vline_with_label(freq, peak,
481                                                   linecat.get_name(row),
482                                                   location=loc, rotate=rotate)
483        #        self._plotter.release()
484        self._plotter.show(hardrefresh=False)
485
486
487    def save(self, filename=None, orientation=None, dpi=None):
488        """
489        Save the plot to a file. The know formats are 'png', 'ps', 'eps'.
490        Parameters:
491             filename:    The name of the output file. This is optional
492                          and autodetects the image format from the file
493                          suffix. If non filename is specified a file
494                          called 'yyyymmdd_hhmmss.png' is created in the
495                          current directory.
496             orientation: optional parameter for postscript only (not eps).
497                          'landscape', 'portrait' or None (default) are valid.
498                          If None is choosen for 'ps' output, the plot is
499                          automatically oriented to fill the page.
500             dpi:         The dpi of the output non-ps plot
501        """
502        self._plotter.save(filename,orientation,dpi)
503        return
504
505
506    def set_mask(self, mask=None, selection=None):
507        """
508        Set a plotting mask for a specific polarization.
509        This is useful for masking out "noise" Pangle outside a source.
510        Parameters:
511             mask:           a mask from scantable.create_mask
512             selection:      the spectra to apply the mask to.
513        Example:
514             select = selector()
515             select.setpolstrings("Pangle")
516             plotter.set_mask(mymask, select)
517        """
518        if not self._data:
519            msg = "Can only set mask after a first call to plot()"
520            if rcParams['verbose']:
521                print msg
522                return
523            else:
524                raise RuntimeError(msg)
525        if len(mask):
526            if isinstance(mask, list) or isinstance(mask, tuple):
527                self._usermask = array(mask)
528            else:
529                self._usermask = mask
530        if mask is None and selection is None:
531            self._usermask = []
532            self._maskselection = None
533        if isinstance(selection, selector):
534            self._maskselection = {'b': selection.get_beams(),
535                                   's': selection.get_scans(),
536                                   'i': selection.get_ifs(),
537                                   'p': selection.get_pols(),
538                                   't': [] }
539        else:
540            self._maskselection = None
541        self.plot(self._data)
542
543    def _slice_indeces(self, data):
544        mn = self._minmaxx[0]
545        mx = self._minmaxx[1]
546        asc = data[0] < data[-1]
547        start=0
548        end = len(data)-1
549        inc = 1
550        if not asc:
551            start = len(data)-1
552            end = 0
553            inc = -1
554        # find min index
555        while start > 0 and data[start] < mn:
556            start+= inc
557        # find max index
558        while end > 0 and data[end] > mx:
559            end-=inc
560        if end > 0: end +=1
561        if start > end:
562            return end,start
563        return start,end
564
565    def _reset(self):
566        self._usermask = []
567        self._usermaskspectra = None
568        self.set_selection(None, False)
569
570    def _plot(self, scan):
571        savesel = scan.get_selection()
572        sel = savesel +  self._selection
573        d0 = {'s': 'SCANNO', 'b': 'BEAMNO', 'i':'IFNO',
574              'p': 'POLNO', 'c': 'CYCLENO', 't' : 'TIME' }
575        order = [d0[self._panelling],d0[self._stacking]]
576        sel.set_order(order)
577        scan.set_selection(sel)
578        d = {'b': scan.getbeam, 's': scan.getscan,
579             'i': scan.getif, 'p': scan.getpol, 't': scan._gettime }
580
581        polmodes = dict(zip(self._selection.get_pols(),
582                            self._selection.get_poltypes()))
583        # this returns either a tuple of numbers or a length  (ncycles)
584        # convert this into lengths
585        n0,nstack0 = self._get_selected_n(scan)
586        if isinstance(n0, int): n = n0
587        else: n = len(n0)
588        if isinstance(nstack0, int): nstack = nstack0
589        else: nstack = len(nstack0)
590        maxpanel, maxstack = 16,8
591        if n > maxpanel or nstack > maxstack:
592            from asap import asaplog
593            maxn = 0
594            if nstack > maxstack: maxn = maxstack
595            if n > maxpanel: maxn = maxpanel
596            msg ="Scan to be plotted contains more than %d selections.\n" \
597                  "Selecting first %d selections..." % (maxn, maxn)
598            asaplog.push(msg)
599            print_log()
600            n = min(n,maxpanel)
601            nstack = min(nstack,maxstack)
602        if n > 1:
603            ganged = rcParams['plotter.ganged']
604            if self._rows and self._cols:
605                n = min(n,self._rows*self._cols)
606                self._plotter.set_panels(rows=self._rows,cols=self._cols,
607                                         nplots=n,ganged=ganged)
608            else:
609                self._plotter.set_panels(rows=n,cols=0,nplots=n,ganged=ganged)
610        else:
611            self._plotter.set_panels()
612        r=0
613        nr = scan.nrow()
614        a0,b0 = -1,-1
615        allxlim = []
616        allylim = []
617        newpanel=True
618        panelcount,stackcount = 0,0
619        while r < nr:
620            a = d[self._panelling](r)
621            b = d[self._stacking](r)
622            if a > a0 and panelcount < n:
623                if n > 1:
624                    self._plotter.subplot(panelcount)
625                self._plotter.palette(0)
626                #title
627                xlab = self._abcissa and self._abcissa[panelcount] \
628                       or scan._getabcissalabel()
629                ylab = self._ordinate and self._ordinate[panelcount] \
630                       or scan._get_ordinate_label()
631                self._plotter.set_axes('xlabel',xlab)
632                self._plotter.set_axes('ylabel',ylab)
633                lbl = self._get_label(scan, r, self._panelling, self._title)
634                if isinstance(lbl, list) or isinstance(lbl, tuple):
635                    if 0 <= panelcount < len(lbl):
636                        lbl = lbl[panelcount]
637                    else:
638                        # get default label
639                        lbl = self._get_label(scan, r, self._panelling, None)
640                self._plotter.set_axes('title',lbl)
641                newpanel = True
642                stackcount =0
643                panelcount += 1
644            if (b > b0 or newpanel) and stackcount < nstack:
645                y = []
646                if len(polmodes):
647                    y = scan._getspectrum(r, polmodes[scan.getpol(r)])
648                else:
649                    y = scan._getspectrum(r)
650                m = scan._getmask(r)
651                from matplotlib.numerix import logical_not, logical_and
652                if self._maskselection and len(self._usermask) == len(m):
653                    if d[self._stacking](r) in self._maskselection[self._stacking]:
654                        m = logical_and(m, self._usermask)
655                x = scan._getabcissa(r)
656                from matplotlib.numerix import ma, array
657                y = ma.masked_array(y,mask=logical_not(array(m,copy=False)))
658                if self._minmaxx is not None:
659                    s,e = self._slice_indeces(x)
660                    x = x[s:e]
661                    y = y[s:e]
662                if len(x) > 1024 and rcParams['plotter.decimate']:
663                    fac = len(x)/1024
664                    x = x[::fac]
665                    y = y[::fac]
666                llbl = self._get_label(scan, r, self._stacking, self._lmap)
667                if isinstance(llbl, list) or isinstance(llbl, tuple):
668                    if 0 <= stackcount < len(llbl):
669                        # use user label
670                        llbl = llbl[stackcount]
671                    else:
672                        # get default label
673                        llbl = self._get_label(scan, r, self._stacking, None)
674                self._plotter.set_line(label=llbl)
675                plotit = self._plotter.plot
676                if self._hist: plotit = self._plotter.hist
677                if len(x) > 0:
678                    plotit(x,y)
679                    xlim= self._minmaxx or [min(x),max(x)]
680                    allxlim += xlim
681                    ylim= self._minmaxy or [ma.minimum(y),ma.maximum(y)]
682                    allylim += ylim
683                stackcount += 1
684                # last in colour stack -> autoscale x
685                if stackcount == nstack:
686                    allxlim.sort()
687                    self._plotter.axes.set_xlim([allxlim[0],allxlim[-1]])
688                    # clear
689                    allxlim =[]
690
691            newpanel = False
692            a0=a
693            b0=b
694            # ignore following rows
695            if (panelcount == n) and (stackcount == nstack):
696                # last panel -> autoscale y if ganged
697                if rcParams['plotter.ganged']:
698                    allylim.sort()
699                    self._plotter.set_limits(ylim=[allylim[0],allylim[-1]])
700                break
701            r+=1 # next row
702        #reset the selector to the scantable's original
703        scan.set_selection(savesel)
704
705    def set_selection(self, selection=None, refresh=True):
706        self._selection = isinstance(selection,selector) and selection or selector()
707        d0 = {'s': 'SCANNO', 'b': 'BEAMNO', 'i':'IFNO',
708              'p': 'POLNO', 'c': 'CYCLENO', 't' : 'TIME' }
709        order = [d0[self._panelling],d0[self._stacking]]
710        self._selection.set_order(order)
711        if self._data and refresh: self.plot(self._data)
712
713    def _get_selected_n(self, scan):
714        d1 = {'b': scan.getbeamnos, 's': scan.getscannos,
715             'i': scan.getifnos, 'p': scan.getpolnos, 't': scan.ncycle }
716        d2 = { 'b': self._selection.get_beams(),
717               's': self._selection.get_scans(),
718               'i': self._selection.get_ifs(),
719               'p': self._selection.get_pols(),
720               't': self._selection.get_cycles() }
721        n =  d2[self._panelling] or d1[self._panelling]()
722        nstack = d2[self._stacking] or d1[self._stacking]()
723        return n,nstack
724
725    def _get_label(self, scan, row, mode, userlabel=None):
726        if isinstance(userlabel, list) and len(userlabel) == 0:
727            userlabel = " "
728        pms = dict(zip(self._selection.get_pols(),self._selection.get_poltypes()))
729        if len(pms):
730            poleval = scan._getpollabel(scan.getpol(row),pms[scan.getpol(row)])
731        else:
732            poleval = scan._getpollabel(scan.getpol(row),scan.poltype())
733        d = {'b': "Beam "+str(scan.getbeam(row)),
734             's': scan._getsourcename(row),
735             'i': "IF"+str(scan.getif(row)),
736             'p': poleval,
737             't': str(scan.get_time(row)) }
738        return userlabel or d[mode]
739
Note: See TracBrowser for help on using the repository browser.