Ignore:
Timestamp:
06/09/10 19:03:06 (14 years ago)
Author:
Kana Sugimoto
Message:

New Development: Yes

JIRA Issue: Yes (CAS-2211)

Ready for Test: Yes

Interface Changes: Yes

What Interface Changed: ASAP 3.0.0 interface changes

Test Programs:

Put in Release Notes: Yes

Module(s): all the CASA sd tools and tasks are affected.

Description: Merged ATNF-ASAP 3.0.0 developments to CASA (alma) branch.

Note you also need to update casa/code/atnf.


Location:
branches/alma
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/alma

  • branches/alma/python/scantable.py

    r1701 r1757  
     1import os
     2try:
     3    from functools import wraps as wraps_dec
     4except ImportError:
     5    from asap.compatibility import wraps as wraps_dec
     6
    17from asap._asap import Scantable
    28from asap import rcParams
    3 from asap import print_log
     9from asap import print_log, print_log_dec
    410from asap import asaplog
    511from asap import selector
    612from asap import linecatalog
     13from asap.coordinate import coordinate
    714from asap import _n_bools, mask_not, mask_and, mask_or
     15
     16
     17def preserve_selection(func):
     18    @wraps_dec(func)
     19    def wrap(obj, *args, **kw):
     20        basesel = obj.get_selection()
     21        val = func(obj, *args, **kw)
     22        obj.set_selection(basesel)
     23        return val
     24    return wrap
     25
     26
     27def is_scantable(filename):
     28    return (os.path.isdir(filename)
     29            and not os.path.exists(filename+'/table.f1')
     30            and os.path.exists(filename+'/table.info'))
     31
    832
    933class scantable(Scantable):
     
    1236    """
    1337
    14     def __init__(self, filename, average=None, unit=None, getpt=None, antenna=None):
     38    #@print_log_dec
     39    def __init__(self, filename, average=None, unit=None, getpt=None, antenna=None, parallactify=None):
    1540        """
    1641        Create a scantable from a saved one or make a reference
     
    3661            antenna:     Antenna selection. integer (id) or string (name
    3762                         or id).
     63            parallactify: Indcicate that the data had been parallatified.
     64                          Default is taken form rc file.
    3865        """
    3966        if average is None:
     
    5784                    return
    5885            antenna = tmpstr.rstrip(',')
     86        parallactify = parallactify or rcParams['scantable.parallactify']
    5987        varlist = vars()
    6088        from asap._asap import stmath
     
    6391            Scantable.__init__(self, filename)
    6492        else:
    65             if isinstance(filename, str):# or \
    66 #                (isinstance(filename, list) or isinstance(filename, tuple)) \
    67 #                  and isinstance(filename[-1], str):
    68                 import os.path
     93            if isinstance(filename, str):
    6994                filename = os.path.expandvars(filename)
    7095                filename = os.path.expanduser(filename)
     
    7398                    if rcParams['verbose']:
    7499                        asaplog.push(s)
    75                         #print asaplog.pop().strip()
    76100                        print_log('ERROR')
    77101                        return
    78102                    raise IOError(s)
    79                 if os.path.isdir(filename) \
    80                     and not os.path.exists(filename+'/table.f1'):
    81                     # crude check if asap table
    82                     if os.path.exists(filename+'/table.info'):
    83                         ondisk = rcParams['scantable.storage'] == 'disk'
    84                         Scantable.__init__(self, filename, ondisk)
    85                         if unit is not None:
    86                             self.set_fluxunit(unit)
    87                         # do not reset to the default freqframe
    88                         #self.set_freqframe(rcParams['scantable.freqframe'])
     103                if is_scantable(filename):
     104                    ondisk = rcParams['scantable.storage'] == 'disk'
     105                    Scantable.__init__(self, filename, ondisk)
     106                    if unit is not None:
     107                        self.set_fluxunit(unit)
     108                    # do not reset to the default freqframe
     109                    #self.set_freqframe(rcParams['scantable.freqframe'])
     110                elif os.path.isdir(filename) \
     111                         and not os.path.exists(filename+'/table.f1'):
     112                    msg = "The given file '%s'is not a valid " \
     113                          "asap table." % (filename)
     114                    if rcParams['verbose']:
     115                        #print msg
     116                        asaplog.push( msg )
     117                        print_log( 'ERROR' )
     118                        return
    89119                    else:
    90                         msg = "The given file '%s'is not a valid " \
    91                               "asap table." % (filename)
    92                         if rcParams['verbose']:
    93                             #print msg
    94                             asaplog.push( msg )
    95                             print_log( 'ERROR' )
    96                             return
    97                         else:
    98                             raise IOError(msg)
     120                        raise IOError(msg)
    99121                else:
    100122                    self._fill([filename], unit, average, getpt, antenna)
     
    102124                  and isinstance(filename[-1], str):
    103125                self._fill(filename, unit, average, getpt, antenna)
     126        self.parallactify(parallactify)
    104127        self._add_history("scantable", varlist)
    105128        print_log()
    106129
     130    #@print_log_dec
    107131    def save(self, name=None, format=None, overwrite=False):
    108132        """
     
    119143                                       'MS2' (saves as an aips++
    120144                                              MeasurementSet V2)
    121                                        'FITS' (save as image FITS - not 
     145                                       'FITS' (save as image FITS - not
    122146                                               readable by class)
    123147                                       'CLASS' (save as FITS readable by CLASS)
     
    130154        """
    131155        from os import path
    132         if format is None: format = rcParams['scantable.save']
     156        format = format or rcParams['scantable.save']
    133157        suffix = '.'+format.lower()
    134158        if name is None or name == "":
     
    203227            else: raise
    204228        try:
    205             bsel = self.get_selection()
    206             sel = selector()
    207             sel.set_scans(allscans)
    208             self.set_selection(bsel+sel)
    209             scopy = self._copy()
    210             self.set_selection(bsel)
    211             return scantable(scopy)
     229            sel = selector(scans=allscans)
     230            return self._select_copy(sel)
    212231        except RuntimeError:
    213232            if rcParams['verbose']:
     
    219238                raise
    220239
     240    def _select_copy(self, selection):
     241        orig = self.get_selection()
     242        self.set_selection(orig+selection)
     243        cp = self.copy()
     244        self.set_selection(orig)
     245        return cp
    221246
    222247    def get_scan(self, scanid=None):
     
    253278            if type(scanid) is str:
    254279                sel.set_name(scanid)
    255                 self.set_selection(bsel+sel)
    256                 scopy = self._copy()
    257                 self.set_selection(bsel)
    258                 return scantable(scopy)
     280                return self._select_copy(sel)
    259281            elif type(scanid) is int:
    260282                sel.set_scans([scanid])
    261                 self.set_selection(bsel+sel)
    262                 scopy = self._copy()
    263                 self.set_selection(bsel)
    264                 return scantable(scopy)
     283                return self._select_copy(sel)
    265284            elif type(scanid) is list:
    266285                sel.set_scans(scanid)
    267                 self.set_selection(sel)
    268                 scopy = self._copy()
    269                 self.set_selection(bsel)
    270                 return scantable(scopy)
     286                return self._select_copy(sel)
    271287            else:
    272288                msg = "Illegal scanid type, use 'int' or 'list' if ints."
     
    294310            filename:    the name of a file to write the putput to
    295311                         Default - no file output
    296             verbose:     print extra info such as the frequency table
    297                          The default (False) is taken from .asaprc
    298312        """
    299313        info = Scantable._summary(self, True)
    300         #if verbose is None: verbose = rcParams['scantable.verbosesummary']
    301314        if filename is not None:
    302315            if filename is "":
     
    328341        """Return the spectrum for the current row in the scantable as a list.
    329342        Parameters:
    330              rowno:   the row number to retrieve the spectrum from       
     343             rowno:   the row number to retrieve the spectrum from
    331344        """
    332345        return self._getspectrum(rowno)
     
    335348        """Return the mask for the current row in the scantable as a list.
    336349        Parameters:
    337              rowno:   the row number to retrieve the mask from       
     350             rowno:   the row number to retrieve the mask from
    338351        """
    339352        return self._getmask(rowno)
     
    343356        Parameters:
    344357             spec:   the spectrum
    345              rowno:    the row number to set the spectrum for       
     358             rowno:    the row number to set the spectrum for
    346359        """
    347360        assert(len(spec) == self.nchan())
    348361        return self._setspectrum(spec, rowno)
     362
     363    def get_coordinate(self, rowno):
     364        """Return the (spectral) coordinate for a a given 'rowno'.
     365        NOTE:
     366            * This coordinate is only valid until a scantable method modifies
     367              the frequency axis.
     368            * This coordinate does contain the original frequency set-up
     369              NOT the new frame. The conversions however are done using the user
     370              specified frame (e.g. LSRK/TOPO). To get the 'real' coordinate,
     371              use scantable.freq_align first. Without it there is no closure,
     372              i.e.
     373              c = myscan.get_coordinate(0)
     374              c.to_frequency(c.get_reference_pixel()) != c.get_reference_value()
     375
     376        Parameters:
     377             rowno:    the row number for the spectral coordinate
     378
     379        """
     380        return coordinate(Scantable.get_coordinate(self, rowno))
    349381
    350382    def get_selection(self):
     
    360392        return selector(self._getselection())
    361393
    362     def set_selection(self, selection=selector()):
     394    def set_selection(self, selection=None, **kw):
    363395        """
    364396        Select a subset of the data. All following operations on this scantable
    365397        are only applied to thi selection.
    366398        Parameters:
    367             selection:    a selector object (default unset the selection)
     399            selection:    a selector object (default unset the selection),
     400
     401            or
     402
     403            any combination of
     404            "pols", "ifs", "beams", "scans", "cycles", "name", "query"
     405
    368406        Examples:
    369407            sel = selector()         # create a selection object
     
    372410            scan.summary()           # will only print summary of scanno 0 an 3
    373411            scan.set_selection()     # unset the selection
    374         """
     412            # or the equivalent
     413            scan.set_selection(scans=[0,3])
     414            scan.summary()           # will only print summary of scanno 0 an 3
     415            scan.set_selection()     # unset the selection
     416        """
     417        if selection is None:
     418            # reset
     419            if len(kw) == 0:
     420                selection = selector()
     421            else:
     422                # try keywords
     423                for k in kw:
     424                    if k not in selector.fields:
     425                        raise KeyError("Invalid selection key '%s', valid keys are %s" % (k, selector.fields))
     426                selection = selector(**kw)
    375427        self._setselection(selection)
    376428
     
    425477            scan.stats(stat='mean', mask=m)
    426478        """
    427         if mask == None:
    428             mask = []
    429         axes = ['Beam', 'IF', 'Pol', 'Time']
     479        mask = mask or []
    430480        if not self._check_ifs():
    431481            raise ValueError("Cannot apply mask as the IFs have different "
     
    441491        if not rtnabc: statvals = self._math._stats(self, mask, stat)
    442492
    443         out = ''
    444         axes = []
     493        #def cb(i):
     494        #    return statvals[i]
     495
     496        #return self._row_callback(cb, stat)
     497
     498        label=stat
     499        #callback=cb
     500        out = ""
     501        #outvec = []
     502        sep = '-'*50
    445503        for i in range(self.nrow()):
    446             axis = []
    447             axis.append(self.getscan(i))
    448             axis.append(self.getbeam(i))
    449             axis.append(self.getif(i))
    450             axis.append(self.getpol(i))
    451             axis.append(self.getcycle(i))
    452             axes.append(axis)
    453             tm = self._gettime(i)
    454             src = self._getsourcename(i)
    455504            refstr = ''
    456505            statunit= ''
     
    459508                if rtnabc:
    460509                    statvals.append(qx['value'])
    461                     #refstr = '(value: %3.3f' % (qy['value'])+' ['+qy['unit']+'])'
    462510                    refstr = ('(value: %'+form) % (qy['value'])+' ['+qy['unit']+'])'
    463511                    statunit= '['+qx['unit']+']'
    464512                else:
    465                     #refstr = '(@ %3.3f' % (qx['value'])+' ['+qx['unit']+'])'
    466513                    refstr = ('(@ %'+form) % (qx['value'])+' ['+qx['unit']+'])'
    467                     #statunit= ' ['+qy['unit']+']'
    468             out += 'Scan[%d] (%s) ' % (axis[0], src)
     514
     515            tm = self._gettime(i)
     516            src = self._getsourcename(i)
     517            out += 'Scan[%d] (%s) ' % (self.getscan(i), src)
    469518            out += 'Time[%s]:\n' % (tm)
    470             if self.nbeam(-1) > 1: out +=  ' Beam[%d] ' % (axis[1])
    471             if self.nif(-1) > 1: out +=  ' IF[%d] ' % (axis[2])
    472             if self.npol(-1) > 1: out +=  ' Pol[%d] ' % (axis[3])
    473             #out += '= %3.3f   ' % (statvals[i]) +refstr+'\n'
     519            if self.nbeam(-1) > 1:
     520                out +=  ' Beam[%d] ' % (self.getbeam(i))
     521            if self.nif(-1) > 1: out +=  ' IF[%d] ' % (self.getif(i))
     522            if self.npol(-1) > 1: out +=  ' Pol[%d] ' % (self.getpol(i))
     523            #outvec.append(callback(i))
     524            #out += ('= %'+form) % (outvec[i]) +'   '+refstr+'\n'
    474525            out += ('= %'+form) % (statvals[i]) +'   '+refstr+'\n'
    475             out +=  "--------------------------------------------------\n"
     526            out +=  sep+"\n"
    476527
    477528        if rcParams['verbose']:
     
    484535            tmpfile='/tmp/tmp_'+usr+'_casapy_asap_scantable_stats'
    485536            f=open(tmpfile,'w')
    486             print >> f, "--------------------------------------------------"
    487             print >> f, " ", stat, statunit
    488             print >> f, "--------------------------------------------------"
     537            print >> f, sep
     538            print >> f, ' %s %s' % (label, statunit)
     539            print >> f, sep
    489540            print >> f, out
    490541            f.close()
     
    492543            x=f.readlines()
    493544            f.close()
    494             for xx in x:
    495                 asaplog.push( xx, False )
     545            blanc=''
     546            asaplog.push(blanc.join(x), False)
     547            #for xx in x:
     548            #    asaplog.push( xx, False )
    496549            print_log()
    497         #else:
    498             #retval = { 'axesnames': ['scanno', 'beamno', 'ifno', 'polno', 'cycleno'],
    499             #           'axes' : axes,
    500             #           'data': statvals}
    501550        return statvals
    502551
     
    541590        return list(Scantable.get_column_names(self))
    542591
    543     def get_tsys(self):
     592    def get_tsys(self, row=-1):
    544593        """
    545594        Return the System temperatures.
     
    547596            a list of Tsys values for the current selection
    548597        """
    549 
     598        if row > -1:
     599            return self._get_column(self._gettsys, row)
    550600        return self._row_callback(self._gettsys, "Tsys")
    551601
     602
     603    def get_weather(self, row=-1):
     604        values = self._get_column(self._get_weather, row)
     605        if row > -1:
     606            return {'temperature': values[0],
     607                    'pressure': values[1], 'humidity' : values[2],
     608                    'windspeed' : values[3], 'windaz' : values[4]
     609                    }
     610        else:
     611            out = []
     612            for r in values:
     613
     614                out.append({'temperature': r[0],
     615                            'pressure': r[1], 'humidity' : r[2],
     616                            'windspeed' : r[3], 'windaz' : r[4]
     617                    })
     618            return out
     619
    552620    def _row_callback(self, callback, label):
    553         axes = []
    554         axesnames = ['scanno', 'beamno', 'ifno', 'polno', 'cycleno']
    555621        out = ""
    556622        outvec = []
     623        sep = '-'*50
    557624        for i in range(self.nrow()):
    558             axis = []
    559             axis.append(self.getscan(i))
    560             axis.append(self.getbeam(i))
    561             axis.append(self.getif(i))
    562             axis.append(self.getpol(i))
    563             axis.append(self.getcycle(i))
    564             axes.append(axis)
    565625            tm = self._gettime(i)
    566626            src = self._getsourcename(i)
    567             out += 'Scan[%d] (%s) ' % (axis[0], src)
     627            out += 'Scan[%d] (%s) ' % (self.getscan(i), src)
    568628            out += 'Time[%s]:\n' % (tm)
    569             if self.nbeam(-1) > 1: out +=  ' Beam[%d] ' % (axis[1])
    570             if self.nif(-1) > 1: out +=  ' IF[%d] ' % (axis[2])
    571             if self.npol(-1) > 1: out +=  ' Pol[%d] ' % (axis[3])
     629            if self.nbeam(-1) > 1:
     630                out +=  ' Beam[%d] ' % (self.getbeam(i))
     631            if self.nif(-1) > 1: out +=  ' IF[%d] ' % (self.getif(i))
     632            if self.npol(-1) > 1: out +=  ' Pol[%d] ' % (self.getpol(i))
    572633            outvec.append(callback(i))
    573634            out += '= %3.3f\n' % (outvec[i])
    574             out +=  "--------------------------------------------------\n"
     635            out +=  sep+'\n'
    575636        if rcParams['verbose']:
    576             asaplog.push("--------------------------------------------------")
     637            asaplog.push(sep)
    577638            asaplog.push(" %s" % (label))
    578             asaplog.push("--------------------------------------------------")
     639            asaplog.push(sep)
    579640            asaplog.push(out)
    580641            print_log()
    581         # disabled because the vector seems more useful
    582         #retval = {'axesnames': axesnames, 'axes': axes, 'data': outvec}
    583642        return outvec
    584643
     
    624683            none
    625684        """
    626         return self._get_column(self._getinttime, row)       
    627        
     685        return self._get_column(self._getinttime, row)
     686
    628687
    629688    def get_sourcename(self, row=-1):
     
    674733        """
    675734        Get a list of Positions on the sky (direction) for the observations.
    676         Return a float for each integration in the scantable.
     735        Return a string for each integration in the scantable.
    677736        Parameters:
    678737            row:    row no of integration. Default -1 return all rows
     
    693752        return self._get_column(self._getdirectionvec, row)
    694753
     754    #@print_log_dec
    695755    def set_unit(self, unit='channel'):
    696756        """
     
    708768        self._add_history("set_unit", varlist)
    709769
     770    #@print_log_dec
    710771    def set_instrument(self, instr):
    711772        """
     
    719780        print_log()
    720781
     782    #@print_log_dec
    721783    def set_feedtype(self, feedtype):
    722784        """
     
    729791        print_log()
    730792
     793    #@print_log_dec
    731794    def set_doppler(self, doppler='RADIO'):
    732795        """
     
    742805        print_log()
    743806
     807    #@print_log_dec
    744808    def set_freqframe(self, frame=None):
    745809        """
     
    747811        Parameters:
    748812            frame:   an optional frame type, default 'LSRK'. Valid frames are:
    749                      'REST', 'TOPO', 'LSRD', 'LSRK', 'BARY',
     813                     'TOPO', 'LSRD', 'LSRK', 'BARY',
    750814                     'GEO', 'GALACTO', 'LGROUP', 'CMB'
    751815        Examples:
    752816            scan.set_freqframe('BARY')
    753817        """
    754         if frame is None: frame = rcParams['scantable.freqframe']
    755         varlist = vars()
    756         valid = ['REST', 'TOPO', 'LSRD', 'LSRK', 'BARY', \
     818        frame = frame or rcParams['scantable.freqframe']
     819        varlist = vars()
     820        # "REST" is not implemented in casacore
     821        #valid = ['REST', 'TOPO', 'LSRD', 'LSRK', 'BARY', \
     822        #           'GEO', 'GALACTO', 'LGROUP', 'CMB']
     823        valid = ['TOPO', 'LSRD', 'LSRK', 'BARY', \
    757824                   'GEO', 'GALACTO', 'LGROUP', 'CMB']
    758825
     
    829896        """
    830897        varlist = vars()
    831         if mask is None:
    832             mask = []
     898        mask = mask or []
    833899        try:
    834900            self._flag(mask, unflag)
     
    883949            else: raise
    884950        self._add_history("clip", varlist)
    885        
    886     def lag_flag(self, frequency, width=0.0, unit="GHz", insitu=None):
     951
     952    #@print_log_dec
     953    def lag_flag(self, start, end, unit="MHz", insitu=None):
     954    #def lag_flag(self, frequency, width=0.0, unit="GHz", insitu=None):
    887955        """
    888956        Flag the data in 'lag' space by providing a frequency to remove.
    889         Flagged data in the scantable gets set to 0.0 before the fft.
     957        Flagged data in the scantable gets interpolated over the region.
    890958        No taper is applied.
    891959        Parameters:
    892             frequency:    the frequency (really a period within the bandwidth)
    893                           to remove
    894             width:        the width of the frequency to remove, to remove a
    895                           range of frequencies around the centre.
    896             unit:         the frequency unit (default "GHz")
     960            start:    the start frequency (really a period within the
     961                      bandwidth)  or period to remove
     962            end:      the end frequency or period to remove
     963            unit:     the frequency unit (default "MHz") or "" for
     964                      explicit lag channels
    897965        Notes:
    898             It is recommended to flag edges of the band or strong 
     966            It is recommended to flag edges of the band or strong
    899967            signals beforehand.
    900968        """
     
    902970        self._math._setinsitu(insitu)
    903971        varlist = vars()
    904         base = { "GHz": 1000000000., "MHz": 1000000., "kHz": 1000., "Hz": 1. }
    905         if not base.has_key(unit):
     972        base = { "GHz": 1000000000., "MHz": 1000000., "kHz": 1000., "Hz": 1.}
     973        if not (unit == "" or base.has_key(unit)):
    906974            raise ValueError("%s is not a valid unit." % unit)
    907975        try:
    908             s = scantable(self._math._lag_flag(self, frequency*base[unit],
    909                                                width*base[unit]))
     976            if unit == "":
     977                s = scantable(self._math._lag_flag(self, start, end, "lags"))
     978            else:
     979                s = scantable(self._math._lag_flag(self, start*base[unit],
     980                                                   end*base[unit], "frequency"))
    910981        except RuntimeError, msg:
    911982            if rcParams['verbose']:
     
    923994            return s
    924995
    925 
     996    #@print_log_dec
    926997    def create_mask(self, *args, **kwargs):
    927998        """
     
    9521023            c)
    9531024            mask only channel 400
    954             msk =  scan.create_mask([400, 400])
    955         """
    956         row = 0
    957         if kwargs.has_key("row"):
    958             row = kwargs.get("row")
     1025            msk =  scan.create_mask([400])
     1026        """
     1027        row = kwargs.get("row", 0)
    9591028        data = self._getabcissa(row)
    9601029        u = self._getcoordinfo()[0]
     
    9731042             and args or args[0]
    9741043        for window in ws:
    975             if (len(window) != 2 or window[0] > window[1] ):
    976                 raise TypeError("A window needs to be defined as [min, max]")
     1044            if len(window) == 1:
     1045                window = [window[0], window[0]]
     1046            if len(window) == 0 or  len(window) > 2:
     1047                raise ValueError("A window needs to be defined as [start(, end)]")
     1048            if window[0] > window[1]:
     1049                tmp = window[0]
     1050                window[0] = window[1]
     1051                window[1] = tmp
    9771052            for i in range(n):
    9781053                if data[i] >= window[0] and data[i] <= window[1]:
     
    11271202            source and IF basis, use scantable.set_selection() before using
    11281203            this function.
    1129             # provide your scantable is call scan
     1204            # provide your scantable is called scan
    11301205            selection = selector()
    11311206            selection.set_name("ORION*")
     
    11881263
    11891264    def shift_refpix(self, delta):
    1190         """
    1191         Shift the reference pixel of the Spectra Coordinate by an
    1192         integer amount.
    1193         Parameters:
    1194             delta:   the amount to shift by
     1265        """
     1266        Shift the reference pixel of the Spectra Coordinate by an
     1267        integer amount.
     1268        Parameters:
     1269            delta:   the amount to shift by
    11951270        Note:
    1196             Be careful using this with broadband data.
    1197         """
    1198         Scantable.shift(self, delta)
     1271            Be careful using this with broadband data.
     1272        """
     1273        Scantable.shift_refpix(self, delta)
    11991274
    12001275    def history(self, filename=None):
     
    12491324    # Maths business
    12501325    #
    1251 
     1326    #@print_log_dec
    12521327    def average_time(self, mask=None, scanav=False, weight='tint', align=False):
    12531328        """
     
    12751350        """
    12761351        varlist = vars()
    1277         if weight is None: weight = 'TINT'
    1278         if mask is None: mask = ()
    1279         if scanav: scanav = "SCAN"
    1280         else: scanav = "NONE"
     1352        weight = weight or 'TINT'
     1353        mask = mask or ()
     1354        scanav = (scanav and 'SCAN') or 'NONE'
    12811355        scan = (self, )
    12821356        try:
     
    13021376        return s
    13031377
     1378    #@print_log_dec
    13041379    def convert_flux(self, jyperk=None, eta=None, d=None, insitu=None):
    13051380        """
     
    13211396        self._math._setinsitu(insitu)
    13221397        varlist = vars()
    1323         if jyperk is None: jyperk = -1.0
    1324         if d is None: d = -1.0
    1325         if eta is None: eta = -1.0
     1398        jyperk = jyperk or -1.0
     1399        d = d or -1.0
     1400        eta = eta or -1.0
    13261401        s = scantable(self._math._convertflux(self, d, eta, jyperk))
    13271402        s._add_history("convert_flux", varlist)
     
    13301405        else: return s
    13311406
     1407    #@print_log_dec
    13321408    def gain_el(self, poly=None, filename="", method="linear", insitu=None):
    13331409        """
     
    13731449        self._math._setinsitu(insitu)
    13741450        varlist = vars()
    1375         if poly is None:
    1376             poly = ()
     1451        poly = poly or ()
    13771452        from os.path import expandvars
    13781453        filename = expandvars(filename)
     
    13801455        s._add_history("gain_el", varlist)
    13811456        print_log()
    1382         if insitu: self._assign(s)
    1383         else: return s
    1384 
     1457        if insitu:
     1458            self._assign(s)
     1459        else:
     1460            return s
     1461
     1462    #@print_log_dec
    13851463    def freq_align(self, reftime=None, method='cubic', insitu=None):
    13861464        """
     
    14011479        self._math._setinsitu(insitu)
    14021480        varlist = vars()
    1403         if reftime is None: reftime = ""
     1481        reftime = reftime or ""
    14041482        s = scantable(self._math._freq_align(self, reftime, method))
    14051483        s._add_history("freq_align", varlist)
     
    14081486        else: return s
    14091487
    1410     def opacity(self, tau, insitu=None):
     1488    #@print_log_dec
     1489    def opacity(self, tau=None, insitu=None):
    14111490        """
    14121491        Apply an opacity correction. The data
    14131492        and Tsys are multiplied by the correction factor.
    14141493        Parameters:
    1415             tau:         Opacity from which the correction factor is
     1494            tau:         (list of) opacity from which the correction factor is
    14161495                         exp(tau*ZD)
    1417                          where ZD is the zenith-distance
     1496                         where ZD is the zenith-distance.
     1497                         If a list is provided, it has to be of length nIF,
     1498                         nIF*nPol or 1 and in order of IF/POL, e.g.
     1499                         [opif0pol0, opif0pol1, opif1pol0 ...]
     1500                         if tau is `None` the opacities are determined from a
     1501                         model.
    14181502            insitu:      if False a new scantable is returned.
    14191503                         Otherwise, the scaling is done in-situ
     
    14231507        self._math._setinsitu(insitu)
    14241508        varlist = vars()
     1509        if not hasattr(tau, "__len__"):
     1510            tau = [tau]
    14251511        s = scantable(self._math._opacity(self, tau))
    14261512        s._add_history("opacity", varlist)
     
    14291515        else: return s
    14301516
     1517    #@print_log_dec
    14311518    def bin(self, width=5, insitu=None):
    14321519        """
     
    14441531        s._add_history("bin", varlist)
    14451532        print_log()
    1446         if insitu: self._assign(s)
    1447         else: return s
    1448 
    1449 
     1533        if insitu:
     1534            self._assign(s)
     1535        else:
     1536            return s
     1537
     1538    #@print_log_dec
    14501539    def resample(self, width=5, method='cubic', insitu=None):
    14511540        """
     
    14701559        else: return s
    14711560
    1472 
     1561    #@print_log_dec
    14731562    def average_pol(self, mask=None, weight='none'):
    14741563        """
     
    14821571        """
    14831572        varlist = vars()
    1484         if mask is None:
    1485             mask = ()
     1573        mask = mask or ()
    14861574        s = scantable(self._math._averagepol(self, mask, weight.upper()))
    14871575        s._add_history("average_pol", varlist)
     
    14891577        return s
    14901578
     1579    #@print_log_dec
    14911580    def average_beam(self, mask=None, weight='none'):
    14921581        """
     
    15001589        """
    15011590        varlist = vars()
    1502         if mask is None:
    1503             mask = ()
     1591        mask = mask or ()
    15041592        s = scantable(self._math._averagebeams(self, mask, weight.upper()))
    15051593        s._add_history("average_beam", varlist)
     
    15071595        return s
    15081596
     1597    def parallactify(self, pflag):
     1598        """
     1599        Set a flag to inidcate whether this data should be treated as having
     1600        been 'parallactified' (total phase == 0.0)
     1601        Parameters:
     1602            pflag:  Bool inidcating whether to turn this on (True) or
     1603                    off (False)
     1604        """
     1605        varlist = vars()
     1606        self._parallactify(pflag)
     1607        self._add_history("parallactify", varlist)
     1608
     1609    #@print_log_dec
    15091610    def convert_pol(self, poltype=None):
    15101611        """
    15111612        Convert the data to a different polarisation type.
     1613        Note that you will need cross-polarisation terms for most conversions.
    15121614        Parameters:
    15131615            poltype:    The new polarisation type. Valid types are:
    1514                         "linear", "stokes" and "circular"
     1616                        "linear", "circular", "stokes" and "linpol"
    15151617        """
    15161618        varlist = vars()
     
    15301632        return s
    15311633
    1532     #def smooth(self, kernel="hanning", width=5.0, insitu=None):
    1533     def smooth(self, kernel="hanning", width=5.0, plot=False, insitu=None):
     1634    #@print_log_dec
     1635    def smooth(self, kernel="hanning", width=5.0, order=2, plot=False, insitu=None):
    15341636        """
    15351637        Smooth the spectrum by the specified kernel (conserving flux).
    15361638        Parameters:
    15371639            kernel:     The type of smoothing kernel. Select from
    1538                         'hanning' (default), 'gaussian', 'boxcar' and
    1539                         'rmedian'
     1640                        'hanning' (default), 'gaussian', 'boxcar', 'rmedian'
     1641                        or 'poly'
    15401642            width:      The width of the kernel in pixels. For hanning this is
    15411643                        ignored otherwise it defauls to 5 pixels.
    15421644                        For 'gaussian' it is the Full Width Half
    15431645                        Maximum. For 'boxcar' it is the full width.
    1544                         For 'rmedian' it is the half width.
     1646                        For 'rmedian' and 'poly' it is the half width.
     1647            order:      Optional parameter for 'poly' kernel (default is 2), to
     1648                        specify the order of the polnomial. Ignored by all other
     1649                        kernels.
    15451650            plot:       plot the original and the smoothed spectra.
    15461651                        In this each indivual fit has to be approved, by
     
    15581663        if plot: orgscan = self.copy()
    15591664
    1560         s = scantable(self._math._smooth(self, kernel.lower(), width))
     1665        s = scantable(self._math._smooth(self, kernel.lower(), width, order))
    15611666        s._add_history("smooth", varlist)
    15621667
     
    16011706        else: return s
    16021707
    1603 
    1604     def poly_baseline(self, mask=None, order=0, plot=False, uselin=False, insitu=None):
     1708    #@print_log_dec
     1709    def poly_baseline(self, mask=None, order=0, plot=False, uselin=False,
     1710                      insitu=None):
    16051711        """
    16061712        Return a scan which has been baselined (all rows) by a polynomial.
     
    18331939            return workscan
    18341940
     1941    #@print_log_dec
    18351942    def rotate_linpolphase(self, angle):
    18361943        """
     
    18491956        return
    18501957
    1851 
     1958    #@print_log_dec
    18521959    def rotate_xyphase(self, angle):
    18531960        """
     
    18661973        return
    18671974
     1975    #@print_log_dec
    18681976    def swap_linears(self):
    18691977        """
    1870         Swap the linear polarisations XX and YY, or better the first two 
     1978        Swap the linear polarisations XX and YY, or better the first two
    18711979        polarisations as this also works for ciculars.
    18721980        """
     
    18771985        return
    18781986
     1987    #@print_log_dec
    18791988    def invert_phase(self):
    18801989        """
     
    18871996        return
    18881997
     1998    #@print_log_dec
    18891999    def add(self, offset, insitu=None):
    18902000        """
     
    19072017            return s
    19082018
     2019    #@print_log_dec
    19092020    def scale(self, factor, tsys=True, insitu=None):
    19102021        """
     
    19722083        self._setsourcetype(stype)
    19732084        self.set_selection(basesel)
    1974         s._add_history("set_sourcetype", varlist)
    1975 
     2085        self._add_history("set_sourcetype", varlist)
     2086
     2087    #@print_log_dec
    19762088    def auto_quotient(self, preserve=True, mode='paired', verify=False):
    19772089        """
     
    19842096                            preserve: Output = Toff * (on/off) - Toff
    19852097                            remove:   Output = Toff * (on/off) - Ton
    1986             mode:           the on/off detection mode 
     2098            mode:           the on/off detection mode
    19872099                            'paired' (default)
    19882100                            identifies 'off' scans by the
     
    20172129        return s
    20182130
     2131    #@print_log_dec
    20192132    def mx_quotient(self, mask = None, weight='median', preserve=True):
    20202133        """
     
    20282141                            remove:   Output = Toff * (on/off) - Ton
    20292142        """
    2030         if mask is None: mask = ()
     2143        mask = mask or ()
    20312144        varlist = vars()
    20322145        on = scantable(self._math._mx_extract(self, 'on'))
     
    20392152        return q
    20402153
     2154    #@print_log_dec
    20412155    def freq_switch(self, insitu=None):
    20422156        """
     
    20582172        else: return s
    20592173
     2174    #@print_log_dec
    20602175    def recalc_azel(self):
    20612176        """
     
    20712186        return
    20722187
     2188    #@print_log_dec
    20732189    def __add__(self, other):
    20742190        """
     
    20772193        return self._operation( other, "ADD" )
    20782194
     2195    #@print_log_dec
    20792196    def __sub__(self, other):
    20802197        """
     
    20832200        return self._operation( other, 'SUB' )
    20842201
     2202    #@print_log_dec
    20852203    def __mul__(self, other):
    20862204        """
     
    20892207        return self._operation( other, 'MUL' )
    20902208
     2209    #@print_log_dec
    20912210    def __div__(self, other):
    20922211        """
     
    21202239        basesel = self.get_selection()
    21212240        for i in range(self.nrow()):
    2122             sel = selector()+basesel
    2123             sel.set_scans(self.getscan(i))
    2124             sel.set_beams(self.getbeam(i))
    2125             sel.set_ifs(self.getif(i))
    2126             sel.set_polarisations(self.getpol(i))
    2127             self.set_selection(sel)
     2241            sel = self.get_row_selector(i)
     2242            self.set_selection(basesel+sel)
    21282243            nans = numpy.isnan(self._getspectrum(0))
    21292244        if numpy.any(nans):
     
    21312246            self.flag(bnans)
    21322247        self.set_selection(basesel)
    2133        
     2248
     2249    def get_row_selector(self, rowno):
     2250        return selector(beams=self.getbeam(rowno),
     2251                        ifs=self.getif(rowno),
     2252                        pols=self.getpol(rowno),
     2253                        scans=self.getscan(rowno),
     2254                        cycles=self.getcycle(rowno))
    21342255
    21352256    def _add_history(self, funcname, parameters):
Note: See TracChangeset for help on using the changeset viewer.