source: trunk/python/scantable.py @ 992

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

added function to convert between polarisation types

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 54.9 KB
Line 
1from asap._asap import Scantable
2from asap import rcParams
3from asap import print_log, asaplog
4from asap import selector
5from numarray import ones,zeros
6import sys
7
8class scantable(Scantable):
9    """
10        The ASAP container for scans
11    """
12
13    def __init__(self, filename, average=None, unit=None):
14        """
15        Create a scantable from a saved one or make a reference
16        Parameters:
17            filename:    the name of an asap table on disk
18                         or
19                         the name of a rpfits/sdfits/ms file
20                         (integrations within scans are auto averaged
21                         and the whole file is read)
22                         or
23                         [advanced] a reference to an existing
24                         scantable
25            average:     average all integrations withinb a scan on read.
26                         The default (True) is taken from .asaprc.
27            unit:         brightness unit; must be consistent with K or Jy.
28                         Over-rides the default selected by the reader
29                         (input rpfits/sdfits/ms) or replaces the value
30                         in existing scantables
31        """
32        if average is None:
33            average = rcParams['scantable.autoaverage']
34        varlist = vars()
35        from asap._asap import stmath
36        self._math = stmath()
37        if isinstance(filename, Scantable):
38            Scantable.__init__(self, filename)
39        else:
40            if isinstance(filename,str):
41                import os.path
42                filename = os.path.expandvars(filename)
43                filename = os.path.expanduser(filename)
44                if not os.path.exists(filename):
45                    s = "File '%s' not found." % (filename)
46                    if rcParams['verbose']:
47                        asaplog.push(s)
48                        print asaplog.pop().strip()
49                        return
50                    raise IOError(s)
51                if os.path.isdir(filename):
52                    # crude check if asap table
53                    if os.path.exists(filename+'/table.info'):
54                        Scantable.__init__(self, filename, "memory")
55                        if unit is not None:
56                            self.set_fluxunit(unit)
57                        self.set_freqframe(rcParams['scantable.freqframe'])
58                    else:
59                        msg = "The given file '%s'is not a valid asap table." % (filename)
60                        if rcParams['verbose']:
61                            print msg
62                            return
63                        else:
64                            raise IOError(msg)
65                else:
66                    self._fill([filename],unit, average)
67            elif (isinstance(filename,list) or isinstance(filename,tuple)) \
68                  and isinstance(filename[-1], str):
69                self._fill(filename, unit, average)
70        print_log()
71
72    def save(self, name=None, format=None, overwrite=False):
73        """
74        Store the scantable on disk. This can be an asap (aips++) Table, SDFITS,
75        Image FITS or MS2 format.
76        Parameters:
77            name:        the name of the outputfile. For format="FITS" this
78                         is the directory file name into which all the files
79                         will be written (default is 'asap_FITS'). For format
80                         "ASCII" this is the root file name (data in 'name'.txt
81                         and header in 'name'_header.txt)
82            format:      an optional file format. Default is ASAP.
83                         Allowed are - 'ASAP' (save as ASAP [aips++] Table),
84                                       'SDFITS' (save as SDFITS file)
85                                       'FITS' (saves each row as a FITS Image)
86                                       'ASCII' (saves as ascii text file)
87                                       'MS2' (saves as an aips++
88                                              MeasurementSet V2)
89            overwrite:   If the file should be overwritten if it exists.
90                         The default False is to return with warning
91                         without writing the output. USE WITH CARE.
92        Example:
93            scan.save('myscan.asap')
94            scan.save('myscan.sdfits','SDFITS')
95        """
96        from os import path
97        if format is None: format = rcParams['scantable.save']
98        suffix = '.'+format.lower()
99        if name is None or name =="":
100            name = 'scantable'+suffix
101            from asap import asaplog
102            msg = "No filename given. Using default name %s..." % name
103            asaplog.push(msg)
104        name = path.expandvars(name)
105        if path.isfile(name) or path.isdir(name):
106            if not overwrite:
107                msg = "File %s exists." % name
108                if rcParams['verbose']:
109                    print msg
110                    return
111                else:
112                    raise IOError(msg)
113        format2 = format.upper()
114        if format2 == 'ASAP':
115            self._save(name)
116        else:
117            from asap._asap import stwriter as stw
118            w = stw(format2)
119            w.write(self, name)
120        print_log()
121        return
122
123    def copy(self):
124        """
125        Return a copy of this scantable.
126        Parameters:
127            none
128        Example:
129            copiedscan = scan.copy()
130        """
131        sd = scantable(Scantable._copy(self))
132        return sd
133
134    def get_scan(self, scanid=None):
135        """
136        Return a specific scan (by scanno) or collection of scans (by
137        source name) in a new scantable.
138        Parameters:
139            scanid:    a (list of) scanno or a source name, unix-style
140                       patterns are accepted for source name matching, e.g.
141                       '*_R' gets all 'ref scans
142        Example:
143            # get all scans containing the source '323p459'
144            newscan = scan.get_scan('323p459')
145            # get all 'off' scans
146            refscans = scan.get_scan('*_R')
147            # get a susbset of scans by scanno (as listed in scan.summary())
148            newscan = scan.get_scan([0,2,7,10])
149        """
150        if scanid is None:
151            if rcParams['verbose']:
152                print "Please specify a scan no or name to retrieve from the scantable"
153                return
154            else:
155                raise RuntimeError("No scan given")
156
157        try:
158            bsel = self.get_selection()
159            sel = selector()
160            if type(scanid) is str:
161                sel.set_name(scanid)
162                self.set_selection(bsel+sel)
163                scopy = self._copy()
164                self.set_selection(bsel)
165                return scantable(scopy)
166            elif type(scanid) is int:
167                sel.set_scans([scanid])
168                self.set_selection(bsel+sel)
169                scopy = self._copy()
170                self.set_selection(bsel)
171                return scantable(scopy)
172            elif type(scanid) is list:
173                sel.set_scans(scanid)
174                self.set_selection(sel)
175                scopy = self._copy()
176                self.set_selection(bsel)
177                return scantable(scopy)
178            else:
179                msg = "Illegal scanid type, use 'int' or 'list' if ints."
180                if rcParams['verbose']:
181                    print msg
182                else:
183                    raise TypeError(msg)
184        except RuntimeError:
185            if rcParams['verbose']: print "Couldn't find any match."
186            else: raise
187
188    def __str__(self):
189        return Scantable._summary(self,True)
190
191    def summary(self, filename=None):
192        """
193        Print a summary of the contents of this scantable.
194        Parameters:
195            filename:    the name of a file to write the putput to
196                         Default - no file output
197            verbose:     print extra info such as the frequency table
198                         The default (False) is taken from .asaprc
199        """
200        info = Scantable._summary(self, True)
201        #if verbose is None: verbose = rcParams['scantable.verbosesummary']
202        if filename is not None:
203            if filename is "":
204                filename = 'scantable_summary.txt'
205            from os.path import expandvars, isdir
206            filename = expandvars(filename)
207            if not isdir(filename):
208                data = open(filename, 'w')
209                data.write(info)
210                data.close()
211            else:
212                msg = "Illegal file name '%s'." % (filename)
213                if rcParams['verbose']:
214                    print msg
215                else:
216                    raise IOError(msg)
217        if rcParams['verbose']:
218            try:
219                from IPython.genutils import page as pager
220            except ImportError:
221                from pydoc import pager
222            pager(info)
223        else:
224            return info
225
226
227    def get_selection(self):
228        """
229        """
230        return selector(self._getselection())
231
232    def set_selection(self, selection):
233        """
234        """
235        self._setselection(selection)
236
237    def set_cursor(self, beam=0, IF=0, pol=0):
238        """
239        Set the spectrum for individual operations.
240        Parameters:
241            beam, IF, pol:    a number
242        Example:
243            scan.set_cursor(0,0,1)
244            pol1sig = scan.stats(all=False) # returns std dev for beam=0
245                                            # if=0, pol=1
246        """
247        print "DEPRECATED"
248        varlist = vars()
249        sel = asap._asap.Selector()
250        sel._setbeams([beam])
251        sel._setpols([pol])
252        sel._setifs([IF])
253        self._add_history("set_cursor", varlist)
254        return
255
256    def get_cursor(self):
257        """
258        Return/print a the current 'cursor' into the Beam/IF/Pol cube.
259        Parameters:
260            none
261        Returns:
262            a list of values (currentBeam,currentIF,currentPol)
263        Example:
264            none
265        """
266        print "DEPRECATED"
267        sel = self._getselection()
268        i = sel.getbeams()[0]
269        j = sel.getifs()[0]
270        k = sel.getpols()[0]
271        from asap import asaplog
272        out = "--------------------------------------------------\n"
273        out += " Cursor position\n"
274        out += "--------------------------------------------------\n"
275        out += 'Beam=%d IF=%d Pol=%d ' % (i,j,k)
276        asaplog.push(out)
277        print_log()
278        return i,j,k
279
280    def stats(self, stat='stddev', mask=None):
281        """
282        Determine the specified statistic of the current beam/if/pol
283        Takes a 'mask' as an optional parameter to specify which
284        channels should be excluded.
285        Parameters:
286            stat:    'min', 'max', 'sumsq', 'sum', 'mean'
287                     'var', 'stddev', 'avdev', 'rms', 'median'
288            mask:    an optional mask specifying where the statistic
289                     should be determined.
290        Example:
291            scan.set_unit('channel')
292            msk = scan.create_mask([100,200],[500,600])
293            scan.stats(stat='mean', mask=m)
294        """
295        from numarray import array,zeros,Float
296        if mask == None:
297            mask = []
298        axes = ['Beam','IF','Pol','Time']
299        if not self._check_ifs():
300             raise ValueError("Cannot apply mask as the IFs have different number of channels"
301                              "Please use setselection() to select individual IFs")
302
303        statvals = self._math._stats(self, mask, stat)
304        out = ''
305        axes = []
306        for i in range(self.nrow()):
307            axis = []
308            axis.append(self.getscan(i))
309            axis.append(self.getbeam(i))
310            axis.append(self.getif(i))
311            axis.append(self.getpol(i))
312            axis.append(self.getcycle(i))
313            axes.append(axis)
314            tm = self._gettime(i)
315            src = self._getsourcename(i)
316            out += 'Scan[%d] (%s) ' % (axis[0], src)
317            out += 'Time[%s]:\n' % (tm)
318            if self.nbeam(-1) > 1: out +=  ' Beam[%d] ' % (axis[1])
319            if self.nif(-1) > 1: out +=  ' IF[%d] ' % (axis[2])
320            if self.npol(-1) > 1: out +=  ' Pol[%d] ' % (axis[3])
321            out += '= %3.3f\n' % (statvals[i])
322            out +=  "--------------------------------------------------\n"
323
324        if rcParams['verbose']:
325            print "--------------------------------------------------"
326            print " ",stat
327            print "--------------------------------------------------"
328            print out
329        retval = { 'axesnames': ['scanno','beamno','ifno','polno','cycleno'],
330                   'axes' : axes,
331                   'data': statvals}
332        return retval
333
334    def stddev(self,mask=None):
335        """
336        Determine the standard deviation of the current beam/if/pol
337        Takes a 'mask' as an optional parameter to specify which
338        channels should be excluded.
339        Parameters:
340            mask:    an optional mask specifying where the standard
341                     deviation should be determined.
342
343        Example:
344            scan.set_unit('channel')
345            msk = scan.create_mask([100,200],[500,600])
346            scan.stddev(mask=m)
347        """
348        return self.stats(stat='stddev',mask=mask);
349
350    def get_tsys(self):
351        """
352        Return the System temperatures.
353        Parameters:
354
355        Returns:
356            a list of Tsys values for the current selection
357        """
358
359        return self._row_callback(self._gettsys, "Tsys")
360
361    def _row_callback(self, callback, label):
362        axes = []
363        axesnames = ['scanno','beamno','ifno','polno','cycleno']
364        out = ""
365        outvec =[]
366        for i in range(self.nrow()):
367            axis = []
368            axis.append(self.getscan(i))
369            axis.append(self.getbeam(i))
370            axis.append(self.getif(i))
371            axis.append(self.getpol(i))
372            axis.append(self.getcycle(i))
373            axes.append(axis)
374            tm = self._gettime(i)
375            src = self._getsourcename(i)
376            out += 'Scan[%d] (%s) ' % (axis[0], src)
377            out += 'Time[%s]:\n' % (tm)
378            if self.nbeam(-1) > 1: out +=  ' Beam[%d] ' % (axis[1])
379            if self.nif(-1) > 1: out +=  ' IF[%d] ' % (axis[2])
380            if self.npol(-1) > 1: out +=  ' Pol[%d] ' % (axis[3])
381            outvec.append(callback(i))
382            out += '= %3.3f\n' % (outvec[i])
383            out +=  "--------------------------------------------------\n"
384        if rcParams['verbose']:
385            print "--------------------------------------------------"
386            print " %s" % (label)
387            print "--------------------------------------------------"
388            print out
389        retval = {'axesnames': axesnames, 'axes': axes, 'data': outvec}
390        return retval
391
392
393    def get_time(self, row=-1):
394        """
395        Get a list of time stamps for the observations.
396        Return a string for each integration in the scantable.
397        Parameters:
398            row:    row no of integration. Default -1 return all rows
399        Example:
400            none
401        """
402        out = []
403        if row == -1:
404            for i in range(self.nrow()):
405                out.append(self._gettime(i))
406            return out
407        else:
408            if row < self.nrow():
409                return self._gettime(row)
410
411    def get_sourcename(self, row=-1):
412        """
413        Get a list source names for the observations.
414        Return a string for each integration in the scantable.
415        Parameters:
416            row:    row no of integration. Default -1 return all rows
417        Example:
418            none
419        """
420        out = []
421        if row == -1:
422            return [self._getsourcename(i) for i in range(self.nrow())]
423        else:
424            if  0 <= row < self.nrow():
425                return self._getsourcename(row)
426
427    def get_elevation(self, row=-1):
428        """
429        Get a list of elevations for the observations.
430        Return a float for each integration in the scantable.
431        Parameters:
432            row:    row no of integration. Default -1 return all rows
433        Example:
434            none
435        """
436        out = []
437        if row == -1:
438            return [self._getelevation(i) for i in range(self.nrow())]
439        else:
440            if  0 <= row < self.nrow():
441                return self._getelevation(row)
442
443    def get_azimuth(self, row=-1):
444        """
445        Get a list of azimuths for the observations.
446        Return a float for each integration in the scantable.
447        Parameters:
448            row:    row no of integration. Default -1 return all rows
449        Example:
450            none
451        """
452        out = []
453        if row == -1:
454            return [self._getazimuth(i) for i in range(self.nrow())]
455        else:
456            if  0 <= row < self.nrow():
457                return self._getazimuth(row)
458
459    def get_parangle(self, row=-1):
460        """
461        Get a list of parallactic angles for the observations.
462        Return a float for each integration in the scantable.
463        Parameters:
464            row:    row no of integration. Default -1 return all rows
465        Example:
466            none
467        """
468        out = []
469        if row == -1:
470            return [self._getparangle(i) for i in range(self.nrow())]
471        else:
472            if  0 <= row < self.nrow():
473                return self._getparangle(row)
474
475    def set_unit(self, unit='channel'):
476        """
477        Set the unit for all following operations on this scantable
478        Parameters:
479            unit:    optional unit, default is 'channel'
480                     one of '*Hz','km/s','channel', ''
481        """
482        varlist = vars()
483        if unit in ['','pixel', 'channel']:
484            unit = ''
485        inf = list(self._getcoordinfo())
486        inf[0] = unit
487        self._setcoordinfo(inf)
488        self._add_history("set_unit",varlist)
489
490    def set_instrument(self, instr):
491        """
492        Set the instrument for subsequent processing
493        Parameters:
494            instr:    Select from 'ATPKSMB', 'ATPKSHOH', 'ATMOPRA',
495                      'DSS-43' (Tid), 'CEDUNA', and 'HOBART'
496        """
497        self._setInstrument(instr)
498        self._add_history("set_instument",vars())
499        print_log()
500
501    def set_doppler(self, doppler='RADIO'):
502        """
503        Set the doppler for all following operations on this scantable.
504        Parameters:
505            doppler:    One of 'RADIO', 'OPTICAL', 'Z', 'BETA', 'GAMMA'
506        """
507        varlist = vars()
508        inf = list(self._getcoordinfo())
509        inf[2] = doppler
510        self._setcoordinfo(inf)
511        self._add_history("set_doppler",vars())
512        print_log()
513
514    def set_freqframe(self, frame=None):
515        """
516        Set the frame type of the Spectral Axis.
517        Parameters:
518            frame:   an optional frame type, default 'LSRK'. Valid frames are:
519                     'REST','TOPO','LSRD','LSRK','BARY',
520                     'GEO','GALACTO','LGROUP','CMB'
521        Examples:
522            scan.set_freqframe('BARY')
523        """
524        if frame is None: frame = rcParams['scantable.freqframe']
525        varlist = vars()
526        valid = ['REST','TOPO','LSRD','LSRK','BARY', \
527                   'GEO','GALACTO','LGROUP','CMB']
528
529        if frame in valid:
530            inf = list(self._getcoordinfo())
531            inf[1] = frame
532            self._setcoordinfo(inf)
533            self._add_history("set_freqframe",varlist)
534        else:
535            msg  = "Please specify a valid freq type. Valid types are:\n",valid
536            if rcParams['verbose']:
537                print msg
538            else:
539                raise TypeError(msg)
540        print_log()
541
542    def set_dirframe(self, frame=""):
543        """
544        Set the frame type of the Direction on the sky.
545        Parameters:
546            frame:   an optional frame type, default ''. Valid frames are:
547                     'J2000', 'B1950', 'GALACTIC'
548        Examples:
549            scan.set_dirframe('GALACTIC')
550        """
551        varlist = vars()
552        try:
553            Scantable.set_dirframe(self, frame)
554        except RuntimeError,msg:
555            if rcParams['verbose']:
556                print msg
557            else:
558                raise
559        self._add_history("set_dirframe",varlist)
560
561    def get_unit(self):
562        """
563        Get the default unit set in this scantable
564        Parameters:
565        Returns:
566            A unit string
567        """
568        inf = self._getcoordinfo()
569        unit = inf[0]
570        if unit == '': unit = 'channel'
571        return unit
572
573    def get_abcissa(self, rowno=0):
574        """
575        Get the abcissa in the current coordinate setup for the currently
576        selected Beam/IF/Pol
577        Parameters:
578            rowno:    an optional row number in the scantable. Default is the
579                      first row, i.e. rowno=0
580        Returns:
581            The abcissa values and it's format string (as a dictionary)
582        """
583        abc = self._getabcissa(rowno)
584        lbl = self._getabcissalabel(rowno)
585        print_log()
586        return abc, lbl
587
588    def create_mask(self, *args, **kwargs):
589        """
590        Compute and return a mask based on [min,max] windows.
591        The specified windows are to be INCLUDED, when the mask is
592        applied.
593        Parameters:
594            [min,max],[min2,max2],...
595                Pairs of start/end points specifying the regions
596                to be masked
597            invert:     optional argument. If specified as True,
598                        return an inverted mask, i.e. the regions
599                        specified are EXCLUDED
600            row:        create the mask using the specified row for
601                        unit conversions, default is row=0
602                        only necessary if frequency varies over rows.
603        Example:
604            scan.set_unit('channel')
605
606            a)
607            msk = scan.set_mask([400,500],[800,900])
608            # masks everything outside 400 and 500
609            # and 800 and 900 in the unit 'channel'
610
611            b)
612            msk = scan.set_mask([400,500],[800,900], invert=True)
613            # masks the regions between 400 and 500
614            # and 800 and 900 in the unit 'channel'
615
616        """
617        row = 0
618        if kwargs.has_key("row"):
619            row = kwargs.get("row")
620        data = self._getabcissa(row)
621        u = self._getcoordinfo()[0]
622        if rcParams['verbose']:
623            if u == "": u = "channel"
624            from asap import asaplog
625            msg = "The current mask window unit is %s" % u
626            if not self._check_ifs():
627                msg += "\nThis mask is only valid for IF=%d" % (self.getif(i))
628            asaplog.push(msg)
629        n = self.nchan()
630        msk = zeros(n)
631        # test if args is a 'list' or a 'normal *args - UGLY!!!
632
633        ws = (isinstance(args[-1][-1],int) or isinstance(args[-1][-1],float)) and args or args[0]
634        for window in ws:
635            if (len(window) != 2 or window[0] > window[1] ):
636                raise TypeError("A window needs to be defined as [min,max]")
637            for i in range(n):
638                if data[i] >= window[0] and data[i] < window[1]:
639                    msk[i] = 1
640        if kwargs.has_key('invert'):
641            if kwargs.get('invert'):
642                from numarray import logical_not
643                msk = logical_not(msk)
644        print_log()
645        return msk
646
647    def get_restfreqs(self):
648        """
649        Get the restfrequency(s) stored in this scantable.
650        The return value(s) are always of unit 'Hz'
651        Parameters:
652            none
653        Returns:
654            a list of doubles
655        """
656        return list(self._getrestfreqs())
657
658
659    def set_restfreqs(self, freqs=None, unit='Hz'):
660        """
661        Set or replace the restfrequency specified and
662        If the 'freqs' argument holds a scalar,
663        then that rest frequency will be applied to all the selected
664        data.  If the 'freqs' argument holds
665        a vector, then it MUST be of equal or smaller length than
666        the number of IFs (and the available restfrequencies will be
667        replaced by this vector).  In this case, *all* data have
668        the restfrequency set per IF according
669        to the corresponding value you give in the 'freqs' vector.
670        E.g. 'freqs=[1e9,2e9]'  would mean IF 0 gets restfreq 1e9 and
671        IF 1 gets restfreq 2e9.
672        You can also specify the frequencies via known line names
673        from the built-in Lovas table.
674        Parameters:
675            freqs:   list of rest frequency values or string idenitfiers
676            unit:    unit for rest frequency (default 'Hz')
677
678        Example:
679            # set the given restfrequency for the whole table
680            scan.set_restfreqs(freqs=1.4e9)
681            # If thee number of IFs in the data is >= 2 the IF0 gets the first
682            # value IF1 the second...
683            scan.set_restfreqs(freqs=[1.4e9,1.67e9])
684            #set the given restfrequency for the whole table (by name)
685            scan.set_restfreqs(freqs="OH1667")
686
687        Note:
688            To do more sophisticate Restfrequency setting, e.g. on a
689            source and IF basis, use scantable.set_selection() before using
690            this function.
691            # provide your scantable is call scan
692            selection = selector()
693            selection.set_name("ORION*")
694            selection.set_ifs([1])
695            scan.set_selection(selection)
696            scan.set_restfreqs(freqs=86.6e9)
697
698        """
699        varlist = vars()
700
701        t = type(freqs)
702        if isinstance(freqs, int) or isinstance(freqs,float):
703           self._setrestfreqs(freqs, unit)
704        elif isinstance(freqs, list) or isinstance(freqs,tuple):
705            if isinstance(freqs[-1], int) or isinstance(freqs[-1],float):
706                sel = selector()
707                savesel = self._getselection()
708                for i in xrange(len(freqs)):
709                    sel.set_ifs([i])
710                    self._setselection(sel)
711                    self._setrestfreqs(freqs[i], unit)
712                self._setselection(savesel)
713            elif isinstance(freqs[-1], str):
714                # not yet implemented
715                pass
716        else:
717            return
718        self._add_history("set_restfreqs", varlist)
719
720
721
722    def history(self):
723        hist = list(self._gethistory())
724        out = "-"*80
725        for h in hist:
726            if h.startswith("---"):
727                out += "\n"+h
728            else:
729                items = h.split("##")
730                date = items[0]
731                func = items[1]
732                items = items[2:]
733                out += "\n"+date+"\n"
734                out += "Function: %s\n  Parameters:" % (func)
735                for i in items:
736                    s = i.split("=")
737                    out += "\n   %s = %s" % (s[0],s[1])
738                out += "\n"+"-"*80
739        try:
740            from IPython.genutils import page as pager
741        except ImportError:
742            from pydoc import pager
743        pager(out)
744        return
745
746    #
747    # Maths business
748    #
749
750    def average_time(self, mask=None, scanav=False, weight='tint', align=False):
751        """
752        Return the (time) average of a scan, or apply it 'insitu'.
753        Note:
754            in channels only
755            The cursor of the output scan is set to 0.
756        Parameters:
757            one scan or comma separated  scans
758            mask:     an optional mask (only used for 'var' and 'tsys'
759                      weighting)
760            scanav:   True averages each scan separately
761                      False (default) averages all scans together,
762            weight:   Weighting scheme. 'none', 'var' (1/var(spec)
763                      weighted), 'tsys' (1/Tsys**2 weighted), 'tint'
764                      (integration time weighted) or 'tintsys' (Tint/Tsys**2).
765                      The default is 'tint'
766            align:    align the spectra in velocity before averaging. It takes
767                      the time of the first spectrum as reference time.
768        Example:
769            # time average the scantable without using a mask
770            newscan = scan.average_time()
771        """
772        varlist = vars()
773        if weight is None: weight = 'TINT'
774        if mask is None: mask = ()
775        if scanav:
776            scanav = "SCAN"
777        else:
778            scanav = "NONE"
779        scan = (self,)
780        try:
781          if align:
782              scan = (self.freq_align(insitu=False),)
783          s = scantable(self._math._average(scan, mask, weight.upper(),
784                        scanav))
785        except RuntimeError,msg:
786            if rcParams['verbose']:
787                print msg
788                return
789            else: raise
790        s._add_history("average_time",varlist)
791        print_log()
792        return s
793
794    def convert_flux(self, jyperk=None, eta=None, d=None, insitu=None):
795        """
796        Return a scan where all spectra are converted to either
797        Jansky or Kelvin depending upon the flux units of the scan table.
798        By default the function tries to look the values up internally.
799        If it can't find them (or if you want to over-ride), you must
800        specify EITHER jyperk OR eta (and D which it will try to look up
801        also if you don't set it). jyperk takes precedence if you set both.
802        Parameters:
803            jyperk:      the Jy / K conversion factor
804            eta:         the aperture efficiency
805            d:           the geomtric diameter (metres)
806            insitu:      if False a new scantable is returned.
807                         Otherwise, the scaling is done in-situ
808                         The default is taken from .asaprc (False)
809            allaxes:         if True apply to all spectra. Otherwise
810                         apply only to the selected (beam/pol/if)spectra only
811                         The default is taken from .asaprc (True if none)
812        """
813        if insitu is None: insitu = rcParams['insitu']
814        self._math._setinsitu(insitu)
815        varlist = vars()
816        if jyperk is None: jyperk = -1.0
817        if d is None: d = -1.0
818        if eta is None: eta = -1.0
819        s = scantable(self._math._convertflux(self, d, eta, jyperk))
820        s._add_history("convert_flux", varlist)
821        print_log()
822        if insitu: self._assign(s)
823        else: return s
824
825    def gain_el(self, poly=None, filename="", method="linear", insitu=None):
826        """
827        Return a scan after applying a gain-elevation correction.
828        The correction can be made via either a polynomial or a
829        table-based interpolation (and extrapolation if necessary).
830        You specify polynomial coefficients, an ascii table or neither.
831        If you specify neither, then a polynomial correction will be made
832        with built in coefficients known for certain telescopes (an error
833        will occur if the instrument is not known).
834        The data and Tsys are *divided* by the scaling factors.
835        Parameters:
836            poly:        Polynomial coefficients (default None) to compute a
837                         gain-elevation correction as a function of
838                         elevation (in degrees).
839            filename:    The name of an ascii file holding correction factors.
840                         The first row of the ascii file must give the column
841                         names and these MUST include columns
842                         "ELEVATION" (degrees) and "FACTOR" (multiply data
843                         by this) somewhere.
844                         The second row must give the data type of the
845                         column. Use 'R' for Real and 'I' for Integer.
846                         An example file would be
847                         (actual factors are arbitrary) :
848
849                         TIME ELEVATION FACTOR
850                         R R R
851                         0.1 0 0.8
852                         0.2 20 0.85
853                         0.3 40 0.9
854                         0.4 60 0.85
855                         0.5 80 0.8
856                         0.6 90 0.75
857            method:      Interpolation method when correcting from a table.
858                         Values are  "nearest", "linear" (default), "cubic"
859                         and "spline"
860            insitu:      if False a new scantable is returned.
861                         Otherwise, the scaling is done in-situ
862                         The default is taken from .asaprc (False)
863        """
864
865        if insitu is None: insitu = rcParams['insitu']
866        self._math._setinsitu(insitu)
867        varlist = vars()
868        if poly is None:
869           poly = ()
870        from os.path import expandvars
871        filename = expandvars(filename)
872        s = scantable(self._math._gainel(self, poly, filename, method))
873        s._add_history("gain_el", varlist)
874        print_log()
875        if insitu: self._assign(s)
876        else: return s
877
878    def freq_align(self, reftime=None, method='cubic', insitu=None):
879        """
880        Return a scan where all rows have been aligned in frequency/velocity.
881        The alignment frequency frame (e.g. LSRK) is that set by function
882        set_freqframe.
883        Parameters:
884            reftime:     reference time to align at. By default, the time of
885                         the first row of data is used.
886            method:      Interpolation method for regridding the spectra.
887                         Choose from "nearest", "linear", "cubic" (default)
888                         and "spline"
889            insitu:      if False a new scantable is returned.
890                         Otherwise, the scaling is done in-situ
891                         The default is taken from .asaprc (False)
892        """
893        if insitu is None: insitu = rcParams["insitu"]
894        self._math._setinsitu(insitu)
895        varlist = vars()
896        if reftime is None: reftime = ""
897        s = scantable(self._math._freq_align(self, reftime, method))
898        s._add_history("freq_align", varlist)
899        print_log()
900        if insitu: self._assign(s)
901        else: return s
902
903    def opacity(self, tau, insitu=None):
904        """
905        Apply an opacity correction. The data
906        and Tsys are multiplied by the correction factor.
907        Parameters:
908            tau:         Opacity from which the correction factor is
909                         exp(tau*ZD)
910                         where ZD is the zenith-distance
911            insitu:      if False a new scantable is returned.
912                         Otherwise, the scaling is done in-situ
913                         The default is taken from .asaprc (False)
914        """
915        if insitu is None: insitu = rcParams['insitu']
916        self._math._setinsitu(insitu)
917        varlist = vars()
918        s = scantable(self._math._opacity(self, tau))
919        s._add_history("opacity", varlist)
920        print_log()
921        if insitu: self._assign(s)
922        else: return s
923
924    def bin(self, width=5, insitu=None):
925        """
926        Return a scan where all spectra have been binned up.
927            width:       The bin width (default=5) in pixels
928            insitu:      if False a new scantable is returned.
929                         Otherwise, the scaling is done in-situ
930                         The default is taken from .asaprc (False)
931        """
932        if insitu is None: insitu = rcParams['insitu']
933        self._math._setinsitu(insitu)
934        varlist = vars()
935        s = scantable(self._math._bin(self, width))
936        s._add_history("bin",varlist)
937        print_log()
938        if insitu: self._assign(s)
939        else: return s
940
941
942    def resample(self, width=5, method='cubic', insitu=None):
943        """
944        Return a scan where all spectra have been binned up
945            width:       The bin width (default=5) in pixels
946            method:      Interpolation method when correcting from a table.
947                         Values are  "nearest", "linear", "cubic" (default)
948                         and "spline"
949            insitu:      if False a new scantable is returned.
950                         Otherwise, the scaling is done in-situ
951                         The default is taken from .asaprc (False)
952        """
953        if insitu is None: insitu = rcParams['insitu']
954        self._math._setinsitu(insitu)
955        varlist = vars()
956        s = scantable(self._math._resample(self, method, width))
957        s._add_history("resample",varlist)
958        print_log()
959        if insitu: self._assign(s)
960        else: return s
961
962
963    def average_pol(self, mask=None, weight='none'):
964        """
965        Average the Polarisations together.
966        Parameters:
967            mask:        An optional mask defining the region, where the
968                         averaging will be applied. The output will have all
969                         specified points masked.
970            weight:      Weighting scheme. 'none' (default), 'var' (1/var(spec)
971                         weighted), or 'tsys' (1/Tsys**2 weighted)
972        """
973        varlist = vars()
974        if mask is None:
975            mask = ()
976        s = scantable(self._math._averagepol(self, mask, weight))
977        s._add_history("average_pol",varlist)
978        print_log()
979        return s
980
981    def convert_pol(self, poltype=None):
982        """
983        Convert the data to a different polarisation type.
984        Parameters:
985            poltype:    The new polarisation type. Valid types are:
986                        "linear", "stokes" and "circular"
987        """
988        varlist = vars()
989        try:
990            s = scantable(self._math._convertpol(self, poltype))
991        except RuntimeError,msg:
992            if rcParams['verbose']:
993              print msg
994              return
995            else:
996                raise
997        s._add_history("convert_pol",varlist)
998        print_log()
999        return s
1000
1001    def smooth(self, kernel="hanning", width=5.0, insitu=None):
1002        """
1003        Smooth the spectrum by the specified kernel (conserving flux).
1004        Parameters:
1005            scan:       The input scan
1006            kernel:     The type of smoothing kernel. Select from
1007                        'hanning' (default), 'gaussian' and 'boxcar'.
1008                        The first three characters are sufficient.
1009            width:      The width of the kernel in pixels. For hanning this is
1010                        ignored otherwise it defauls to 5 pixels.
1011                        For 'gaussian' it is the Full Width Half
1012                        Maximum. For 'boxcar' it is the full width.
1013            insitu:     if False a new scantable is returned.
1014                        Otherwise, the scaling is done in-situ
1015                        The default is taken from .asaprc (False)
1016        Example:
1017             none
1018        """
1019        if insitu is None: insitu = rcParams['insitu']
1020        self._math._setinsitu(insitu)
1021        varlist = vars()
1022        s = scantable(self._math._smooth(self,kernel,width))
1023        s._add_history("smooth", varlist)
1024        print_log()
1025        if insitu: self._assign(s)
1026        else: return s
1027
1028
1029    def poly_baseline(self, mask=None, order=0, insitu=None):
1030        """
1031        Return a scan which has been baselined (all rows) by a polynomial.
1032        Parameters:
1033            scan:       a scantable
1034            mask:       an optional mask
1035            order:      the order of the polynomial (default is 0)
1036            insitu:     if False a new scantable is returned.
1037                        Otherwise, the scaling is done in-situ
1038                        The default is taken from .asaprc (False)
1039            allaxes:    If True (default) apply to all spectra. Otherwise
1040                        apply only to the selected (beam/pol/if)spectra only
1041                        The default is taken from .asaprc (True if none)
1042        Example:
1043            # return a scan baselined by a third order polynomial,
1044            # not using a mask
1045            bscan = scan.poly_baseline(order=3)
1046        """
1047        if insitu is None: insitu = rcParams['insitu']
1048        varlist = vars()
1049        if mask is None:
1050            from numarray import ones
1051            mask = list(ones(self.nchan(-1)))
1052        from asap.asapfitter import fitter
1053        f = fitter()
1054        f.set_scan(self, mask)
1055        f.set_function(poly=order)
1056        s = f.auto_fit(insitu)
1057        s._add_history("poly_baseline", varlist)
1058        print_log()
1059        if insitu: self._assign(s)
1060        else: return s
1061
1062    def auto_poly_baseline(self, mask=[], edge=(0,0), order=0,
1063                           threshold=3, insitu=None):
1064        """
1065        Return a scan which has been baselined (all rows) by a polynomial.
1066        Spectral lines are detected first using linefinder and masked out
1067        to avoid them affecting the baseline solution.
1068
1069        Parameters:
1070            mask:       an optional mask retreived from scantable
1071            edge:       an optional number of channel to drop at
1072                        the edge of spectrum. If only one value is
1073                        specified, the same number will be dropped from
1074                        both sides of the spectrum. Default is to keep
1075                        all channels. Nested tuples represent individual
1076                        edge selection for different IFs (a number of spectral
1077                        channels can be different)
1078            order:      the order of the polynomial (default is 0)
1079            threshold:  the threshold used by line finder. It is better to
1080                        keep it large as only strong lines affect the
1081                        baseline solution.
1082            insitu:     if False a new scantable is returned.
1083                        Otherwise, the scaling is done in-situ
1084                        The default is taken from .asaprc (False)
1085
1086        Example:
1087            scan2=scan.auto_poly_baseline(order=7)
1088        """
1089        if insitu is None: insitu = rcParams['insitu']
1090        varlist = vars()
1091        from asap.asapfitter import fitter
1092        from asap.asaplinefind import linefinder
1093        from asap import _is_sequence_or_number as _is_valid
1094
1095        # check whether edge is set up for each IF individually
1096        individualEdge = False;
1097        if len(edge)>1:
1098           if isinstance(edge[0],list) or isinstance(edge[0],tuple):
1099               individualEdge = True;
1100
1101        if not _is_valid(edge, int) and not individualEdge:
1102            raise ValueError, "Parameter 'edge' has to be an integer or a \
1103            pair of integers specified as a tuple. Nested tuples are allowed \
1104            to make individual selection for different IFs."
1105
1106        curedge = (0,0)
1107        if individualEdge:
1108           for edge_par in edge:
1109               if not _is_valid(edge,int):
1110                  raise ValueError, "Each element of the 'edge' tuple has \
1111                  to be a pair of integers or an integer."
1112        else:
1113           curedge = edge;
1114
1115        # setup fitter
1116        f = fitter()
1117        f.set_function(poly=order)
1118
1119        # setup line finder
1120        fl=linefinder()
1121        fl.set_options(threshold=threshold)
1122
1123        if not insitu:
1124            workscan=self.copy()
1125        else:
1126            workscan=self
1127
1128        fl.set_scan(workscan)
1129
1130        rows=range(workscan.nrow())
1131        from asap import asaplog
1132        asaplog.push("Processing:")
1133        for r in rows:
1134            msg = " Scan[%d] Beam[%d] IF[%d] Pol[%d] Cycle[%d]" %        (workscan.getscan(r),workscan.getbeam(r),workscan.getif(r),workscan.getpol(r), workscan.getcycle(r))
1135            asaplog.push(msg, False)
1136
1137            # figure out edge parameter
1138            if individualEdge:
1139               if len(edge)>=workscan.getif(r):
1140                  raise RuntimeError, "Number of edge elements appear to be less than the number of IFs"
1141                  curedge = edge[workscan.getif(r)]
1142
1143            # setup line finder
1144            fl.find_lines(r,mask,curedge)
1145            f.set_scan(workscan, fl.get_mask())
1146            f.x = workscan._getabcissa(r)
1147            f.y = workscan._getspectrum(r)
1148            f.data = None
1149            f.fit()
1150            x = f.get_parameters()
1151            workscan._setspectrum(f.fitter.getresidual(), r)
1152        workscan._add_history("poly_baseline", varlist)
1153        if insitu:
1154            self._assign(workscan)
1155        else:
1156            return workscan
1157
1158    def rotate_linpolphase(self, angle):
1159        """
1160        Rotate the phase of the complex polarization O=Q+iU correlation.
1161        This is always done in situ in the raw data.  So if you call this
1162        function more than once then each call rotates the phase further.
1163        Parameters:
1164            angle:   The angle (degrees) to rotate (add) by.
1165        Examples:
1166            scan.rotate_linpolphase(2.3)
1167        """
1168        varlist = vars()
1169        self._math._rotate_linpolphase(self, angle)
1170        self._add_history("rotate_linpolphase", varlist)
1171        print_log()
1172        return
1173
1174
1175    def rotate_xyphase(self, angle):
1176        """
1177        Rotate the phase of the XY correlation.  This is always done in situ
1178        in the data.  So if you call this function more than once
1179        then each call rotates the phase further.
1180        Parameters:
1181            angle:   The angle (degrees) to rotate (add) by.
1182        Examples:
1183            scan.rotate_xyphase(2.3)
1184        """
1185        varlist = vars()
1186        self._math._rotate_xyphase(self, angle)
1187        self._add_history("rotate_xyphase", varlist)
1188        print_log()
1189        return
1190
1191    def swap_linears(self):
1192        """
1193        Swap the linear polarisations XX and YY
1194        """
1195        varlist = vars()
1196        self._math._swap_linears(self)
1197        self._add_history("swap_linears", varlist)
1198        print_log()
1199        return
1200
1201    def invert_phase(self):
1202        """
1203        Invert the phase of the complex polarisation
1204        """
1205        varlist = vars()
1206        self._math._invert_phase(self)
1207        self._add_history("invert_phase", varlist)
1208        print_log()
1209        return
1210
1211    def add(self, offset, insitu=None):
1212        """
1213        Return a scan where all spectra have the offset added
1214        Parameters:
1215            offset:      the offset
1216            insitu:      if False a new scantable is returned.
1217                         Otherwise, the scaling is done in-situ
1218                         The default is taken from .asaprc (False)
1219        """
1220        if insitu is None: insitu = rcParams['insitu']
1221        self._math._setinsitu(insitu)
1222        varlist = vars()
1223        s = scantable(self._math._unaryop(self, offset, "ADD", False))
1224        s._add_history("add",varlist)
1225        print_log()
1226        if insitu:
1227            self._assign(s)
1228        else:
1229            return s
1230
1231    def scale(self, factor, tsys=True, insitu=None,):
1232        """
1233        Return a scan where all spectra are scaled by the give 'factor'
1234        Parameters:
1235            factor:      the scaling factor
1236            insitu:      if False a new scantable is returned.
1237                         Otherwise, the scaling is done in-situ
1238                         The default is taken from .asaprc (False)
1239            tsys:        if True (default) then apply the operation to Tsys
1240                         as well as the data
1241        """
1242        if insitu is None: insitu = rcParams['insitu']
1243        self._math._setinsitu(insitu)
1244        varlist = vars()
1245        s = scantable(self._math._unaryop(self, factor, "MUL", tsys))
1246        s._add_history("scale",varlist)
1247        print_log()
1248        if insitu:
1249            self._assign(s)
1250        else:
1251            return s
1252
1253    def auto_quotient(self, mode='time', preserve=True):
1254        """
1255        This function allows to build quotients automatically.
1256        It assumes the observation to have the same numer of
1257        "ons" and "offs"
1258        It will support "closest off in time" in the future
1259        Parameters:
1260            mode:           the on/off detection mode; 'suffix' (default)
1261                            'suffix' identifies 'off' scans by the
1262                            trailing '_R' (Mopra/Parkes) or
1263                            '_e'/'_w' (Tid)
1264            preserve:       you can preserve (default) the continuum or
1265                            remove it.  The equations used are
1266                            preserve: Output = Toff * (on/off) - Toff
1267                            remove:   Output = Tref * (on/off) - Ton
1268        """
1269        modes = ["time"]
1270        if not mode in modes:
1271            msg = "please provide valid mode. Valid modes are %s" % (modes)
1272            raise ValueError(msg)
1273        varlist = vars()
1274        s = scantable(self._math._quotient(self, mode, preserve))
1275        s._add_history("auto_quotient",varlist)
1276        print_log()
1277        return s
1278
1279
1280
1281
1282    def freq_switch(self, insitu=None):
1283        """
1284        Apply frequency switching to the data.
1285        Parameters:
1286            insitu:      if False a new scantable is returned.
1287                         Otherwise, the swictching is done in-situ
1288                         The default is taken from .asaprc (False)
1289        Example:
1290            none
1291        """
1292        if insitu is None: insitu = rcParams['insitu']
1293        self._math._setinsitu(insitu)
1294        varlist = vars()
1295        s = scantable(self._math._freqswitch(self))
1296        s._add_history("freq_switch",varlist)
1297        print_log()
1298        if insitu: self._assign(s)
1299        else: return s
1300
1301    def recalc_azel(self):
1302        """
1303        Recalculate the azimuth and elevation for each position.
1304        Parameters:
1305            none
1306        Example:
1307        """
1308        varlist = vars()
1309        self._recalcazel()
1310        self._add_history("recalc_azel", varlist)
1311        print_log()
1312        return
1313
1314    def __add__(self, other):
1315        varlist = vars()
1316        s = None
1317        if isinstance(other, scantable):
1318            print "scantable + scantable NYI"
1319            return
1320        elif isinstance(other, float):
1321            s = scantable(self._math._unaryop(self, other, "ADD", False))
1322        else:
1323            raise TypeError("Other input is not a scantable or float value")
1324        s._add_history("operator +", varlist)
1325        print_log()
1326        return s
1327
1328    def __sub__(self, other):
1329        """
1330        implicit on all axes and on Tsys
1331        """
1332        varlist = vars()
1333        s = None
1334        if isinstance(other, scantable):
1335            print "scantable - scantable NYI"
1336            return
1337        elif isinstance(other, float):
1338            s = scantable(self._math._unaryop(self, other, "SUB", False))
1339        else:
1340            raise TypeError("Other input is not a scantable or float value")
1341        s._add_history("operator -", varlist)
1342        print_log()
1343        return s
1344
1345    def __mul__(self, other):
1346        """
1347        implicit on all axes and on Tsys
1348        """
1349        varlist = vars()
1350        s = None
1351        if isinstance(other, scantable):
1352            print "scantable * scantable NYI"
1353            return
1354        elif isinstance(other, float):
1355            s = scantable(self._math._unaryop(self, other, "MUL", False))
1356        else:
1357            raise TypeError("Other input is not a scantable or float value")
1358        s._add_history("operator *", varlist)
1359        print_log()
1360        return s
1361
1362
1363    def __div__(self, other):
1364        """
1365        implicit on all axes and on Tsys
1366        """
1367        varlist = vars()
1368        s = None
1369        if isinstance(other, scantable):
1370            print "scantable / scantable NYI"
1371            return
1372        elif isinstance(other, float):
1373            if other == 0.0:
1374                raise ZeroDivisionError("Dividing by zero is not recommended")
1375            s = scantable(self._math._unaryop(self, other, "DIV", False))
1376        else:
1377            raise TypeError("Other input is not a scantable or float value")
1378        s._add_history("operator /", varlist)
1379        print_log()
1380        return s
1381
1382    def get_fit(self, row=0):
1383        """
1384        Print or return the stored fits for a row in the scantable
1385        Parameters:
1386            row:    the row which the fit has been applied to.
1387        """
1388        if row > self.nrow():
1389            return
1390        from asap.asapfit import asapfit
1391        fit = asapfit(self._getfit(row))
1392        if rcParams['verbose']:
1393            print fit
1394            return
1395        else:
1396            return fit.as_dict()
1397
1398    def _add_history(self, funcname, parameters):
1399        # create date
1400        sep = "##"
1401        from datetime import datetime
1402        dstr = datetime.now().strftime('%Y/%m/%d %H:%M:%S')
1403        hist = dstr+sep
1404        hist += funcname+sep#cdate+sep
1405        if parameters.has_key('self'): del parameters['self']
1406        for k,v in parameters.iteritems():
1407            if type(v) is dict:
1408                for k2,v2 in v.iteritems():
1409                    hist += k2
1410                    hist += "="
1411                    if isinstance(v2,scantable):
1412                        hist += 'scantable'
1413                    elif k2 == 'mask':
1414                        if isinstance(v2,list) or isinstance(v2,tuple):
1415                            hist += str(self._zip_mask(v2))
1416                        else:
1417                            hist += str(v2)
1418                    else:
1419                        hist += str(v2)
1420            else:
1421                hist += k
1422                hist += "="
1423                if isinstance(v,scantable):
1424                    hist += 'scantable'
1425                elif k == 'mask':
1426                    if isinstance(v,list) or isinstance(v,tuple):
1427                        hist += str(self._zip_mask(v))
1428                    else:
1429                        hist += str(v)
1430                else:
1431                    hist += str(v)
1432            hist += sep
1433        hist = hist[:-2] # remove trailing '##'
1434        self._addhistory(hist)
1435
1436
1437    def _zip_mask(self, mask):
1438        mask = list(mask)
1439        i = 0
1440        segments = []
1441        while mask[i:].count(1):
1442            i += mask[i:].index(1)
1443            if mask[i:].count(0):
1444                j = i + mask[i:].index(0)
1445            else:
1446                j = len(mask)
1447            segments.append([i,j])
1448            i = j
1449        return segments
1450
1451    def _get_ordinate_label(self):
1452        fu = "("+self.get_fluxunit()+")"
1453        import re
1454        lbl = "Intensity"
1455        if re.match(".K.",fu):
1456            lbl = "Brightness Temperature "+ fu
1457        elif re.match(".Jy.",fu):
1458            lbl = "Flux density "+ fu
1459        return lbl
1460
1461    def _check_ifs(self):
1462        nchans = [self.nchan(i) for i in range(self.nif(-1))]
1463        nchans = filter(lambda t: t > 0, nchans)
1464        return (sum(nchans)/len(nchans) == nchans[0])
1465
1466    def _fill(self, names, unit, average):
1467        import os
1468        varlist = vars()
1469        from asap._asap import stfiller
1470        first = True
1471        fullnames = []
1472        for name in names:
1473            name = os.path.expandvars(name)
1474            name = os.path.expanduser(name)
1475            if not os.path.exists(name):
1476                msg = "File '%s' does not exists" % (name)
1477                if rcParams['verbose']:
1478                    asaplog.push(msg)
1479                    print asaplog.pop().strip()
1480                    return
1481                raise IOError(msg)
1482            fullnames.append(name)
1483        if average:
1484            asaplog.push('Auto averaging integrations')
1485        for name in fullnames:
1486            r = stfiller()
1487            msg = "Importing %s..." % (name)
1488            asaplog.push(msg,False)
1489            print_log()
1490            r._open(name,-1,-1)
1491            r._read()
1492            tbl = r._getdata()
1493            if average:
1494                tbl = self._math._average((tbl,),(),'NONE','SCAN')
1495                #tbl = tbl2
1496            if not first:
1497                tbl = self._math._merge([self, tbl])
1498                #tbl = tbl2
1499            Scantable.__init__(self, tbl)
1500            r._close()
1501            del r,tbl
1502            first = False
1503        if unit is not None:
1504            self.set_fluxunit(unit)
1505        self.set_freqframe(rcParams['scantable.freqframe'])
1506        #self._add_history("scantable", varlist)
1507
Note: See TracBrowser for help on using the repository browser.