source: tags/asap2beta/python/scantable.py

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

Fix to Ticket #17 - average_pol not working.

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