source: branches/Release2.0/python/scantable.py

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

Fix for Ticket #33; was confusing mask and flag again. == flag svn diff ../python/scantable.py!

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