source: trunk/python/scantable.py @ 1003

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

added column_names()

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 55.6 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
351    def column_names(self):
352        """
353        Return a  list of column names, which can be used for selection.
354        """
355        return list(Scantable.column_names(self))
356
357    def get_tsys(self):
358        """
359        Return the System temperatures.
360        Parameters:
361
362        Returns:
363            a list of Tsys values for the current selection
364        """
365
366        return self._row_callback(self._gettsys, "Tsys")
367
368    def _row_callback(self, callback, label):
369        axes = []
370        axesnames = ['scanno','beamno','ifno','polno','cycleno']
371        out = ""
372        outvec =[]
373        for i in range(self.nrow()):
374            axis = []
375            axis.append(self.getscan(i))
376            axis.append(self.getbeam(i))
377            axis.append(self.getif(i))
378            axis.append(self.getpol(i))
379            axis.append(self.getcycle(i))
380            axes.append(axis)
381            tm = self._gettime(i)
382            src = self._getsourcename(i)
383            out += 'Scan[%d] (%s) ' % (axis[0], src)
384            out += 'Time[%s]:\n' % (tm)
385            if self.nbeam(-1) > 1: out +=  ' Beam[%d] ' % (axis[1])
386            if self.nif(-1) > 1: out +=  ' IF[%d] ' % (axis[2])
387            if self.npol(-1) > 1: out +=  ' Pol[%d] ' % (axis[3])
388            outvec.append(callback(i))
389            out += '= %3.3f\n' % (outvec[i])
390            out +=  "--------------------------------------------------\n"
391        if rcParams['verbose']:
392            print "--------------------------------------------------"
393            print " %s" % (label)
394            print "--------------------------------------------------"
395            print out
396        retval = {'axesnames': axesnames, 'axes': axes, 'data': outvec}
397        return retval
398
399
400    def get_time(self, row=-1):
401        """
402        Get a list of time stamps for the observations.
403        Return a string for each integration in the scantable.
404        Parameters:
405            row:    row no of integration. Default -1 return all rows
406        Example:
407            none
408        """
409        out = []
410        if row == -1:
411            for i in range(self.nrow()):
412                out.append(self._gettime(i))
413            return out
414        else:
415            if row < self.nrow():
416                return self._gettime(row)
417
418    def get_sourcename(self, row=-1):
419        """
420        Get a list source names for the observations.
421        Return a string for each integration in the scantable.
422        Parameters:
423            row:    row no of integration. Default -1 return all rows
424        Example:
425            none
426        """
427        out = []
428        if row == -1:
429            return [self._getsourcename(i) for i in range(self.nrow())]
430        else:
431            if  0 <= row < self.nrow():
432                return self._getsourcename(row)
433
434    def get_elevation(self, row=-1):
435        """
436        Get a list of elevations for the observations.
437        Return a float for each integration in the scantable.
438        Parameters:
439            row:    row no of integration. Default -1 return all rows
440        Example:
441            none
442        """
443        out = []
444        if row == -1:
445            return [self._getelevation(i) for i in range(self.nrow())]
446        else:
447            if  0 <= row < self.nrow():
448                return self._getelevation(row)
449
450    def get_azimuth(self, row=-1):
451        """
452        Get a list of azimuths for the observations.
453        Return a float for each integration in the scantable.
454        Parameters:
455            row:    row no of integration. Default -1 return all rows
456        Example:
457            none
458        """
459        out = []
460        if row == -1:
461            return [self._getazimuth(i) for i in range(self.nrow())]
462        else:
463            if  0 <= row < self.nrow():
464                return self._getazimuth(row)
465
466    def get_parangle(self, row=-1):
467        """
468        Get a list of parallactic angles for the observations.
469        Return a float for each integration in the scantable.
470        Parameters:
471            row:    row no of integration. Default -1 return all rows
472        Example:
473            none
474        """
475        out = []
476        if row == -1:
477            return [self._getparangle(i) for i in range(self.nrow())]
478        else:
479            if  0 <= row < self.nrow():
480                return self._getparangle(row)
481
482    def set_unit(self, unit='channel'):
483        """
484        Set the unit for all following operations on this scantable
485        Parameters:
486            unit:    optional unit, default is 'channel'
487                     one of '*Hz','km/s','channel', ''
488        """
489        varlist = vars()
490        if unit in ['','pixel', 'channel']:
491            unit = ''
492        inf = list(self._getcoordinfo())
493        inf[0] = unit
494        self._setcoordinfo(inf)
495        self._add_history("set_unit",varlist)
496
497    def set_instrument(self, instr):
498        """
499        Set the instrument for subsequent processing
500        Parameters:
501            instr:    Select from 'ATPKSMB', 'ATPKSHOH', 'ATMOPRA',
502                      'DSS-43' (Tid), 'CEDUNA', and 'HOBART'
503        """
504        self._setInstrument(instr)
505        self._add_history("set_instument",vars())
506        print_log()
507
508    def set_doppler(self, doppler='RADIO'):
509        """
510        Set the doppler for all following operations on this scantable.
511        Parameters:
512            doppler:    One of 'RADIO', 'OPTICAL', 'Z', 'BETA', 'GAMMA'
513        """
514        varlist = vars()
515        inf = list(self._getcoordinfo())
516        inf[2] = doppler
517        self._setcoordinfo(inf)
518        self._add_history("set_doppler",vars())
519        print_log()
520
521    def set_freqframe(self, frame=None):
522        """
523        Set the frame type of the Spectral Axis.
524        Parameters:
525            frame:   an optional frame type, default 'LSRK'. Valid frames are:
526                     'REST','TOPO','LSRD','LSRK','BARY',
527                     'GEO','GALACTO','LGROUP','CMB'
528        Examples:
529            scan.set_freqframe('BARY')
530        """
531        if frame is None: frame = rcParams['scantable.freqframe']
532        varlist = vars()
533        valid = ['REST','TOPO','LSRD','LSRK','BARY', \
534                   'GEO','GALACTO','LGROUP','CMB']
535
536        if frame in valid:
537            inf = list(self._getcoordinfo())
538            inf[1] = frame
539            self._setcoordinfo(inf)
540            self._add_history("set_freqframe",varlist)
541        else:
542            msg  = "Please specify a valid freq type. Valid types are:\n",valid
543            if rcParams['verbose']:
544                print msg
545            else:
546                raise TypeError(msg)
547        print_log()
548
549    def set_dirframe(self, frame=""):
550        """
551        Set the frame type of the Direction on the sky.
552        Parameters:
553            frame:   an optional frame type, default ''. Valid frames are:
554                     'J2000', 'B1950', 'GALACTIC'
555        Examples:
556            scan.set_dirframe('GALACTIC')
557        """
558        varlist = vars()
559        try:
560            Scantable.set_dirframe(self, frame)
561        except RuntimeError,msg:
562            if rcParams['verbose']:
563                print msg
564            else:
565                raise
566        self._add_history("set_dirframe",varlist)
567
568    def get_unit(self):
569        """
570        Get the default unit set in this scantable
571        Parameters:
572        Returns:
573            A unit string
574        """
575        inf = self._getcoordinfo()
576        unit = inf[0]
577        if unit == '': unit = 'channel'
578        return unit
579
580    def get_abcissa(self, rowno=0):
581        """
582        Get the abcissa in the current coordinate setup for the currently
583        selected Beam/IF/Pol
584        Parameters:
585            rowno:    an optional row number in the scantable. Default is the
586                      first row, i.e. rowno=0
587        Returns:
588            The abcissa values and it's format string (as a dictionary)
589        """
590        abc = self._getabcissa(rowno)
591        lbl = self._getabcissalabel(rowno)
592        print_log()
593        return abc, lbl
594
595    def flag(self, mask=[]):
596        """
597        Flag the selected data using an optional channel mask.
598        Parameters:
599            mask:   an optional channel mask, created with create_mask. Default
600                    (no mask) is all channels.
601        """
602        varlist = vars()
603        try:
604            self._flag(mask)
605        except RuntimeError,msg:
606            if rcParams['verbose']:
607                print msg
608                return
609            else: raise
610        self._add_history("flag", varlist)
611
612
613    def create_mask(self, *args, **kwargs):
614        """
615        Compute and return a mask based on [min,max] windows.
616        The specified windows are to be INCLUDED, when the mask is
617        applied.
618        Parameters:
619            [min,max],[min2,max2],...
620                Pairs of start/end points specifying the regions
621                to be masked
622            invert:     optional argument. If specified as True,
623                        return an inverted mask, i.e. the regions
624                        specified are EXCLUDED
625            row:        create the mask using the specified row for
626                        unit conversions, default is row=0
627                        only necessary if frequency varies over rows.
628        Example:
629            scan.set_unit('channel')
630
631            a)
632            msk = scan.set_mask([400,500],[800,900])
633            # masks everything outside 400 and 500
634            # and 800 and 900 in the unit 'channel'
635
636            b)
637            msk = scan.set_mask([400,500],[800,900], invert=True)
638            # masks the regions between 400 and 500
639            # and 800 and 900 in the unit 'channel'
640
641        """
642        row = 0
643        if kwargs.has_key("row"):
644            row = kwargs.get("row")
645        data = self._getabcissa(row)
646        u = self._getcoordinfo()[0]
647        if rcParams['verbose']:
648            if u == "": u = "channel"
649            from asap import asaplog
650            msg = "The current mask window unit is %s" % u
651            if not self._check_ifs():
652                msg += "\nThis mask is only valid for IF=%d" % (self.getif(i))
653            asaplog.push(msg)
654        n = self.nchan()
655        msk = zeros(n)
656        # test if args is a 'list' or a 'normal *args - UGLY!!!
657
658        ws = (isinstance(args[-1][-1],int) or isinstance(args[-1][-1],float)) and args or args[0]
659        for window in ws:
660            if (len(window) != 2 or window[0] > window[1] ):
661                raise TypeError("A window needs to be defined as [min,max]")
662            for i in range(n):
663                if data[i] >= window[0] and data[i] < window[1]:
664                    msk[i] = 1
665        if kwargs.has_key('invert'):
666            if kwargs.get('invert'):
667                from numarray import logical_not
668                msk = logical_not(msk)
669        print_log()
670        return msk
671
672    def get_restfreqs(self):
673        """
674        Get the restfrequency(s) stored in this scantable.
675        The return value(s) are always of unit 'Hz'
676        Parameters:
677            none
678        Returns:
679            a list of doubles
680        """
681        return list(self._getrestfreqs())
682
683
684    def set_restfreqs(self, freqs=None, unit='Hz'):
685        """
686        Set or replace the restfrequency specified and
687        If the 'freqs' argument holds a scalar,
688        then that rest frequency will be applied to all the selected
689        data.  If the 'freqs' argument holds
690        a vector, then it MUST be of equal or smaller length than
691        the number of IFs (and the available restfrequencies will be
692        replaced by this vector).  In this case, *all* data have
693        the restfrequency set per IF according
694        to the corresponding value you give in the 'freqs' vector.
695        E.g. 'freqs=[1e9,2e9]'  would mean IF 0 gets restfreq 1e9 and
696        IF 1 gets restfreq 2e9.
697        You can also specify the frequencies via known line names
698        from the built-in Lovas table.
699        Parameters:
700            freqs:   list of rest frequency values or string idenitfiers
701            unit:    unit for rest frequency (default 'Hz')
702
703        Example:
704            # set the given restfrequency for the whole table
705            scan.set_restfreqs(freqs=1.4e9)
706            # If thee number of IFs in the data is >= 2 the IF0 gets the first
707            # value IF1 the second...
708            scan.set_restfreqs(freqs=[1.4e9,1.67e9])
709            #set the given restfrequency for the whole table (by name)
710            scan.set_restfreqs(freqs="OH1667")
711
712        Note:
713            To do more sophisticate Restfrequency setting, e.g. on a
714            source and IF basis, use scantable.set_selection() before using
715            this function.
716            # provide your scantable is call scan
717            selection = selector()
718            selection.set_name("ORION*")
719            selection.set_ifs([1])
720            scan.set_selection(selection)
721            scan.set_restfreqs(freqs=86.6e9)
722
723        """
724        varlist = vars()
725
726        t = type(freqs)
727        if isinstance(freqs, int) or isinstance(freqs,float):
728           self._setrestfreqs(freqs, unit)
729        elif isinstance(freqs, list) or isinstance(freqs,tuple):
730            if isinstance(freqs[-1], int) or isinstance(freqs[-1],float):
731                sel = selector()
732                savesel = self._getselection()
733                for i in xrange(len(freqs)):
734                    sel.set_ifs([i])
735                    self._setselection(sel)
736                    self._setrestfreqs(freqs[i], unit)
737                self._setselection(savesel)
738            elif isinstance(freqs[-1], str):
739                # not yet implemented
740                pass
741        else:
742            return
743        self._add_history("set_restfreqs", varlist)
744
745
746
747    def history(self):
748        hist = list(self._gethistory())
749        out = "-"*80
750        for h in hist:
751            if h.startswith("---"):
752                out += "\n"+h
753            else:
754                items = h.split("##")
755                date = items[0]
756                func = items[1]
757                items = items[2:]
758                out += "\n"+date+"\n"
759                out += "Function: %s\n  Parameters:" % (func)
760                for i in items:
761                    s = i.split("=")
762                    out += "\n   %s = %s" % (s[0],s[1])
763                out += "\n"+"-"*80
764        try:
765            from IPython.genutils import page as pager
766        except ImportError:
767            from pydoc import pager
768        pager(out)
769        return
770
771    #
772    # Maths business
773    #
774
775    def average_time(self, mask=None, scanav=False, weight='tint', align=False):
776        """
777        Return the (time) average of a scan, or apply it 'insitu'.
778        Note:
779            in channels only
780            The cursor of the output scan is set to 0.
781        Parameters:
782            one scan or comma separated  scans
783            mask:     an optional mask (only used for 'var' and 'tsys'
784                      weighting)
785            scanav:   True averages each scan separately
786                      False (default) averages all scans together,
787            weight:   Weighting scheme. 'none', 'var' (1/var(spec)
788                      weighted), 'tsys' (1/Tsys**2 weighted), 'tint'
789                      (integration time weighted) or 'tintsys' (Tint/Tsys**2).
790                      The default is 'tint'
791            align:    align the spectra in velocity before averaging. It takes
792                      the time of the first spectrum as reference time.
793        Example:
794            # time average the scantable without using a mask
795            newscan = scan.average_time()
796        """
797        varlist = vars()
798        if weight is None: weight = 'TINT'
799        if mask is None: mask = ()
800        if scanav:
801            scanav = "SCAN"
802        else:
803            scanav = "NONE"
804        scan = (self,)
805        try:
806          if align:
807              scan = (self.freq_align(insitu=False),)
808          s = scantable(self._math._average(scan, mask, weight.upper(),
809                        scanav))
810        except RuntimeError,msg:
811            if rcParams['verbose']:
812                print msg
813                return
814            else: raise
815        s._add_history("average_time",varlist)
816        print_log()
817        return s
818
819    def convert_flux(self, jyperk=None, eta=None, d=None, insitu=None):
820        """
821        Return a scan where all spectra are converted to either
822        Jansky or Kelvin depending upon the flux units of the scan table.
823        By default the function tries to look the values up internally.
824        If it can't find them (or if you want to over-ride), you must
825        specify EITHER jyperk OR eta (and D which it will try to look up
826        also if you don't set it). jyperk takes precedence if you set both.
827        Parameters:
828            jyperk:      the Jy / K conversion factor
829            eta:         the aperture efficiency
830            d:           the geomtric diameter (metres)
831            insitu:      if False a new scantable is returned.
832                         Otherwise, the scaling is done in-situ
833                         The default is taken from .asaprc (False)
834            allaxes:         if True apply to all spectra. Otherwise
835                         apply only to the selected (beam/pol/if)spectra only
836                         The default is taken from .asaprc (True if none)
837        """
838        if insitu is None: insitu = rcParams['insitu']
839        self._math._setinsitu(insitu)
840        varlist = vars()
841        if jyperk is None: jyperk = -1.0
842        if d is None: d = -1.0
843        if eta is None: eta = -1.0
844        s = scantable(self._math._convertflux(self, d, eta, jyperk))
845        s._add_history("convert_flux", varlist)
846        print_log()
847        if insitu: self._assign(s)
848        else: return s
849
850    def gain_el(self, poly=None, filename="", method="linear", insitu=None):
851        """
852        Return a scan after applying a gain-elevation correction.
853        The correction can be made via either a polynomial or a
854        table-based interpolation (and extrapolation if necessary).
855        You specify polynomial coefficients, an ascii table or neither.
856        If you specify neither, then a polynomial correction will be made
857        with built in coefficients known for certain telescopes (an error
858        will occur if the instrument is not known).
859        The data and Tsys are *divided* by the scaling factors.
860        Parameters:
861            poly:        Polynomial coefficients (default None) to compute a
862                         gain-elevation correction as a function of
863                         elevation (in degrees).
864            filename:    The name of an ascii file holding correction factors.
865                         The first row of the ascii file must give the column
866                         names and these MUST include columns
867                         "ELEVATION" (degrees) and "FACTOR" (multiply data
868                         by this) somewhere.
869                         The second row must give the data type of the
870                         column. Use 'R' for Real and 'I' for Integer.
871                         An example file would be
872                         (actual factors are arbitrary) :
873
874                         TIME ELEVATION FACTOR
875                         R R R
876                         0.1 0 0.8
877                         0.2 20 0.85
878                         0.3 40 0.9
879                         0.4 60 0.85
880                         0.5 80 0.8
881                         0.6 90 0.75
882            method:      Interpolation method when correcting from a table.
883                         Values are  "nearest", "linear" (default), "cubic"
884                         and "spline"
885            insitu:      if False a new scantable is returned.
886                         Otherwise, the scaling is done in-situ
887                         The default is taken from .asaprc (False)
888        """
889
890        if insitu is None: insitu = rcParams['insitu']
891        self._math._setinsitu(insitu)
892        varlist = vars()
893        if poly is None:
894           poly = ()
895        from os.path import expandvars
896        filename = expandvars(filename)
897        s = scantable(self._math._gainel(self, poly, filename, method))
898        s._add_history("gain_el", varlist)
899        print_log()
900        if insitu: self._assign(s)
901        else: return s
902
903    def freq_align(self, reftime=None, method='cubic', insitu=None):
904        """
905        Return a scan where all rows have been aligned in frequency/velocity.
906        The alignment frequency frame (e.g. LSRK) is that set by function
907        set_freqframe.
908        Parameters:
909            reftime:     reference time to align at. By default, the time of
910                         the first row of data is used.
911            method:      Interpolation method for regridding the spectra.
912                         Choose from "nearest", "linear", "cubic" (default)
913                         and "spline"
914            insitu:      if False a new scantable is returned.
915                         Otherwise, the scaling is done in-situ
916                         The default is taken from .asaprc (False)
917        """
918        if insitu is None: insitu = rcParams["insitu"]
919        self._math._setinsitu(insitu)
920        varlist = vars()
921        if reftime is None: reftime = ""
922        s = scantable(self._math._freq_align(self, reftime, method))
923        s._add_history("freq_align", varlist)
924        print_log()
925        if insitu: self._assign(s)
926        else: return s
927
928    def opacity(self, tau, insitu=None):
929        """
930        Apply an opacity correction. The data
931        and Tsys are multiplied by the correction factor.
932        Parameters:
933            tau:         Opacity from which the correction factor is
934                         exp(tau*ZD)
935                         where ZD is the zenith-distance
936            insitu:      if False a new scantable is returned.
937                         Otherwise, the scaling is done in-situ
938                         The default is taken from .asaprc (False)
939        """
940        if insitu is None: insitu = rcParams['insitu']
941        self._math._setinsitu(insitu)
942        varlist = vars()
943        s = scantable(self._math._opacity(self, tau))
944        s._add_history("opacity", varlist)
945        print_log()
946        if insitu: self._assign(s)
947        else: return s
948
949    def bin(self, width=5, insitu=None):
950        """
951        Return a scan where all spectra have been binned up.
952            width:       The bin width (default=5) in pixels
953            insitu:      if False a new scantable is returned.
954                         Otherwise, the scaling is done in-situ
955                         The default is taken from .asaprc (False)
956        """
957        if insitu is None: insitu = rcParams['insitu']
958        self._math._setinsitu(insitu)
959        varlist = vars()
960        s = scantable(self._math._bin(self, width))
961        s._add_history("bin",varlist)
962        print_log()
963        if insitu: self._assign(s)
964        else: return s
965
966
967    def resample(self, width=5, method='cubic', insitu=None):
968        """
969        Return a scan where all spectra have been binned up
970            width:       The bin width (default=5) in pixels
971            method:      Interpolation method when correcting from a table.
972                         Values are  "nearest", "linear", "cubic" (default)
973                         and "spline"
974            insitu:      if False a new scantable is returned.
975                         Otherwise, the scaling is done in-situ
976                         The default is taken from .asaprc (False)
977        """
978        if insitu is None: insitu = rcParams['insitu']
979        self._math._setinsitu(insitu)
980        varlist = vars()
981        s = scantable(self._math._resample(self, method, width))
982        s._add_history("resample",varlist)
983        print_log()
984        if insitu: self._assign(s)
985        else: return s
986
987
988    def average_pol(self, mask=None, weight='none'):
989        """
990        Average the Polarisations together.
991        Parameters:
992            mask:        An optional mask defining the region, where the
993                         averaging will be applied. The output will have all
994                         specified points masked.
995            weight:      Weighting scheme. 'none' (default), 'var' (1/var(spec)
996                         weighted), or 'tsys' (1/Tsys**2 weighted)
997        """
998        varlist = vars()
999        if mask is None:
1000            mask = ()
1001        s = scantable(self._math._averagepol(self, mask, weight))
1002        s._add_history("average_pol",varlist)
1003        print_log()
1004        return s
1005
1006    def convert_pol(self, poltype=None):
1007        """
1008        Convert the data to a different polarisation type.
1009        Parameters:
1010            poltype:    The new polarisation type. Valid types are:
1011                        "linear", "stokes" and "circular"
1012        """
1013        varlist = vars()
1014        try:
1015            s = scantable(self._math._convertpol(self, poltype))
1016        except RuntimeError,msg:
1017            if rcParams['verbose']:
1018              print msg
1019              return
1020            else:
1021                raise
1022        s._add_history("convert_pol",varlist)
1023        print_log()
1024        return s
1025
1026    def smooth(self, kernel="hanning", width=5.0, insitu=None):
1027        """
1028        Smooth the spectrum by the specified kernel (conserving flux).
1029        Parameters:
1030            scan:       The input scan
1031            kernel:     The type of smoothing kernel. Select from
1032                        'hanning' (default), 'gaussian' and 'boxcar'.
1033                        The first three characters are sufficient.
1034            width:      The width of the kernel in pixels. For hanning this is
1035                        ignored otherwise it defauls to 5 pixels.
1036                        For 'gaussian' it is the Full Width Half
1037                        Maximum. For 'boxcar' it is the full width.
1038            insitu:     if False a new scantable is returned.
1039                        Otherwise, the scaling is done in-situ
1040                        The default is taken from .asaprc (False)
1041        Example:
1042             none
1043        """
1044        if insitu is None: insitu = rcParams['insitu']
1045        self._math._setinsitu(insitu)
1046        varlist = vars()
1047        s = scantable(self._math._smooth(self,kernel,width))
1048        s._add_history("smooth", varlist)
1049        print_log()
1050        if insitu: self._assign(s)
1051        else: return s
1052
1053
1054    def poly_baseline(self, mask=None, order=0, insitu=None):
1055        """
1056        Return a scan which has been baselined (all rows) by a polynomial.
1057        Parameters:
1058            scan:       a scantable
1059            mask:       an optional mask
1060            order:      the order of the polynomial (default is 0)
1061            insitu:     if False a new scantable is returned.
1062                        Otherwise, the scaling is done in-situ
1063                        The default is taken from .asaprc (False)
1064            allaxes:    If True (default) apply to all spectra. Otherwise
1065                        apply only to the selected (beam/pol/if)spectra only
1066                        The default is taken from .asaprc (True if none)
1067        Example:
1068            # return a scan baselined by a third order polynomial,
1069            # not using a mask
1070            bscan = scan.poly_baseline(order=3)
1071        """
1072        if insitu is None: insitu = rcParams['insitu']
1073        varlist = vars()
1074        if mask is None:
1075            from numarray import ones
1076            mask = list(ones(self.nchan(-1)))
1077        from asap.asapfitter import fitter
1078        f = fitter()
1079        f.set_scan(self, mask)
1080        f.set_function(poly=order)
1081        s = f.auto_fit(insitu)
1082        s._add_history("poly_baseline", varlist)
1083        print_log()
1084        if insitu: self._assign(s)
1085        else: return s
1086
1087    def auto_poly_baseline(self, mask=[], edge=(0,0), order=0,
1088                           threshold=3, insitu=None):
1089        """
1090        Return a scan which has been baselined (all rows) by a polynomial.
1091        Spectral lines are detected first using linefinder and masked out
1092        to avoid them affecting the baseline solution.
1093
1094        Parameters:
1095            mask:       an optional mask retreived from scantable
1096            edge:       an optional number of channel to drop at
1097                        the edge of spectrum. If only one value is
1098                        specified, the same number will be dropped from
1099                        both sides of the spectrum. Default is to keep
1100                        all channels. Nested tuples represent individual
1101                        edge selection for different IFs (a number of spectral
1102                        channels can be different)
1103            order:      the order of the polynomial (default is 0)
1104            threshold:  the threshold used by line finder. It is better to
1105                        keep it large as only strong lines affect the
1106                        baseline solution.
1107            insitu:     if False a new scantable is returned.
1108                        Otherwise, the scaling is done in-situ
1109                        The default is taken from .asaprc (False)
1110
1111        Example:
1112            scan2=scan.auto_poly_baseline(order=7)
1113        """
1114        if insitu is None: insitu = rcParams['insitu']
1115        varlist = vars()
1116        from asap.asapfitter import fitter
1117        from asap.asaplinefind import linefinder
1118        from asap import _is_sequence_or_number as _is_valid
1119
1120        # check whether edge is set up for each IF individually
1121        individualEdge = False;
1122        if len(edge)>1:
1123           if isinstance(edge[0],list) or isinstance(edge[0],tuple):
1124               individualEdge = True;
1125
1126        if not _is_valid(edge, int) and not individualEdge:
1127            raise ValueError, "Parameter 'edge' has to be an integer or a \
1128            pair of integers specified as a tuple. Nested tuples are allowed \
1129            to make individual selection for different IFs."
1130
1131        curedge = (0,0)
1132        if individualEdge:
1133           for edge_par in edge:
1134               if not _is_valid(edge,int):
1135                  raise ValueError, "Each element of the 'edge' tuple has \
1136                  to be a pair of integers or an integer."
1137        else:
1138           curedge = edge;
1139
1140        # setup fitter
1141        f = fitter()
1142        f.set_function(poly=order)
1143
1144        # setup line finder
1145        fl=linefinder()
1146        fl.set_options(threshold=threshold)
1147
1148        if not insitu:
1149            workscan=self.copy()
1150        else:
1151            workscan=self
1152
1153        fl.set_scan(workscan)
1154
1155        rows=range(workscan.nrow())
1156        from asap import asaplog
1157        asaplog.push("Processing:")
1158        for r in rows:
1159            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))
1160            asaplog.push(msg, False)
1161
1162            # figure out edge parameter
1163            if individualEdge:
1164               if len(edge)>=workscan.getif(r):
1165                  raise RuntimeError, "Number of edge elements appear to be less than the number of IFs"
1166                  curedge = edge[workscan.getif(r)]
1167
1168            # setup line finder
1169            fl.find_lines(r,mask,curedge)
1170            f.set_scan(workscan, fl.get_mask())
1171            f.x = workscan._getabcissa(r)
1172            f.y = workscan._getspectrum(r)
1173            f.data = None
1174            f.fit()
1175            x = f.get_parameters()
1176            workscan._setspectrum(f.fitter.getresidual(), r)
1177        workscan._add_history("poly_baseline", varlist)
1178        if insitu:
1179            self._assign(workscan)
1180        else:
1181            return workscan
1182
1183    def rotate_linpolphase(self, angle):
1184        """
1185        Rotate the phase of the complex polarization O=Q+iU correlation.
1186        This is always done in situ in the raw data.  So if you call this
1187        function more than once then each call rotates the phase further.
1188        Parameters:
1189            angle:   The angle (degrees) to rotate (add) by.
1190        Examples:
1191            scan.rotate_linpolphase(2.3)
1192        """
1193        varlist = vars()
1194        self._math._rotate_linpolphase(self, angle)
1195        self._add_history("rotate_linpolphase", varlist)
1196        print_log()
1197        return
1198
1199
1200    def rotate_xyphase(self, angle):
1201        """
1202        Rotate the phase of the XY correlation.  This is always done in situ
1203        in the data.  So if you call this function more than once
1204        then each call rotates the phase further.
1205        Parameters:
1206            angle:   The angle (degrees) to rotate (add) by.
1207        Examples:
1208            scan.rotate_xyphase(2.3)
1209        """
1210        varlist = vars()
1211        self._math._rotate_xyphase(self, angle)
1212        self._add_history("rotate_xyphase", varlist)
1213        print_log()
1214        return
1215
1216    def swap_linears(self):
1217        """
1218        Swap the linear polarisations XX and YY
1219        """
1220        varlist = vars()
1221        self._math._swap_linears(self)
1222        self._add_history("swap_linears", varlist)
1223        print_log()
1224        return
1225
1226    def invert_phase(self):
1227        """
1228        Invert the phase of the complex polarisation
1229        """
1230        varlist = vars()
1231        self._math._invert_phase(self)
1232        self._add_history("invert_phase", varlist)
1233        print_log()
1234        return
1235
1236    def add(self, offset, insitu=None):
1237        """
1238        Return a scan where all spectra have the offset added
1239        Parameters:
1240            offset:      the offset
1241            insitu:      if False a new scantable is returned.
1242                         Otherwise, the scaling is done in-situ
1243                         The default is taken from .asaprc (False)
1244        """
1245        if insitu is None: insitu = rcParams['insitu']
1246        self._math._setinsitu(insitu)
1247        varlist = vars()
1248        s = scantable(self._math._unaryop(self, offset, "ADD", False))
1249        s._add_history("add",varlist)
1250        print_log()
1251        if insitu:
1252            self._assign(s)
1253        else:
1254            return s
1255
1256    def scale(self, factor, tsys=True, insitu=None,):
1257        """
1258        Return a scan where all spectra are scaled by the give 'factor'
1259        Parameters:
1260            factor:      the scaling factor
1261            insitu:      if False a new scantable is returned.
1262                         Otherwise, the scaling is done in-situ
1263                         The default is taken from .asaprc (False)
1264            tsys:        if True (default) then apply the operation to Tsys
1265                         as well as the data
1266        """
1267        if insitu is None: insitu = rcParams['insitu']
1268        self._math._setinsitu(insitu)
1269        varlist = vars()
1270        s = scantable(self._math._unaryop(self, factor, "MUL", tsys))
1271        s._add_history("scale",varlist)
1272        print_log()
1273        if insitu:
1274            self._assign(s)
1275        else:
1276            return s
1277
1278    def auto_quotient(self, mode='time', preserve=True):
1279        """
1280        This function allows to build quotients automatically.
1281        It assumes the observation to have the same numer of
1282        "ons" and "offs"
1283        It will support "closest off in time" in the future
1284        Parameters:
1285            mode:           the on/off detection mode; 'suffix' (default)
1286                            'suffix' identifies 'off' scans by the
1287                            trailing '_R' (Mopra/Parkes) or
1288                            '_e'/'_w' (Tid)
1289            preserve:       you can preserve (default) the continuum or
1290                            remove it.  The equations used are
1291                            preserve: Output = Toff * (on/off) - Toff
1292                            remove:   Output = Tref * (on/off) - Ton
1293        """
1294        modes = ["time"]
1295        if not mode in modes:
1296            msg = "please provide valid mode. Valid modes are %s" % (modes)
1297            raise ValueError(msg)
1298        varlist = vars()
1299        s = scantable(self._math._quotient(self, mode, preserve))
1300        s._add_history("auto_quotient",varlist)
1301        print_log()
1302        return s
1303
1304
1305
1306
1307    def freq_switch(self, insitu=None):
1308        """
1309        Apply frequency switching to the data.
1310        Parameters:
1311            insitu:      if False a new scantable is returned.
1312                         Otherwise, the swictching is done in-situ
1313                         The default is taken from .asaprc (False)
1314        Example:
1315            none
1316        """
1317        if insitu is None: insitu = rcParams['insitu']
1318        self._math._setinsitu(insitu)
1319        varlist = vars()
1320        s = scantable(self._math._freqswitch(self))
1321        s._add_history("freq_switch",varlist)
1322        print_log()
1323        if insitu: self._assign(s)
1324        else: return s
1325
1326    def recalc_azel(self):
1327        """
1328        Recalculate the azimuth and elevation for each position.
1329        Parameters:
1330            none
1331        Example:
1332        """
1333        varlist = vars()
1334        self._recalcazel()
1335        self._add_history("recalc_azel", varlist)
1336        print_log()
1337        return
1338
1339    def __add__(self, other):
1340        varlist = vars()
1341        s = None
1342        if isinstance(other, scantable):
1343            print "scantable + scantable NYI"
1344            return
1345        elif isinstance(other, float):
1346            s = scantable(self._math._unaryop(self, other, "ADD", False))
1347        else:
1348            raise TypeError("Other input is not a scantable or float value")
1349        s._add_history("operator +", varlist)
1350        print_log()
1351        return s
1352
1353    def __sub__(self, other):
1354        """
1355        implicit on all axes and on Tsys
1356        """
1357        varlist = vars()
1358        s = None
1359        if isinstance(other, scantable):
1360            print "scantable - scantable NYI"
1361            return
1362        elif isinstance(other, float):
1363            s = scantable(self._math._unaryop(self, other, "SUB", False))
1364        else:
1365            raise TypeError("Other input is not a scantable or float value")
1366        s._add_history("operator -", varlist)
1367        print_log()
1368        return s
1369
1370    def __mul__(self, other):
1371        """
1372        implicit on all axes and on Tsys
1373        """
1374        varlist = vars()
1375        s = None
1376        if isinstance(other, scantable):
1377            print "scantable * scantable NYI"
1378            return
1379        elif isinstance(other, float):
1380            s = scantable(self._math._unaryop(self, other, "MUL", False))
1381        else:
1382            raise TypeError("Other input is not a scantable or float value")
1383        s._add_history("operator *", varlist)
1384        print_log()
1385        return s
1386
1387
1388    def __div__(self, other):
1389        """
1390        implicit on all axes and on Tsys
1391        """
1392        varlist = vars()
1393        s = None
1394        if isinstance(other, scantable):
1395            print "scantable / scantable NYI"
1396            return
1397        elif isinstance(other, float):
1398            if other == 0.0:
1399                raise ZeroDivisionError("Dividing by zero is not recommended")
1400            s = scantable(self._math._unaryop(self, other, "DIV", False))
1401        else:
1402            raise TypeError("Other input is not a scantable or float value")
1403        s._add_history("operator /", varlist)
1404        print_log()
1405        return s
1406
1407    def get_fit(self, row=0):
1408        """
1409        Print or return the stored fits for a row in the scantable
1410        Parameters:
1411            row:    the row which the fit has been applied to.
1412        """
1413        if row > self.nrow():
1414            return
1415        from asap.asapfit import asapfit
1416        fit = asapfit(self._getfit(row))
1417        if rcParams['verbose']:
1418            print fit
1419            return
1420        else:
1421            return fit.as_dict()
1422
1423    def _add_history(self, funcname, parameters):
1424        # create date
1425        sep = "##"
1426        from datetime import datetime
1427        dstr = datetime.now().strftime('%Y/%m/%d %H:%M:%S')
1428        hist = dstr+sep
1429        hist += funcname+sep#cdate+sep
1430        if parameters.has_key('self'): del parameters['self']
1431        for k,v in parameters.iteritems():
1432            if type(v) is dict:
1433                for k2,v2 in v.iteritems():
1434                    hist += k2
1435                    hist += "="
1436                    if isinstance(v2,scantable):
1437                        hist += 'scantable'
1438                    elif k2 == 'mask':
1439                        if isinstance(v2,list) or isinstance(v2,tuple):
1440                            hist += str(self._zip_mask(v2))
1441                        else:
1442                            hist += str(v2)
1443                    else:
1444                        hist += str(v2)
1445            else:
1446                hist += k
1447                hist += "="
1448                if isinstance(v,scantable):
1449                    hist += 'scantable'
1450                elif k == 'mask':
1451                    if isinstance(v,list) or isinstance(v,tuple):
1452                        hist += str(self._zip_mask(v))
1453                    else:
1454                        hist += str(v)
1455                else:
1456                    hist += str(v)
1457            hist += sep
1458        hist = hist[:-2] # remove trailing '##'
1459        self._addhistory(hist)
1460
1461
1462    def _zip_mask(self, mask):
1463        mask = list(mask)
1464        i = 0
1465        segments = []
1466        while mask[i:].count(1):
1467            i += mask[i:].index(1)
1468            if mask[i:].count(0):
1469                j = i + mask[i:].index(0)
1470            else:
1471                j = len(mask)
1472            segments.append([i,j])
1473            i = j
1474        return segments
1475
1476    def _get_ordinate_label(self):
1477        fu = "("+self.get_fluxunit()+")"
1478        import re
1479        lbl = "Intensity"
1480        if re.match(".K.",fu):
1481            lbl = "Brightness Temperature "+ fu
1482        elif re.match(".Jy.",fu):
1483            lbl = "Flux density "+ fu
1484        return lbl
1485
1486    def _check_ifs(self):
1487        nchans = [self.nchan(i) for i in range(self.nif(-1))]
1488        nchans = filter(lambda t: t > 0, nchans)
1489        return (sum(nchans)/len(nchans) == nchans[0])
1490
1491    def _fill(self, names, unit, average):
1492        import os
1493        varlist = vars()
1494        from asap._asap import stfiller
1495        first = True
1496        fullnames = []
1497        for name in names:
1498            name = os.path.expandvars(name)
1499            name = os.path.expanduser(name)
1500            if not os.path.exists(name):
1501                msg = "File '%s' does not exists" % (name)
1502                if rcParams['verbose']:
1503                    asaplog.push(msg)
1504                    print asaplog.pop().strip()
1505                    return
1506                raise IOError(msg)
1507            fullnames.append(name)
1508        if average:
1509            asaplog.push('Auto averaging integrations')
1510        for name in fullnames:
1511            r = stfiller()
1512            msg = "Importing %s..." % (name)
1513            asaplog.push(msg,False)
1514            print_log()
1515            r._open(name,-1,-1)
1516            r._read()
1517            tbl = r._getdata()
1518            if average:
1519                tbl = self._math._average((tbl,),(),'NONE','SCAN')
1520                #tbl = tbl2
1521            if not first:
1522                tbl = self._math._merge([self, tbl])
1523                #tbl = tbl2
1524            Scantable.__init__(self, tbl)
1525            r._close()
1526            del r,tbl
1527            first = False
1528        if unit is not None:
1529            self.set_fluxunit(unit)
1530        self.set_freqframe(rcParams['scantable.freqframe'])
1531        #self._add_history("scantable", varlist)
1532
Note: See TracBrowser for help on using the repository browser.