Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/python/scantable.py

    r2687 r3010  
    22
    33import os
     4import re
    45import tempfile
    56import numpy
     
    4546        l=f.readline()
    4647        f.close()
    47         if ( l.find('Scantable') != -1 ):
    48             return True
    49         elif ( l.find('Measurement Set') == -1 and
    50                l.find('Image') == -1 ):
     48        match_pattern = '^Type = (Scantable)? *$'
     49        if re.match(match_pattern,l):
    5150            return True
    5251        else:
     
    175174    return str(showprogress).lower() + ',' + str(minnrow)
    176175
     176def pack_blinfo(blinfo, maxirow):
     177    """\
     178    convert a dictionary or a list of dictionaries of baseline info
     179    into a list of comma-separated strings.
     180    """
     181    if isinstance(blinfo, dict):
     182        res = do_pack_blinfo(blinfo, maxirow)
     183        return [res] if res != '' else []
     184    elif isinstance(blinfo, list) or isinstance(blinfo, tuple):
     185        res = []
     186        for i in xrange(len(blinfo)):
     187            resi = do_pack_blinfo(blinfo[i], maxirow)
     188            if resi != '':
     189                res.append(resi)
     190    return res
     191
     192def do_pack_blinfo(blinfo, maxirow):
     193    """\
     194    convert a dictionary of baseline info for a spectrum into
     195    a comma-separated string.
     196    """
     197    dinfo = {}
     198    for key in ['row', 'blfunc', 'masklist']:
     199        if blinfo.has_key(key):
     200            val = blinfo[key]
     201            if key == 'row':
     202                irow = val
     203            if isinstance(val, list) or isinstance(val, tuple):
     204                slval = []
     205                for i in xrange(len(val)):
     206                    if isinstance(val[i], list) or isinstance(val[i], tuple):
     207                        for j in xrange(len(val[i])):
     208                            slval.append(str(val[i][j]))
     209                    else:
     210                        slval.append(str(val[i]))
     211                sval = ",".join(slval)
     212            else:
     213                sval = str(val)
     214
     215            dinfo[key] = sval
     216        else:
     217            raise ValueError("'"+key+"' is missing in blinfo.")
     218
     219    if irow >= maxirow: return ''
     220   
     221    for key in ['order', 'npiece', 'nwave']:
     222        if blinfo.has_key(key):
     223            val = blinfo[key]
     224            if isinstance(val, list) or isinstance(val, tuple):
     225                slval = []
     226                for i in xrange(len(val)):
     227                    slval.append(str(val[i]))
     228                sval = ",".join(slval)
     229            else:
     230                sval = str(val)
     231            dinfo[key] = sval
     232
     233    fspec_keys = {'poly': 'order', 'chebyshev': 'order', 'cspline': 'npiece', 'sinusoid': 'nwave'}
     234
     235    fspec_key = fspec_keys[dinfo['blfunc']]
     236    if not blinfo.has_key(fspec_key):
     237        raise ValueError("'"+fspec_key+"' is missing in blinfo.")
     238
     239    clip_params_n = 0
     240    for key in ['clipthresh', 'clipniter']:
     241        if blinfo.has_key(key):
     242            clip_params_n += 1
     243            dinfo[key] = str(blinfo[key])
     244
     245    if clip_params_n == 0:
     246        dinfo['clipthresh'] = '0.0'
     247        dinfo['clipniter']  = '0'
     248    elif clip_params_n != 2:
     249        raise ValueError("both 'clipthresh' and 'clipniter' must be given for n-sigma clipping.")
     250
     251    lf_params_n = 0
     252    for key in ['thresh', 'edge', 'chan_avg_limit']:
     253        if blinfo.has_key(key):
     254            lf_params_n += 1
     255            val = blinfo[key]
     256            if isinstance(val, list) or isinstance(val, tuple):
     257                slval = []
     258                for i in xrange(len(val)):
     259                    slval.append(str(val[i]))
     260                sval = ",".join(slval)
     261            else:
     262                sval = str(val)
     263            dinfo[key] = sval
     264
     265    if lf_params_n == 3:
     266        dinfo['use_linefinder'] = 'true'
     267    elif lf_params_n == 0:
     268        dinfo['use_linefinder'] = 'false'
     269        dinfo['thresh']         = ''
     270        dinfo['edge']           = ''
     271        dinfo['chan_avg_limit'] = ''
     272    else:
     273        raise ValueError("all of 'thresh', 'edge' and 'chan_avg_limit' must be given to use linefinder.")
     274   
     275    slblinfo = [dinfo['row'], dinfo['blfunc'], dinfo[fspec_key], dinfo['masklist'], \
     276                dinfo['clipthresh'], dinfo['clipniter'], \
     277                dinfo['use_linefinder'], dinfo['thresh'], dinfo['edge'], dinfo['chan_avg_limit']]
     278   
     279    return ":".join(slblinfo)
     280
     281def parse_fitresult(sres):
     282    """\
     283    Parse the returned value of apply_bltable() or sub_baseline() and
     284    extract row number, the best-fit coefficients and rms, then pack
     285    them into a dictionary.
     286    The input value is generated by Scantable::packFittingResults() and
     287    formatted as 'row:coeff[0],coeff[1],..,coeff[n-1]:rms'.
     288    """
     289    res = []
     290    for i in xrange(len(sres)):
     291        (srow, scoeff, srms) = sres[i].split(":")
     292        row = int(srow)
     293        rms = float(srms)
     294        lscoeff = scoeff.split(",")
     295        coeff = []
     296        for j in xrange(len(lscoeff)):
     297            coeff.append(float(lscoeff[j]))
     298        res.append({'row': row, 'coeff': coeff, 'rms': rms})
     299
     300    return res
     301
     302def is_number(s):
     303    s = s.strip()
     304    res = True
     305    try:
     306        a = float(s)
     307        res = True
     308    except:
     309        res = False
     310    finally:
     311        return res
     312
     313def is_frequency(s):
     314    s = s.strip()
     315    return (s[-2:].lower() == "hz")
     316
     317def get_freq_by_string(s1, s2):
     318    if not (is_number(s1) and is_frequency(s2)):
     319        raise RuntimeError("Invalid input string.")
     320   
     321    prefix_list = ["a", "f", "p", "n", "u", "m", ".", "k", "M", "G", "T", "P", "E"]
     322    factor_list = [1e-18, 1e-15, 1e-12, 1e-9, 1e-6, 1e-3, 1.0, 1e+3, 1e+6, 1e+9, 1e+12, 1e+15, 1e+18]
     323
     324    s1 = s1.strip()
     325    s2 = s2.strip()
     326   
     327    prefix = s2[-3:-2]
     328    if is_number(prefix):
     329        res1 = float(s1)
     330        res2 = float(s2[:-2])
     331    else:
     332        factor = factor_list[prefix_list.index(prefix)]
     333        res1 = float(s1) * factor
     334        res2 = float(s2[:-3]) * factor
     335
     336    return (res1, res2)
     337
     338def is_velocity(s):
     339    s = s.strip()
     340    return (s[-3:].lower() == "m/s")
     341
     342def get_velocity_by_string(s1, s2):
     343    if not (is_number(s1) and is_velocity(s2)):
     344        raise RuntimeError("Invalid input string.")
     345
     346    # note that the default velocity unit is km/s
     347    prefix_list = [".", "k"]
     348    factor_list = [1e-3, 1.0]
     349
     350    s1 = s1.strip()
     351    s2 = s2.strip()
     352
     353    prefix = s2[-4:-3]
     354    if is_number(prefix): # in case velocity unit m/s
     355        res1 = float(s1) * 1e-3
     356        res2 = float(s2[:-3]) * 1e-3
     357    else:
     358        factor = factor_list[prefix_list.index(prefix)]
     359        res1 = float(s1) * factor
     360        res2 = float(s2[:-4]) * factor
     361
     362    return (res1, res2)
     363
     364def get_frequency_by_velocity(restfreq, vel, doppler):
     365    # vel is in unit of km/s
     366
     367    # speed of light
     368    vel_c = 299792.458
     369
     370    import math
     371    r = vel / vel_c
     372
     373    if doppler.lower() == 'radio':
     374        return restfreq * (1.0 - r)
     375    if doppler.lower() == 'optical':
     376        return restfreq / (1.0 + r)
     377    else:
     378        return restfreq * math.sqrt((1.0 - r) / (1.0 + r))
     379
     380def get_restfreq_in_Hz(s_restfreq):
     381    value = 0.0
     382    unit = ""
     383    s = s_restfreq.replace(" ","")
     384
     385    for i in range(len(s))[::-1]:
     386        if s[i].isalpha():
     387            unit = s[i] + unit
     388        else:
     389            value = float(s[0:i+1])
     390            break
     391
     392    if (unit == "") or (unit.lower() == "hz"):
     393        return value
     394    elif (len(unit) == 3) and (unit[1:3].lower() == "hz"):
     395        unitprefix = unit[0]
     396        factor = 1.0
     397
     398        prefix_list = ["a", "f", "p", "n", "u", "m", ".", "k", "M", "G", "T", "P", "E"]
     399        factor_list = [1e-18, 1e-15, 1e-12, 1e-9, 1e-6, 1e-3, 1.0, 1e+3, 1e+6, 1e+9, 1e+12, 1e+15, 1e+18]
     400        factor = factor_list[prefix_list.index(unitprefix)]
     401        """
     402        if (unitprefix == 'a'):
     403            factor = 1.0e-18
     404        elif (unitprefix == 'f'):
     405            factor = 1.0e-15
     406        elif (unitprefix == 'p'):
     407            factor = 1.0e-12
     408        elif (unitprefix == 'n'):
     409            factor = 1.0e-9
     410        elif (unitprefix == 'u'):
     411            factor = 1.0e-6
     412        elif (unitprefix == 'm'):
     413            factor = 1.0e-3
     414        elif (unitprefix == 'k'):
     415            factor = 1.0e+3
     416        elif (unitprefix == 'M'):
     417            factor = 1.0e+6
     418        elif (unitprefix == 'G'):
     419            factor = 1.0e+9
     420        elif (unitprefix == 'T'):
     421            factor = 1.0e+12
     422        elif (unitprefix == 'P'):
     423            factor = 1.0e+15
     424        elif (unitprefix == 'E'):
     425            factor = 1.0e+18
     426        """
     427        return value*factor
     428    else:
     429        mesg = "wrong unit of restfreq."
     430        raise Exception, mesg
     431
     432def normalise_restfreq(in_restfreq):
     433    if isinstance(in_restfreq, float):
     434        return in_restfreq
     435    elif isinstance(in_restfreq, int) or isinstance(in_restfreq, long):
     436        return float(in_restfreq)
     437    elif isinstance(in_restfreq, str):
     438        return get_restfreq_in_Hz(in_restfreq)
     439    elif isinstance(in_restfreq, list) or isinstance(in_restfreq, numpy.ndarray):
     440        if isinstance(in_restfreq, numpy.ndarray):
     441            if len(in_restfreq.shape) > 1:
     442                mesg = "given in numpy.ndarray, in_restfreq must be 1-D."
     443                raise Exception, mesg
     444       
     445        res = []
     446        for i in xrange(len(in_restfreq)):
     447            elem = in_restfreq[i]
     448            if isinstance(elem, float):
     449                res.append(elem)
     450            elif isinstance(elem, int) or isinstance(elem, long):
     451                res.append(float(elem))
     452            elif isinstance(elem, str):
     453                res.append(get_restfreq_in_Hz(elem))
     454            elif isinstance(elem, dict):
     455                if isinstance(elem["value"], float):
     456                    res.append(elem)
     457                elif isinstance(elem["value"], int):
     458                    dictelem = {}
     459                    dictelem["name"]  = elem["name"]
     460                    dictelem["value"] = float(elem["value"])
     461                    res.append(dictelem)
     462                elif isinstance(elem["value"], str):
     463                    dictelem = {}
     464                    dictelem["name"]  = elem["name"]
     465                    dictelem["value"] = get_restfreq_in_Hz(elem["value"])
     466                    res.append(dictelem)
     467            else:
     468                mesg = "restfreq elements must be float, int, or string."
     469                raise Exception, mesg
     470        return res
     471    else:
     472        mesg = "wrong type of restfreq given."
     473        raise Exception, mesg
     474
     475def set_restfreq(s, restfreq):
     476    rfset = (restfreq != '') and (restfreq != [])
     477    if rfset:
     478        s.set_restfreqs(normalise_restfreq(restfreq))
     479
    177480class scantable(Scantable):
    178481    """\
     
    210513                          Default (false) is taken from rc file.
    211514
     515            getpt:        Whether to import direction from MS/POINTING
     516                          table properly or not.
     517                          This is effective only when filename is MS.
     518                          The default (True) is to import direction
     519                          from MS/POINTING.
    212520        """
    213521        if average is None:
     
    244552                    self._fill([filename], unit, average, opts)
    245553                elif os.path.isfile(filename):
    246                     self._fill([filename], unit, average)
     554                    opts={'nro': {}}
     555                    nrokeys=['freqref']
     556                    for key in nrokeys:
     557                        if key in args.keys():
     558                            opts['nro'][key] = args[key]
     559                    self._fill([filename], unit, average, opts)
    247560                    # only apply to new data not "copy constructor"
    248561                    self.parallactify(parallactify)
     
    578891
    579892    @asaplog_post_dec
    580     def stats(self, stat='stddev', mask=None, form='3.3f', row=None):
     893    def stats(self, stat='stddev', mask=None, form='3.3f', row=None, skip_flaggedrow=False):
    581894        """\
    582895        Determine the specified statistic of the current beam/if/pol
     
    596909            row:     row number of spectrum to process.
    597910                     (default is None: for all rows)
     911
     912            skip_flaggedrow: if True, skip outputting text for flagged
     913                             spectra. default is False.
    598914
    599915        Example:
     
    608924                             "number of channels. Please use setselection() "
    609925                             "to select individual IFs")
    610         rtnabc = False
    611         if stat.lower().endswith('_abc'): rtnabc = True
    612926        getchan = False
    613927        if stat.lower().startswith('min') or stat.lower().startswith('max'):
     
    615929            getchan = True
    616930            statvals = []
    617         if not rtnabc:
     931
     932        rtnabc = False
     933        if stat.lower().endswith('_abc'):
     934            rtnabc = True
     935        else:
    618936            if row == None:
    619937                statvals = self._math._stats(self, mask, stat)
     
    641959            statunit= ''
    642960            if getchan:
    643                 qx, qy = self.chan2data(rowno=i, chan=chan[i])
    644                 if rtnabc:
    645                     statvals.append(qx['value'])
    646                     refstr = ('(value: %'+form) % (qy['value'])+' ['+qy['unit']+'])'
    647                     statunit= '['+qx['unit']+']'
     961                if self._is_all_chan_flagged(i):
     962                    if rtnabc:
     963                        statvals.append(None)
    648964                else:
    649                     refstr = ('(@ %'+form) % (qx['value'])+' ['+qx['unit']+'])'
     965                    qx, qy = self.chan2data(rowno=i, chan=chan[i])
     966                    if rtnabc:
     967                        statvals.append(qx['value'])
     968                        refstr = ('(value: %'+form) % (qy['value'])+' ['+qy['unit']+'])'
     969                        statunit= '['+qx['unit']+']'
     970                    else:
     971                        refstr = ('(@ %'+form) % (qx['value'])+' ['+qx['unit']+'])'
     972
     973            if self._is_all_chan_flagged(i):
     974                if not rtnabc:
     975                    statvals[i] = None
     976                if skip_flaggedrow:
     977                    continue
    650978
    651979            tm = self._gettime(i)
     
    659987            if len(rows) > 1:
    660988                # out += ('= %'+form) % (outvec[i]) +'   '+refstr+'\n'
    661                 out += ('= %'+form) % (statvals[i]) +'   '+refstr+'\n'
     989                if statvals[i] is None:
     990                    out += ('= None(flagged)') + '   '+refstr+'\n'
     991                else:
     992                    out += ('= %'+form) % (statvals[i]) +'   '+refstr+'\n'
    662993            else:
    663994                # out += ('= %'+form) % (outvec[0]) +'   '+refstr+'\n'
    664                 out += ('= %'+form) % (statvals[0]) +'   '+refstr+'\n'
     995                if statvals[0] is None:
     996                    out += ('= None(flagged)') + '   '+refstr+'\n'
     997                else:
     998                    out += ('= %'+form) % (statvals[0]) +'   '+refstr+'\n'
    665999            out +=  sep+"\n"
    6661000
     
    6831017        asaplog.push(''.join(x), False)
    6841018
     1019        if skip_flaggedrow:
     1020            nstatvals = len(statvals)
     1021            for i in reversed(xrange(nstatvals)):
     1022                if statvals[i] is None:
     1023                    del statvals[i]
    6851024        return statvals
    6861025
     
    7651104        return self._get_column( self._gettsysspectrum, row )
    7661105
     1106    def set_tsys(self, values, row=-1):
     1107        """\
     1108        Set the Tsys value(s) of the given 'row' or the whole scantable
     1109        (selection).
     1110       
     1111        Parameters:
     1112
     1113            values:    a scalar or list (if Tsys is a vector) of Tsys value(s)
     1114            row:       the row number to apply Tsys values to.
     1115                       (default all rows)
     1116                       
     1117        """
     1118           
     1119        if not hasattr(values, "__len__"):
     1120            values = [values]
     1121        self._settsys(values, row)
     1122
    7671123    def get_weather(self, row=-1):
    7681124        """\
    769         Return the weather informations.
     1125        Return the weather information.
    7701126
    7711127        Parameters:
     
    7781134
    7791135        """
    780 
     1136        if row >= len(self):
     1137            raise IndexError("row out of range")
    7811138        values = self._get_column(self._get_weather, row)
    7821139        if row > -1:
     
    7881145            out = []
    7891146            for r in values:
    790 
    7911147                out.append({'temperature': r[0],
    7921148                            'pressure': r[1], 'humidity' : r[2],
     
    10051361        self._add_history("set_feedtype", vars())
    10061362
     1363    @asaplog_post_dec
     1364    def get_doppler(self):
     1365        """\
     1366        Get the doppler.
     1367        """
     1368        return self._getcoordinfo()[2]
     1369   
    10071370    @asaplog_post_dec
    10081371    def set_doppler(self, doppler='RADIO'):
     
    14711834
    14721835    @asaplog_post_dec
     1836    def parse_spw_selection(self, selectstring, restfreq=None, frame=None, doppler=None):
     1837        """
     1838        Parse MS type spw/channel selection syntax.
     1839
     1840        Parameters:
     1841            selectstring : A string expression of spw and channel selection.
     1842                           Comma-separated expressions mean different spw -
     1843                           channel combinations. Spws and channel selections
     1844                           are partitioned by a colon ':'. In a single
     1845                           selection expression, you can put multiple values
     1846                           separated by semicolons ';'. Both for spw and
     1847                           channel selection, allowed cases include single
     1848                           value, blank('') or asterisk('*') to specify all
     1849                           available values, two values connected with a
     1850                           tilde ('~') to specify an inclusive range. Unit
     1851                           strings for frequency or velocity can be added to
     1852                           the tilde-connected values. For channel selection
     1853                           expression, placing a '<' or a '>' is possible to
     1854                           specify a semi-infinite interval as well.
     1855
     1856                     examples:
     1857                           '' or '*'   = all spws (all channels)
     1858                           '<2,4~6,9'  = Spws 0,1,4,5,6,9 (all channels)
     1859                           '3:3~45;60' = channels 3 to 45 and 60 in spw 3
     1860                           '0~1:2~6,8' = channels 2 to 6 in spws 0,1, and
     1861                                         all channels in spw8
     1862                           '1.3~1.5GHz' = all spws whose central frequency
     1863                                          falls in frequency range between
     1864                                          1.3GHz and 1.5GHz.
     1865                           '1.3~1.5GHz:1.3~1.5GHz' = channels which fall
     1866                                                     between the specified
     1867                                                     frequency range in spws
     1868                                                     whose central frequency
     1869                                                     falls in the specified
     1870                                                     frequency range.
     1871                           '1:-200~250km/s' = channels that fall between the
     1872                                              specified velocity range in
     1873                                              spw 1.
     1874            restfreq: the rest frequency.
     1875                     examples: '115.2712GHz', 115271201800.0
     1876            frame:   an optional frame type, default 'LSRK'. Valid frames are:
     1877                     'TOPO', 'LSRD', 'LSRK', 'BARY',
     1878                     'GEO', 'GALACTO', 'LGROUP', 'CMB'
     1879            doppler: one of 'RADIO', 'OPTICAL', 'Z', 'BETA', 'GAMMA'
     1880        Returns:
     1881        A dictionary of selected (valid) spw and masklist pairs,
     1882        e.g. {'0': [[50,250],[350,462]], '2': [[100,400],[550,974]]}
     1883        """
     1884        if not isinstance(selectstring, str):
     1885            asaplog.post()
     1886            asaplog.push("Expression of spw/channel selection must be a string.")
     1887            asaplog.post("ERROR")
     1888
     1889        orig_unit = self.get_unit()
     1890        self.set_unit('channel')
     1891       
     1892        if restfreq is not None:
     1893            orig_molids = self._getmolidcol_list()
     1894            set_restfreq(self, restfreq)
     1895
     1896        orig_coord = self._getcoordinfo()
     1897
     1898        if frame is not None:
     1899            orig_frame = orig_coord[1]
     1900            self.set_freqframe(frame)
     1901
     1902        if doppler is not None:
     1903            orig_doppler = orig_coord[2]
     1904            self.set_doppler(doppler)
     1905       
     1906        valid_ifs = self.getifnos()
     1907
     1908        comma_sep = selectstring.split(",")
     1909        res = {}
     1910
     1911        for cms_elem in comma_sep:
     1912            colon_sep = cms_elem.split(":")
     1913           
     1914            if (len(colon_sep) > 2):
     1915                raise RuntimeError("Invalid selection expression: more than two colons!")
     1916           
     1917            # parse spw expression and store result in spw_list.
     1918            # allowed cases include '', '*', 'a', '<a', '>a', 'a~b',
     1919            # 'a~b*Hz' (where * can be '', 'k', 'M', 'G' etc.),
     1920            # 'a~b*m/s' (where * can be '' or 'k') and also
     1921            # several of the above expressions connected with ';'.
     1922           
     1923            spw_list = []
     1924
     1925            semicolon_sep = colon_sep[0].split(";")
     1926           
     1927            for scs_elem in semicolon_sep:
     1928                scs_elem = scs_elem.strip()
     1929               
     1930                lt_sep = scs_elem.split("<")
     1931                gt_sep = scs_elem.split(">")
     1932                ti_sep = scs_elem.split("~")
     1933               
     1934                lt_sep_length = len(lt_sep)
     1935                gt_sep_length = len(gt_sep)
     1936                ti_sep_length = len(ti_sep)
     1937               
     1938                len_product = lt_sep_length * gt_sep_length * ti_sep_length
     1939
     1940                if (len_product > 2):
     1941                    # '<', '>' and '~' must not coexist in a single spw expression
     1942                   
     1943                    raise RuntimeError("Invalid spw selection.")
     1944               
     1945                elif (len_product == 1):
     1946                    # '', '*', or single spw number.
     1947                   
     1948                    if (scs_elem == "") or (scs_elem == "*"):
     1949                        spw_list = valid_ifs[:] # deep copy
     1950                   
     1951                    else: # single number
     1952                        expr = int(scs_elem)
     1953                        spw_list.append(expr)
     1954                        if expr not in valid_ifs:
     1955                            asaplog.push("Invalid spw given. Ignored.")
     1956                   
     1957                else: # (len_product == 2)
     1958                    # namely, one of '<', '>' or '~' appears just once.
     1959                   
     1960                    if (lt_sep_length == 2): # '<a'
     1961                        if is_number(lt_sep[1]):
     1962                            no_valid_spw = True
     1963                            for i in valid_ifs:
     1964                                if (i < float(lt_sep[1])):
     1965                                    spw_list.append(i)
     1966                                    no_valid_spw = False
     1967
     1968                            if no_valid_spw:
     1969                                raise ValueError("Invalid spw selection ('<" + str(lt_sep[1]) + "').")
     1970                       
     1971                        else:
     1972                            raise RuntimeError("Invalid spw selection.")
     1973                       
     1974                    elif (gt_sep_length == 2): # '>a'
     1975                        if is_number(gt_sep[1]):
     1976                            no_valid_spw = True
     1977                            for i in valid_ifs:
     1978                                if (i > float(gt_sep[1])):
     1979                                    spw_list.append(i)
     1980                                    no_valid_spw = False
     1981                           
     1982                            if no_valid_spw:
     1983                                raise ValueError("Invalid spw selection ('>" + str(gt_sep[1]) + "').")
     1984                       
     1985                        else:
     1986                            raise RuntimeError("Invalid spw selection.")
     1987                       
     1988                    else: # (ti_sep_length == 2) where both boundaries inclusive
     1989                        expr0 = ti_sep[0].strip()
     1990                        expr1 = ti_sep[1].strip()
     1991
     1992                        if is_number(expr0) and is_number(expr1):
     1993                            # 'a~b'
     1994                            expr_pmin = min(float(expr0), float(expr1))
     1995                            expr_pmax = max(float(expr0), float(expr1))
     1996                            has_invalid_spw = False
     1997                            no_valid_spw = True
     1998                           
     1999                            for i in valid_ifs:
     2000                                if (expr_pmin <= i) and (i <= expr_pmax):
     2001                                    spw_list.append(i)
     2002                                    no_valid_spw = False
     2003                                else:
     2004                                    has_invalid_spw = True
     2005
     2006                            if has_invalid_spw:
     2007                                msg = "Invalid spw is given. Ignored."
     2008                                asaplog.push(msg)
     2009                                asaplog.post()
     2010
     2011                            if no_valid_spw:
     2012                                raise ValueError("No valid spw in range ('" + str(expr_pmin) + "~" + str(expr_pmax) + "').")
     2013                       
     2014                        elif is_number(expr0) and is_frequency(expr1):
     2015                            # 'a~b*Hz'
     2016                            (expr_f0, expr_f1) = get_freq_by_string(expr0, expr1)
     2017                            expr_fmin = min(expr_f0, expr_f1)
     2018                            expr_fmax = max(expr_f0, expr_f1)
     2019                            no_valid_spw = True
     2020                           
     2021                            for coord in self._get_coordinate_list():
     2022                                spw = coord['if']
     2023                               
     2024                                """
     2025                                expr_p0 = coord['coord'].to_pixel(expr_f0)
     2026                                expr_p1 = coord['coord'].to_pixel(expr_f1)
     2027                                expr_pmin = min(expr_p0, expr_p1)
     2028                                expr_pmax = max(expr_p0, expr_p1)
     2029                               
     2030                                pmin = 0.0
     2031                                pmax = float(self.nchan(spw) - 1)
     2032
     2033                                if ((expr_pmax - pmin)*(expr_pmin - pmax) <= 0.0):
     2034                                    spw_list.append(spw)
     2035                                    no_valid_spw = False
     2036                                """
     2037
     2038                                crd = coord['coord']
     2039                                fhead = crd.to_frequency(0)
     2040                                ftail = crd.to_frequency(self.nchan(spw) - 1)
     2041                                fcen  = (fhead + ftail) / 2.0
     2042
     2043                                if ((expr_fmin <= fcen) and (fcen <= expr_fmax)):
     2044                                    spw_list.append(spw)
     2045                                    no_valid_spw = False
     2046                               
     2047                            if no_valid_spw:
     2048                                raise ValueError("No valid spw in range ('" + str(expr0) + "~" + str(expr1) + "').")
     2049                               
     2050                        elif is_number(expr0) and is_velocity(expr1):
     2051                            # 'a~b*m/s'
     2052                            (expr_v0, expr_v1) = get_velocity_by_string(expr0, expr1)
     2053                            expr_vmin = min(expr_v0, expr_v1)
     2054                            expr_vmax = max(expr_v0, expr_v1)
     2055                            no_valid_spw = True
     2056                           
     2057                            for coord in self._get_coordinate_list():
     2058                                spw = coord['if']
     2059
     2060                                """
     2061                                pmin = 0.0
     2062                                pmax = float(self.nchan(spw) - 1)
     2063                               
     2064                                vel0 = coord['coord'].to_velocity(pmin)
     2065                                vel1 = coord['coord'].to_velocity(pmax)
     2066                               
     2067                                vmin = min(vel0, vel1)
     2068                                vmax = max(vel0, vel1)
     2069
     2070                                if ((expr_vmax - vmin)*(expr_vmin - vmax) <= 0.0):
     2071                                    spw_list.append(spw)
     2072                                    no_valid_spw = False
     2073                                """
     2074
     2075                                crd = coord['coord']
     2076                                fhead = crd.to_frequency(0)
     2077                                ftail = crd.to_frequency(self.nchan(spw) - 1)
     2078                                fcen  = (fhead + ftail) / 2.0
     2079                                vcen  = crd.to_velocity(crd.to_pixel(fcen))
     2080
     2081                                if ((expr_vmin <= vcen) and (vcen <= expr_vmax)):
     2082                                    spw_list.append(spw)
     2083                                    no_valid_spw = False
     2084
     2085                            if no_valid_spw:
     2086                                raise ValueError("No valid spw in range ('" + str(expr0) + "~" + str(expr1) + "').")
     2087                           
     2088                        else:
     2089                            # cases such as 'aGHz~bkm/s' are not allowed now
     2090                            raise RuntimeError("Invalid spw selection.")
     2091
     2092            # check spw list and remove invalid ones.
     2093            # if no valid spw left, emit ValueError.
     2094            if len(spw_list) == 0:
     2095                raise ValueError("No valid spw in given range.")
     2096           
     2097            # parse channel expression and store the result in crange_list.
     2098            # allowed cases include '', 'a~b', 'a*Hz~b*Hz' (where * can be
     2099            # '', 'k', 'M', 'G' etc.), 'a*m/s~b*m/s' (where * can be '' or 'k')
     2100            # and also several of the above expressions connected with ';'.
     2101           
     2102            for spw in spw_list:
     2103                pmin = 0.0
     2104                pmax = float(self.nchan(spw) - 1)
     2105
     2106                molid = self._getmolidcol_list()[self.get_first_rowno_by_if(spw)]
     2107               
     2108                if (len(colon_sep) == 1):
     2109                    # no expression for channel selection,
     2110                    # which means all channels are to be selected.
     2111                    crange_list = [[pmin, pmax]]
     2112               
     2113                else: # (len(colon_sep) == 2)
     2114                    crange_list = []
     2115                   
     2116                    found = False
     2117                    for i in self._get_coordinate_list():
     2118                        if (i['if'] == spw):
     2119                            coord = i['coord']
     2120                            found = True
     2121                            break
     2122
     2123                    if found:
     2124                        semicolon_sep = colon_sep[1].split(";")
     2125                        for scs_elem in semicolon_sep:
     2126                            scs_elem = scs_elem.strip()
     2127
     2128                            ti_sep = scs_elem.split("~")
     2129                            ti_sep_length = len(ti_sep)
     2130
     2131                            if (ti_sep_length > 2):
     2132                                raise RuntimeError("Invalid channel selection.")
     2133                       
     2134                            elif (ti_sep_length == 1):
     2135                                if (scs_elem == "") or (scs_elem == "*"):
     2136                                    # '' and '*' for all channels
     2137                                    crange_list = [[pmin, pmax]]
     2138                                    break
     2139                                elif (is_number(scs_elem)):
     2140                                    # single channel given
     2141                                    crange_list.append([float(scs_elem), float(scs_elem)])
     2142                                else:
     2143                                    raise RuntimeError("Invalid channel selection.")
     2144
     2145                            else: #(ti_sep_length == 2)
     2146                                expr0 = ti_sep[0].strip()
     2147                                expr1 = ti_sep[1].strip()
     2148
     2149                                if is_number(expr0) and is_number(expr1):
     2150                                    # 'a~b'
     2151                                    expr_pmin = min(float(expr0), float(expr1))
     2152                                    expr_pmax = max(float(expr0), float(expr1))
     2153
     2154                                elif is_number(expr0) and is_frequency(expr1):
     2155                                    # 'a~b*Hz'
     2156                                    (expr_f0, expr_f1) = get_freq_by_string(expr0, expr1)
     2157                                    expr_p0 = coord.to_pixel(expr_f0)
     2158                                    expr_p1 = coord.to_pixel(expr_f1)
     2159                                    expr_pmin = min(expr_p0, expr_p1)
     2160                                    expr_pmax = max(expr_p0, expr_p1)
     2161
     2162                                elif is_number(expr0) and is_velocity(expr1):
     2163                                    # 'a~b*m/s'
     2164                                    restf = self.get_restfreqs()[molid][0]
     2165                                    (expr_v0, expr_v1) = get_velocity_by_string(expr0, expr1)
     2166                                    dppl = self.get_doppler()
     2167                                    expr_f0 = get_frequency_by_velocity(restf, expr_v0, dppl)
     2168                                    expr_f1 = get_frequency_by_velocity(restf, expr_v1, dppl)
     2169                                    expr_p0 = coord.to_pixel(expr_f0)
     2170                                    expr_p1 = coord.to_pixel(expr_f1)
     2171                                    expr_pmin = min(expr_p0, expr_p1)
     2172                                    expr_pmax = max(expr_p0, expr_p1)
     2173                           
     2174                                else:
     2175                                    # cases such as 'aGHz~bkm/s' are not allowed now
     2176                                    raise RuntimeError("Invalid channel selection.")
     2177
     2178                                cmin = max(pmin, expr_pmin)
     2179                                cmax = min(pmax, expr_pmax)
     2180                                # if the given range of channel selection has overwrap with
     2181                                # that of current spw, output the overwrap area.
     2182                                if (cmin <= cmax):
     2183                                    cmin = float(int(cmin + 0.5))
     2184                                    cmax = float(int(cmax + 0.5))
     2185                                    crange_list.append([cmin, cmax])
     2186
     2187                    if (len(crange_list) == 0):
     2188                        crange_list.append([])
     2189
     2190                if (len(crange_list[0]) > 0):
     2191                    if res.has_key(spw):
     2192                        res[spw].extend(crange_list)
     2193                    else:
     2194                        res[spw] = crange_list
     2195
     2196        for spw in res.keys():
     2197            if spw in valid_ifs:
     2198                # remove duplicated channel ranges
     2199                for i in reversed(xrange(len(res[spw]))):
     2200                    for j in xrange(i):
     2201                        if ((res[spw][i][0]-res[spw][j][1])*(res[spw][i][1]-res[spw][j][0]) <= 0) or \
     2202                            (min(abs(res[spw][i][0]-res[spw][j][1]),abs(res[spw][j][0]-res[spw][i][1])) == 1):
     2203                            asaplog.post()
     2204                            merge_warn_mesg = "Spw " + str(spw) + ": overwrapping channel ranges are merged."
     2205                            asaplog.push(merge_warn_mesg)
     2206                            asaplog.post('WARN')
     2207                            res[spw][j][0] = min(res[spw][i][0], res[spw][j][0])
     2208                            res[spw][j][1] = max(res[spw][i][1], res[spw][j][1])
     2209                            res[spw].pop(i)
     2210                            break
     2211            else:
     2212                del res[spw]
     2213
     2214        if len(res) == 0:
     2215            raise RuntimeError("No valid spw.")
     2216       
     2217        # restore original values
     2218        self.set_unit(orig_unit)
     2219        if restfreq is not None:
     2220            self._setmolidcol_list(orig_molids)
     2221        if frame is not None:
     2222            self.set_freqframe(orig_frame)
     2223        if doppler is not None:
     2224            self.set_doppler(orig_doppler)
     2225       
     2226        return res
     2227   
     2228    @asaplog_post_dec
     2229    def get_first_rowno_by_if(self, ifno):
     2230        found = False
     2231        for irow in xrange(self.nrow()):
     2232            if (self.getif(irow) == ifno):
     2233                res = irow
     2234                found = True
     2235                break
     2236
     2237        if not found: raise RuntimeError("No valid spw.")
     2238       
     2239        return res
     2240
     2241    @asaplog_post_dec
     2242    def _get_coordinate_list(self):
     2243        res = []
     2244        spws = self.getifnos()
     2245        for spw in spws:
     2246            elem = {}
     2247            elem['if']    = spw
     2248            elem['coord'] = self.get_coordinate(self.get_first_rowno_by_if(spw))
     2249            res.append(elem)
     2250
     2251        return res
     2252   
     2253    @asaplog_post_dec
    14732254    def parse_maskexpr(self, maskstring):
    14742255        """
     
    15012282            maskstring = str(valid_ifs)[1:-1]
    15022283        ## split each selection "IF range[:CHAN range]"
    1503         sellist = maskstring.split(',')
     2284        # split maskstring by "<spaces>,<spaces>"
     2285        comma_sep = re.compile('\s*,\s*')
     2286        sellist = comma_sep.split(maskstring)
     2287        # separator by "<spaces>:<spaces>"
     2288        collon_sep = re.compile('\s*:\s*')
    15042289        for currselstr in sellist:
    1505             selset = currselstr.split(':')
     2290            selset = collon_sep.split(currselstr)
    15062291            # spw and mask string (may include ~, < or >)
    15072292            spwmasklist = self._parse_selection(selset[0], typestr='integer',
     
    16372422        if smode == 'r':
    16382423            minidx = 0
    1639             maxidx = self.nrow()
     2424            maxidx = self.nrow()-1
    16402425        else:
    16412426            idx = getattr(self,"get"+mode+"nos")()
     
    16432428            maxidx = max(idx)
    16442429            del idx
    1645         sellist = selexpr.split(',')
     2430        # split selexpr by "<spaces>,<spaces>"
     2431        comma_sep = re.compile('\s*,\s*')
     2432        sellist = comma_sep.split(selexpr)
    16462433        idxlist = []
    16472434        for currselstr in sellist:
     
    16512438            for thelist in currlist:
    16522439                idxlist += range(thelist[0],thelist[1]+1)
     2440        # remove duplicated elements after first ones
     2441        for i in reversed(xrange(len(idxlist))):
     2442            if idxlist.index(idxlist[i]) < i:
     2443                idxlist.pop(i)
     2444
     2445        # remove elements outside range [minidx, maxidx] for smode='r'
     2446        if smode == 'r':
     2447            for i in reversed(xrange(len(idxlist))):
     2448                if (idxlist[i] < minidx) or (idxlist[i] > maxidx):
     2449                    idxlist.pop(i)
     2450       
    16532451        msg = "Selected %s: %s" % (mode.upper()+"NO", str(idxlist))
    16542452        asaplog.push(msg)
     
    16762474            --> returns [[0.,2.5],[5.0,7.0],[9.,9.]]
    16772475        """
    1678         selgroups = selstr.split(';')
     2476        # split selstr by '<spaces>;<spaces>'
     2477        semi_sep = re.compile('\s*;\s*')
     2478        selgroups = semi_sep.split(selstr)
    16792479        sellists = []
    16802480        if typestr.lower().startswith('int'):
     
    16852485       
    16862486        for currsel in  selgroups:
     2487            if currsel.strip() == '*' or len(currsel.strip()) == 0:
     2488                minsel = minval
     2489                maxsel = maxval
    16872490            if currsel.find('~') > 0:
    16882491                # val0 <= x <= val1
    16892492                minsel = formatfunc(currsel.split('~')[0].strip())
    1690                 maxsel = formatfunc(currsel.split('~')[1].strip()) 
     2493                maxsel = formatfunc(currsel.split('~')[1].strip())
    16912494            elif currsel.strip().find('<=') > -1:
    16922495                bound = currsel.split('<=')
     
    19072710
    19082711    @asaplog_post_dec
    1909     def history(self, filename=None):
     2712    def history(self, filename=None, nrows=-1, start=0):
    19102713        """\
    19112714        Print the history. Optionally to a file.
     
    19162719
    19172720        """
    1918         hist = list(self._gethistory())
     2721        n = self._historylength()
     2722        if nrows == -1:
     2723            nrows = n
     2724        if start+nrows > n:
     2725            nrows = nrows-start
     2726        if n > 1000 and nrows == n:
     2727            nrows = 1000
     2728            start = n-1000
     2729            asaplog.push("Warning: History has {0} entries. Displaying last "
     2730                         "1000".format(n))
     2731        hist = list(self._gethistory(nrows, start))
    19192732        out = "-"*80
    19202733        for h in hist:
    1921             if h.startswith("---"):
    1922                 out = "\n".join([out, h])
     2734            if not h.strip():
     2735                continue
     2736            if h.find("---") >-1:
     2737                continue
    19232738            else:
    19242739                items = h.split("##")
     
    19332748                    s = i.split("=")
    19342749                    out += "\n   %s = %s" % (s[0], s[1])
    1935                 out = "\n".join([out, "-"*80])
     2750                out = "\n".join([out, "*"*80])
    19362751        if filename is not None:
    19372752            if filename is "":
    19382753                filename = 'scantable_history.txt'
    1939             import os
    19402754            filename = os.path.expandvars(os.path.expanduser(filename))
    19412755            if not os.path.isdir(filename):
     
    19522766    #
    19532767    @asaplog_post_dec
    1954     def average_time(self, mask=None, scanav=False, weight='tint', align=False):
     2768    def average_time(self, mask=None, scanav=False, weight='tint', align=False,
     2769                     avmode="NONE"):
    19552770        """\
    19562771        Return the (time) weighted average of a scan. Scans will be averaged
     
    19802795            align:    align the spectra in velocity before averaging. It takes
    19812796                      the time of the first spectrum as reference time.
     2797            avmode:   'SOURCE' - also select by source name -  or
     2798                      'NONE' (default). Not applicable for scanav=True or
     2799                      weight=median
    19822800
    19832801        Example::
     
    19902808        weight = weight or 'TINT'
    19912809        mask = mask or ()
    1992         scanav = (scanav and 'SCAN') or 'NONE'
     2810        scanav = (scanav and 'SCAN') or avmode.upper()
    19932811        scan = (self, )
    19942812
    19952813        if align:
    19962814            scan = (self.freq_align(insitu=False), )
     2815            asaplog.push("Note: Alignment is don on a source-by-source basis")
     2816            asaplog.push("Note: Averaging (by default) is not")
     2817            # we need to set it to SOURCE averaging here           
    19972818        s = None
    19982819        if weight.upper() == 'MEDIAN':
     
    25393360            raise RuntimeError(msg)
    25403361
    2541 
    2542     @asaplog_post_dec
    2543     def sinusoid_baseline(self, insitu=None, mask=None, applyfft=None,
     3362    @asaplog_post_dec
     3363    def apply_bltable(self, insitu=None, retfitres=None, inbltable=None, outbltable=None, overwrite=None):
     3364        """\
     3365        Subtract baseline based on parameters written in Baseline Table.
     3366
     3367        Parameters:
     3368            insitu:        if True, baseline fitting/subtraction is done
     3369                           in-situ. If False, a new scantable with
     3370                           baseline subtracted is returned. Actually,
     3371                           format of the returned value depends on both
     3372                           insitu and retfitres (see below).
     3373                           The default is taken from .asaprc (False)
     3374            retfitres:     if True, the results of baseline fitting (i.e.,
     3375                           coefficients and rms) are returned.
     3376                           default is False.
     3377                           The format of the returned value of this
     3378                           function varies as follows:
     3379                           (1) in case insitu=True and retfitres=True:
     3380                               fitting result.
     3381                           (2) in case insitu=True and retfitres=False:
     3382                               None.
     3383                           (3) in case insitu=False and retfitres=True:
     3384                               a dictionary containing a new scantable
     3385                               (with baseline subtracted) and the fitting
     3386                               results.
     3387                           (4) in case insitu=False and retfitres=False:
     3388                               a new scantable (with baseline subtracted).
     3389            inbltable:     name of input baseline table. The row number of
     3390                           scantable and that of inbltable must be
     3391                           identical.
     3392            outbltable:    name of output baseline table where baseline
     3393                           parameters and fitting results recorded.
     3394                           default is ''(no output).
     3395            overwrite:     if True when an existing baseline table is
     3396                           specified for outbltable, overwrites it.
     3397                           Otherwise there is no harm.
     3398                           default is False.
     3399        """
     3400
     3401        try:
     3402            varlist = vars()
     3403            if retfitres      is None: retfitres      = False
     3404            if inbltable      is None: raise ValueError("bltable missing.")
     3405            if outbltable     is None: outbltable     = ''
     3406            if overwrite      is None: overwrite      = False
     3407
     3408            if insitu is None: insitu = rcParams['insitu']
     3409            if insitu:
     3410                workscan = self
     3411            else:
     3412                workscan = self.copy()
     3413
     3414            sres = workscan._apply_bltable(inbltable,
     3415                                           retfitres,
     3416                                           outbltable,
     3417                                           os.path.exists(outbltable),
     3418                                           overwrite)
     3419            if retfitres: res = parse_fitresult(sres)
     3420
     3421            workscan._add_history('apply_bltable', varlist)
     3422
     3423            if insitu:
     3424                self._assign(workscan)
     3425                if retfitres:
     3426                    return res
     3427                else:
     3428                    return None
     3429            else:
     3430                if retfitres:
     3431                    return {'scantable': workscan, 'fitresults': res}
     3432                else:
     3433                    return workscan
     3434       
     3435        except RuntimeError, e:
     3436            raise_fitting_failure_exception(e)
     3437
     3438    @asaplog_post_dec
     3439    def sub_baseline(self, insitu=None, retfitres=None, blinfo=None, bltable=None, overwrite=None):
     3440        """\
     3441        Subtract baseline based on parameters written in the input list.
     3442
     3443        Parameters:
     3444            insitu:        if True, baseline fitting/subtraction is done
     3445                           in-situ. If False, a new scantable with
     3446                           baseline subtracted is returned. Actually,
     3447                           format of the returned value depends on both
     3448                           insitu and retfitres (see below).
     3449                           The default is taken from .asaprc (False)
     3450            retfitres:     if True, the results of baseline fitting (i.e.,
     3451                           coefficients and rms) are returned.
     3452                           default is False.
     3453                           The format of the returned value of this
     3454                           function varies as follows:
     3455                           (1) in case insitu=True and retfitres=True:
     3456                               fitting result.
     3457                           (2) in case insitu=True and retfitres=False:
     3458                               None.
     3459                           (3) in case insitu=False and retfitres=True:
     3460                               a dictionary containing a new scantable
     3461                               (with baseline subtracted) and the fitting
     3462                               results.
     3463                           (4) in case insitu=False and retfitres=False:
     3464                               a new scantable (with baseline subtracted).
     3465            blinfo:        baseline parameter set stored in a dictionary
     3466                           or a list of dictionary. Each dictionary
     3467                           corresponds to each spectrum and must contain
     3468                           the following keys and values:
     3469                             'row': row number,
     3470                             'blfunc': function name. available ones include
     3471                                       'poly', 'chebyshev', 'cspline' and
     3472                                       'sinusoid',
     3473                             'order': maximum order of polynomial. needed
     3474                                      if blfunc='poly' or 'chebyshev',
     3475                             'npiece': number or piecewise polynomial.
     3476                                       needed if blfunc='cspline',
     3477                             'nwave': a list of sinusoidal wave numbers.
     3478                                      needed if blfunc='sinusoid', and
     3479                             'masklist': min-max windows for channel mask.
     3480                                         the specified ranges will be used
     3481                                         for fitting.
     3482            bltable:       name of output baseline table where baseline
     3483                           parameters and fitting results recorded.
     3484                           default is ''(no output).
     3485            overwrite:     if True when an existing baseline table is
     3486                           specified for bltable, overwrites it.
     3487                           Otherwise there is no harm.
     3488                           default is False.
     3489                           
     3490        Example:
     3491            sub_baseline(blinfo=[{'row':0, 'blfunc':'poly', 'order':5,
     3492                                  'masklist':[[10,350],[352,510]]},
     3493                                 {'row':1, 'blfunc':'cspline', 'npiece':3,
     3494                                  'masklist':[[3,16],[19,404],[407,511]]}
     3495                                  ])
     3496
     3497                the first spectrum (row=0) will be fitted with polynomial
     3498                of order=5 and the next one (row=1) will be fitted with cubic
     3499                spline consisting of 3 pieces.
     3500        """
     3501
     3502        try:
     3503            varlist = vars()
     3504            if retfitres      is None: retfitres      = False
     3505            if blinfo         is None: blinfo         = []
     3506            if bltable        is None: bltable        = ''
     3507            if overwrite      is None: overwrite      = False
     3508
     3509            if insitu is None: insitu = rcParams['insitu']
     3510            if insitu:
     3511                workscan = self
     3512            else:
     3513                workscan = self.copy()
     3514
     3515            nrow = workscan.nrow()
     3516
     3517            in_blinfo = pack_blinfo(blinfo=blinfo, maxirow=nrow)
     3518
     3519            sres = workscan._sub_baseline(in_blinfo,
     3520                                          retfitres,
     3521                                          bltable,
     3522                                          os.path.exists(bltable),
     3523                                          overwrite)
     3524            if retfitres: res = parse_fitresult(sres)
     3525           
     3526            workscan._add_history('sub_baseline', varlist)
     3527
     3528            if insitu:
     3529                self._assign(workscan)
     3530                if retfitres:
     3531                    return res
     3532                else:
     3533                    return None
     3534            else:
     3535                if retfitres:
     3536                    return {'scantable': workscan, 'fitresults': res}
     3537                else:
     3538                    return workscan
     3539
     3540        except RuntimeError, e:
     3541            raise_fitting_failure_exception(e)
     3542
     3543    @asaplog_post_dec
     3544    def calc_aic(self, value=None, blfunc=None, order=None, mask=None,
     3545                 whichrow=None, uselinefinder=None, edge=None,
     3546                 threshold=None, chan_avg_limit=None):
     3547        """\
     3548        Calculates and returns model selection criteria for a specified
     3549        baseline model and a given spectrum data.
     3550        Available values include Akaike Information Criterion (AIC), the
     3551        corrected Akaike Information Criterion (AICc) by Sugiura(1978),
     3552        Bayesian Information Criterion (BIC) and the Generalised Cross
     3553        Validation (GCV).
     3554
     3555        Parameters:
     3556            value:         name of model selection criteria to calculate.
     3557                           available ones include 'aic', 'aicc', 'bic' and
     3558                           'gcv'. default is 'aicc'.
     3559            blfunc:        baseline function name. available ones include
     3560                           'chebyshev', 'cspline' and 'sinusoid'.
     3561                           default is 'chebyshev'.
     3562            order:         parameter for basline function. actually stands for
     3563                           order of polynomial (order) for 'chebyshev',
     3564                           number of spline pieces (npiece) for 'cspline' and
     3565                           maximum wave number for 'sinusoid', respectively.
     3566                           default is 5 (which is also the default order value
     3567                           for [auto_]chebyshev_baseline()).
     3568            mask:          an optional mask. default is [].
     3569            whichrow:      row number. default is 0 (the first row)
     3570            uselinefinder: use sd.linefinder() to flag out line regions
     3571                           default is True.
     3572            edge:           an optional number of channel to drop at
     3573                            the edge of spectrum. If only one value is
     3574                            specified, the same number will be dropped
     3575                            from both sides of the spectrum. Default
     3576                            is to keep all channels. Nested tuples
     3577                            represent individual edge selection for
     3578                            different IFs (a number of spectral channels
     3579                            can be different)
     3580                            default is (0, 0).
     3581            threshold:      the threshold used by line finder. It is
     3582                            better to keep it large as only strong lines
     3583                            affect the baseline solution.
     3584                            default is 3.
     3585            chan_avg_limit: a maximum number of consequtive spectral
     3586                            channels to average during the search of
     3587                            weak and broad lines. The default is no
     3588                            averaging (and no search for weak lines).
     3589                            If such lines can affect the fitted baseline
     3590                            (e.g. a high order polynomial is fitted),
     3591                            increase this parameter (usually values up
     3592                            to 8 are reasonable). Most users of this
     3593                            method should find the default value sufficient.
     3594                            default is 1.
     3595
     3596        Example:
     3597            aic = scan.calc_aic(blfunc='chebyshev', order=5, whichrow=0)
     3598        """
     3599
     3600        try:
     3601            varlist = vars()
     3602
     3603            if value          is None: value          = 'aicc'
     3604            if blfunc         is None: blfunc         = 'chebyshev'
     3605            if order          is None: order          = 5
     3606            if mask           is None: mask           = []
     3607            if whichrow       is None: whichrow       = 0
     3608            if uselinefinder  is None: uselinefinder  = True
     3609            if edge           is None: edge           = (0, 0)
     3610            if threshold      is None: threshold      = 3
     3611            if chan_avg_limit is None: chan_avg_limit = 1
     3612
     3613            return self._calc_aic(value, blfunc, order, mask,
     3614                                  whichrow, uselinefinder, edge,
     3615                                  threshold, chan_avg_limit)
     3616           
     3617        except RuntimeError, e:
     3618            raise_fitting_failure_exception(e)
     3619
     3620    @asaplog_post_dec
     3621    def sinusoid_baseline(self, mask=None, applyfft=None,
    25443622                          fftmethod=None, fftthresh=None,
    2545                           addwn=None, rejwn=None, clipthresh=None,
    2546                           clipniter=None, plot=None,
    2547                           getresidual=None, showprogress=None,
    2548                           minnrow=None, outlog=None, blfile=None, csvformat=None):
     3623                          addwn=None, rejwn=None,
     3624                          insitu=None,
     3625                          clipthresh=None, clipniter=None,
     3626                          plot=None,
     3627                          getresidual=None,
     3628                          showprogress=None, minnrow=None,
     3629                          outlog=None,
     3630                          blfile=None, csvformat=None,
     3631                          bltable=None):
    25493632        """\
    25503633        Return a scan which has been baselined (all rows) with sinusoidal
     
    25523635
    25533636        Parameters:
    2554             insitu:        if False a new scantable is returned.
    2555                            Otherwise, the scaling is done in-situ
    2556                            The default is taken from .asaprc (False)
    25573637            mask:          an optional mask
    25583638            applyfft:      if True use some method, such as FFT, to find
     
    25863666                           wave numbers which are specified both in addwn
    25873667                           and rejwn will NOT be used. default is [].
     3668            insitu:        if False a new scantable is returned.
     3669                           Otherwise, the scaling is done in-situ
     3670                           The default is taken from .asaprc (False)
    25883671            clipthresh:    Clipping threshold. (default is 3.0, unit: sigma)
    25893672            clipniter:     maximum number of iteration of 'clipthresh'-sigma
     
    26053688                           (default is '': no file/logger output)
    26063689            csvformat:     if True blfile is csv-formatted, default is False.
     3690            bltable:       name of a baseline table where fitting results
     3691                           (coefficients, rms, etc.) are to be written.
     3692                           if given, fitting results will NOT be output to
     3693                           scantable (insitu=True) or None will be
     3694                           returned (insitu=False).
     3695                           (default is "": no table output)
    26073696
    26083697        Example:
     
    26263715                workscan = self.copy()
    26273716           
    2628             #if mask          is None: mask          = [True for i in xrange(workscan.nchan())]
    26293717            if mask          is None: mask          = []
    26303718            if applyfft      is None: applyfft      = True
     
    26423730            if blfile        is None: blfile        = ''
    26433731            if csvformat     is None: csvformat     = False
    2644 
    2645             if csvformat:
    2646                 scsvformat = "T"
    2647             else:
    2648                 scsvformat = "F"
     3732            if bltable       is None: bltable       = ''
     3733
     3734            sapplyfft = 'true' if applyfft else 'false'
     3735            fftinfo = ','.join([sapplyfft, fftmethod.lower(), str(fftthresh).lower()])
     3736
     3737            scsvformat = 'T' if csvformat else 'F'
    26493738
    26503739            #CURRENTLY, PLOT=true is UNAVAILABLE UNTIL sinusoidal fitting is implemented as a fitter method.
    2651             workscan._sinusoid_baseline(mask, applyfft, fftmethod.lower(),
    2652                                         str(fftthresh).lower(),
     3740            workscan._sinusoid_baseline(mask,
     3741                                        fftinfo,
     3742                                        #applyfft, fftmethod.lower(),
     3743                                        #str(fftthresh).lower(),
    26533744                                        workscan._parse_wn(addwn),
    26543745                                        workscan._parse_wn(rejwn),
     
    26573748                                        pack_progress_params(showprogress,
    26583749                                                             minnrow),
    2659                                         outlog, scsvformat+blfile)
     3750                                        outlog, scsvformat+blfile,
     3751                                        bltable)
    26603752            workscan._add_history('sinusoid_baseline', varlist)
    2661            
    2662             if insitu:
    2663                 self._assign(workscan)
     3753
     3754            if bltable == '':
     3755                if insitu:
     3756                    self._assign(workscan)
     3757                else:
     3758                    return workscan
    26643759            else:
    2665                 return workscan
     3760                if not insitu:
     3761                    return None
    26663762           
    26673763        except RuntimeError, e:
     
    26703766
    26713767    @asaplog_post_dec
    2672     def auto_sinusoid_baseline(self, insitu=None, mask=None, applyfft=None,
     3768    def auto_sinusoid_baseline(self, mask=None, applyfft=None,
    26733769                               fftmethod=None, fftthresh=None,
    2674                                addwn=None, rejwn=None, clipthresh=None,
    2675                                clipniter=None, edge=None, threshold=None,
    2676                                chan_avg_limit=None, plot=None,
    2677                                getresidual=None, showprogress=None,
    2678                                minnrow=None, outlog=None, blfile=None, csvformat=None):
     3770                               addwn=None, rejwn=None,
     3771                               insitu=None,
     3772                               clipthresh=None, clipniter=None,
     3773                               edge=None, threshold=None, chan_avg_limit=None,
     3774                               plot=None,
     3775                               getresidual=None,
     3776                               showprogress=None, minnrow=None,
     3777                               outlog=None,
     3778                               blfile=None, csvformat=None,
     3779                               bltable=None):
    26793780        """\
    26803781        Return a scan which has been baselined (all rows) with sinusoidal
     
    26843785
    26853786        Parameters:
    2686             insitu:         if False a new scantable is returned.
    2687                             Otherwise, the scaling is done in-situ
    2688                             The default is taken from .asaprc (False)
    26893787            mask:           an optional mask retreived from scantable
    26903788            applyfft:       if True use some method, such as FFT, to find
     
    27183816                            wave numbers which are specified both in addwn
    27193817                            and rejwn will NOT be used. default is [].
     3818            insitu:         if False a new scantable is returned.
     3819                            Otherwise, the scaling is done in-situ
     3820                            The default is taken from .asaprc (False)
    27203821            clipthresh:     Clipping threshold. (default is 3.0, unit: sigma)
    27213822            clipniter:      maximum number of iteration of 'clipthresh'-sigma
     
    27573858                            (default is "": no file/logger output)
    27583859            csvformat:      if True blfile is csv-formatted, default is False.
     3860            bltable:        name of a baseline table where fitting results
     3861                            (coefficients, rms, etc.) are to be written.
     3862                            if given, fitting results will NOT be output to
     3863                            scantable (insitu=True) or None will be
     3864                            returned (insitu=False).
     3865                            (default is "": no table output)
    27593866
    27603867        Example:
     
    27753882                workscan = self.copy()
    27763883           
    2777             #if mask           is None: mask           = [True for i in xrange(workscan.nchan())]
    27783884            if mask           is None: mask           = []
    27793885            if applyfft       is None: applyfft       = True
     
    27943900            if blfile         is None: blfile         = ''
    27953901            if csvformat      is None: csvformat      = False
    2796 
    2797             if csvformat:
    2798                 scsvformat = "T"
    2799             else:
    2800                 scsvformat = "F"
     3902            if bltable        is None: bltable        = ''
     3903
     3904            sapplyfft = 'true' if applyfft else 'false'
     3905            fftinfo = ','.join([sapplyfft, fftmethod.lower(), str(fftthresh).lower()])
     3906
     3907            scsvformat = 'T' if csvformat else 'F'
    28013908
    28023909            #CURRENTLY, PLOT=true is UNAVAILABLE UNTIL sinusoidal fitting is implemented as a fitter method.
    2803             workscan._auto_sinusoid_baseline(mask, applyfft,
    2804                                              fftmethod.lower(),
    2805                                              str(fftthresh).lower(),
     3910            workscan._auto_sinusoid_baseline(mask,
     3911                                             fftinfo,
    28063912                                             workscan._parse_wn(addwn),
    28073913                                             workscan._parse_wn(rejwn),
     
    28123918                                             pack_progress_params(showprogress,
    28133919                                                                  minnrow),
    2814                                              outlog, scsvformat+blfile)
     3920                                             outlog, scsvformat+blfile, bltable)
    28153921            workscan._add_history("auto_sinusoid_baseline", varlist)
    2816            
    2817             if insitu:
    2818                 self._assign(workscan)
     3922
     3923            if bltable == '':
     3924                if insitu:
     3925                    self._assign(workscan)
     3926                else:
     3927                    return workscan
    28193928            else:
    2820                 return workscan
     3929                if not insitu:
     3930                    return None
    28213931           
    28223932        except RuntimeError, e:
     
    28243934
    28253935    @asaplog_post_dec
    2826     def cspline_baseline(self, insitu=None, mask=None, npiece=None,
     3936    def cspline_baseline(self, mask=None, npiece=None, insitu=None,
    28273937                         clipthresh=None, clipniter=None, plot=None,
    28283938                         getresidual=None, showprogress=None, minnrow=None,
    2829                          outlog=None, blfile=None, csvformat=None):
     3939                         outlog=None, blfile=None, csvformat=None,
     3940                         bltable=None):
    28303941        """\
    28313942        Return a scan which has been baselined (all rows) by cubic spline
     
    28333944
    28343945        Parameters:
     3946            mask:         An optional mask
     3947            npiece:       Number of pieces. (default is 2)
    28353948            insitu:       If False a new scantable is returned.
    28363949                          Otherwise, the scaling is done in-situ
    28373950                          The default is taken from .asaprc (False)
    2838             mask:         An optional mask
    2839             npiece:       Number of pieces. (default is 2)
    28403951            clipthresh:   Clipping threshold. (default is 3.0, unit: sigma)
    28413952            clipniter:    maximum number of iteration of 'clipthresh'-sigma
     
    28573968                          (default is "": no file/logger output)
    28583969            csvformat:    if True blfile is csv-formatted, default is False.
     3970            bltable:      name of a baseline table where fitting results
     3971                          (coefficients, rms, etc.) are to be written.
     3972                          if given, fitting results will NOT be output to
     3973                          scantable (insitu=True) or None will be
     3974                          returned (insitu=False).
     3975                          (default is "": no table output)
    28593976
    28603977        Example:
     
    28783995                workscan = self.copy()
    28793996
    2880             #if mask         is None: mask         = [True for i in xrange(workscan.nchan())]
    28813997            if mask         is None: mask         = []
    28823998            if npiece       is None: npiece       = 2
     
    28894005            if outlog       is None: outlog       = False
    28904006            if blfile       is None: blfile       = ''
    2891             if csvformat     is None: csvformat     = False
    2892 
    2893             if csvformat:
    2894                 scsvformat = "T"
    2895             else:
    2896                 scsvformat = "F"
     4007            if csvformat    is None: csvformat    = False
     4008            if bltable      is None: bltable      = ''
     4009
     4010            scsvformat = 'T' if csvformat else 'F'
    28974011
    28984012            #CURRENTLY, PLOT=true UNAVAILABLE UNTIL cubic spline fitting is implemented as a fitter method.
    2899             workscan._cspline_baseline(mask, npiece, clipthresh, clipniter,
     4013            workscan._cspline_baseline(mask, npiece,
     4014                                       clipthresh, clipniter,
    29004015                                       getresidual,
    29014016                                       pack_progress_params(showprogress,
    29024017                                                            minnrow),
    2903                                        outlog, scsvformat+blfile)
     4018                                       outlog, scsvformat+blfile,
     4019                                       bltable)
    29044020            workscan._add_history("cspline_baseline", varlist)
    2905            
    2906             if insitu:
    2907                 self._assign(workscan)
     4021
     4022            if bltable == '':
     4023                if insitu:
     4024                    self._assign(workscan)
     4025                else:
     4026                    return workscan
    29084027            else:
    2909                 return workscan
     4028                if not insitu:
     4029                    return None
    29104030           
    29114031        except RuntimeError, e:
     
    29134033
    29144034    @asaplog_post_dec
    2915     def auto_cspline_baseline(self, insitu=None, mask=None, npiece=None,
     4035    def auto_cspline_baseline(self, mask=None, npiece=None, insitu=None,
    29164036                              clipthresh=None, clipniter=None,
    29174037                              edge=None, threshold=None, chan_avg_limit=None,
    29184038                              getresidual=None, plot=None,
    29194039                              showprogress=None, minnrow=None, outlog=None,
    2920                               blfile=None, csvformat=None):
     4040                              blfile=None, csvformat=None, bltable=None):
    29214041        """\
    29224042        Return a scan which has been baselined (all rows) by cubic spline
     
    29264046
    29274047        Parameters:
     4048            mask:           an optional mask retreived from scantable
     4049            npiece:         Number of pieces. (default is 2)
    29284050            insitu:         if False a new scantable is returned.
    29294051                            Otherwise, the scaling is done in-situ
    29304052                            The default is taken from .asaprc (False)
    2931             mask:           an optional mask retreived from scantable
    2932             npiece:         Number of pieces. (default is 2)
    29334053            clipthresh:     Clipping threshold. (default is 3.0, unit: sigma)
    29344054            clipniter:      maximum number of iteration of 'clipthresh'-sigma
     
    29704090                            (default is "": no file/logger output)
    29714091            csvformat:      if True blfile is csv-formatted, default is False.
     4092            bltable:        name of a baseline table where fitting results
     4093                            (coefficients, rms, etc.) are to be written.
     4094                            if given, fitting results will NOT be output to
     4095                            scantable (insitu=True) or None will be
     4096                            returned (insitu=False).
     4097                            (default is "": no table output)
    29724098
    29734099        Example:
     
    30034129            if blfile         is None: blfile         = ''
    30044130            if csvformat      is None: csvformat      = False
    3005 
    3006             if csvformat:
    3007                 scsvformat = "T"
    3008             else:
    3009                 scsvformat = "F"
     4131            if bltable        is None: bltable        = ''
     4132
     4133            scsvformat = 'T' if csvformat else 'F'
    30104134
    30114135            #CURRENTLY, PLOT=true UNAVAILABLE UNTIL cubic spline fitting is implemented as a fitter method.
    3012             workscan._auto_cspline_baseline(mask, npiece, clipthresh,
    3013                                             clipniter,
     4136            workscan._auto_cspline_baseline(mask, npiece,
     4137                                            clipthresh, clipniter,
    30144138                                            normalise_edge_param(edge),
    30154139                                            threshold,
     
    30174141                                            pack_progress_params(showprogress,
    30184142                                                                 minnrow),
    3019                                             outlog, scsvformat+blfile)
     4143                                            outlog,
     4144                                            scsvformat+blfile,
     4145                                            bltable)
    30204146            workscan._add_history("auto_cspline_baseline", varlist)
    3021            
    3022             if insitu:
    3023                 self._assign(workscan)
     4147
     4148            if bltable == '':
     4149                if insitu:
     4150                    self._assign(workscan)
     4151                else:
     4152                    return workscan
    30244153            else:
    3025                 return workscan
     4154                if not insitu:
     4155                    return None
    30264156           
    30274157        except RuntimeError, e:
     
    30294159
    30304160    @asaplog_post_dec
    3031     def chebyshev_baseline(self, insitu=None, mask=None, order=None,
     4161    def chebyshev_baseline(self, mask=None, order=None, insitu=None,
    30324162                           clipthresh=None, clipniter=None, plot=None,
    30334163                           getresidual=None, showprogress=None, minnrow=None,
    3034                            outlog=None, blfile=None, csvformat=None):
     4164                           outlog=None, blfile=None, csvformat=None,
     4165                           bltable=None):
    30354166        """\
    30364167        Return a scan which has been baselined (all rows) by Chebyshev polynomials.
    30374168
    30384169        Parameters:
     4170            mask:         An optional mask
     4171            order:        the maximum order of Chebyshev polynomial (default is 5)
    30394172            insitu:       If False a new scantable is returned.
    30404173                          Otherwise, the scaling is done in-situ
    30414174                          The default is taken from .asaprc (False)
    3042             mask:         An optional mask
    3043             order:        the maximum order of Chebyshev polynomial (default is 5)
    30444175            clipthresh:   Clipping threshold. (default is 3.0, unit: sigma)
    30454176            clipniter:    maximum number of iteration of 'clipthresh'-sigma
     
    30614192                          (default is "": no file/logger output)
    30624193            csvformat:    if True blfile is csv-formatted, default is False.
     4194            bltable:      name of a baseline table where fitting results
     4195                          (coefficients, rms, etc.) are to be written.
     4196                          if given, fitting results will NOT be output to
     4197                          scantable (insitu=True) or None will be
     4198                          returned (insitu=False).
     4199                          (default is "": no table output)
    30634200
    30644201        Example:
     
    30824219                workscan = self.copy()
    30834220
    3084             #if mask         is None: mask         = [True for i in xrange(workscan.nchan())]
    30854221            if mask         is None: mask         = []
    30864222            if order        is None: order        = 5
     
    30934229            if outlog       is None: outlog       = False
    30944230            if blfile       is None: blfile       = ''
    3095             if csvformat     is None: csvformat     = False
    3096 
    3097             if csvformat:
    3098                 scsvformat = "T"
    3099             else:
    3100                 scsvformat = "F"
     4231            if csvformat    is None: csvformat    = False
     4232            if bltable      is None: bltable      = ''
     4233
     4234            scsvformat = 'T' if csvformat else 'F'
    31014235
    31024236            #CURRENTLY, PLOT=true UNAVAILABLE UNTIL cubic spline fitting is implemented as a fitter method.
    3103             workscan._chebyshev_baseline(mask, order, clipthresh, clipniter,
     4237            workscan._chebyshev_baseline(mask, order,
     4238                                         clipthresh, clipniter,
    31044239                                         getresidual,
    31054240                                         pack_progress_params(showprogress,
    31064241                                                              minnrow),
    3107                                          outlog, scsvformat+blfile)
     4242                                         outlog, scsvformat+blfile,
     4243                                         bltable)
    31084244            workscan._add_history("chebyshev_baseline", varlist)
    3109            
    3110             if insitu:
    3111                 self._assign(workscan)
     4245
     4246            if bltable == '':
     4247                if insitu:
     4248                    self._assign(workscan)
     4249                else:
     4250                    return workscan
    31124251            else:
    3113                 return workscan
     4252                if not insitu:
     4253                    return None
    31144254           
    31154255        except RuntimeError, e:
     
    31174257
    31184258    @asaplog_post_dec
    3119     def auto_chebyshev_baseline(self, insitu=None, mask=None, order=None,
     4259    def auto_chebyshev_baseline(self, mask=None, order=None, insitu=None,
    31204260                              clipthresh=None, clipniter=None,
    31214261                              edge=None, threshold=None, chan_avg_limit=None,
    31224262                              getresidual=None, plot=None,
    31234263                              showprogress=None, minnrow=None, outlog=None,
    3124                               blfile=None, csvformat=None):
     4264                              blfile=None, csvformat=None, bltable=None):
    31254265        """\
    31264266        Return a scan which has been baselined (all rows) by Chebyshev polynomials.
     
    31294269
    31304270        Parameters:
     4271            mask:           an optional mask retreived from scantable
     4272            order:          the maximum order of Chebyshev polynomial (default is 5)
    31314273            insitu:         if False a new scantable is returned.
    31324274                            Otherwise, the scaling is done in-situ
    31334275                            The default is taken from .asaprc (False)
    3134             mask:           an optional mask retreived from scantable
    3135             order:          the maximum order of Chebyshev polynomial (default is 5)
    31364276            clipthresh:     Clipping threshold. (default is 3.0, unit: sigma)
    31374277            clipniter:      maximum number of iteration of 'clipthresh'-sigma
     
    31734313                            (default is "": no file/logger output)
    31744314            csvformat:      if True blfile is csv-formatted, default is False.
     4315            bltable:        name of a baseline table where fitting results
     4316                            (coefficients, rms, etc.) are to be written.
     4317                            if given, fitting results will NOT be output to
     4318                            scantable (insitu=True) or None will be
     4319                            returned (insitu=False).
     4320                            (default is "": no table output)
    31754321
    31764322        Example:
     
    31914337                workscan = self.copy()
    31924338           
    3193             #if mask           is None: mask           = [True for i in xrange(workscan.nchan())]
    31944339            if mask           is None: mask           = []
    31954340            if order          is None: order          = 5
     
    32064351            if blfile         is None: blfile         = ''
    32074352            if csvformat      is None: csvformat      = False
    3208 
    3209             if csvformat:
    3210                 scsvformat = "T"
    3211             else:
    3212                 scsvformat = "F"
     4353            if bltable        is None: bltable        = ''
     4354
     4355            scsvformat = 'T' if csvformat else 'F'
    32134356
    32144357            #CURRENTLY, PLOT=true UNAVAILABLE UNTIL cubic spline fitting is implemented as a fitter method.
    3215             workscan._auto_chebyshev_baseline(mask, order, clipthresh,
    3216                                               clipniter,
     4358            workscan._auto_chebyshev_baseline(mask, order,
     4359                                              clipthresh, clipniter,
    32174360                                              normalise_edge_param(edge),
    32184361                                              threshold,
     
    32204363                                              pack_progress_params(showprogress,
    32214364                                                                   minnrow),
    3222                                               outlog, scsvformat+blfile)
     4365                                              outlog, scsvformat+blfile,
     4366                                              bltable)
    32234367            workscan._add_history("auto_chebyshev_baseline", varlist)
    3224            
    3225             if insitu:
    3226                 self._assign(workscan)
     4368
     4369            if bltable == '':
     4370                if insitu:
     4371                    self._assign(workscan)
     4372                else:
     4373                    return workscan
    32274374            else:
    3228                 return workscan
     4375                if not insitu:
     4376                    return None
    32294377           
    32304378        except RuntimeError, e:
     
    32324380
    32334381    @asaplog_post_dec
    3234     def poly_baseline(self, mask=None, order=None, insitu=None, plot=None,
     4382    def poly_baseline(self, mask=None, order=None, insitu=None,
     4383                      clipthresh=None, clipniter=None, plot=None,
    32354384                      getresidual=None, showprogress=None, minnrow=None,
    3236                       outlog=None, blfile=None, csvformat=None):
     4385                      outlog=None, blfile=None, csvformat=None,
     4386                      bltable=None):
    32374387        """\
    32384388        Return a scan which has been baselined (all rows) by a polynomial.
    32394389        Parameters:
     4390            mask:         an optional mask
     4391            order:        the order of the polynomial (default is 0)
    32404392            insitu:       if False a new scantable is returned.
    32414393                          Otherwise, the scaling is done in-situ
    32424394                          The default is taken from .asaprc (False)
    3243             mask:         an optional mask
    3244             order:        the order of the polynomial (default is 0)
     4395            clipthresh:   Clipping threshold. (default is 3.0, unit: sigma)
     4396            clipniter:    maximum number of iteration of 'clipthresh'-sigma
     4397                          clipping (default is 0)
    32454398            plot:         plot the fit and the residual. In this each
    32464399                          indivual fit has to be approved, by typing 'y'
     
    32584411                          (default is "": no file/logger output)
    32594412            csvformat:    if True blfile is csv-formatted, default is False.
     4413            bltable:      name of a baseline table where fitting results
     4414                          (coefficients, rms, etc.) are to be written.
     4415                          if given, fitting results will NOT be output to
     4416                          scantable (insitu=True) or None will be
     4417                          returned (insitu=False).
     4418                          (default is "": no table output)
    32604419
    32614420        Example:
     
    32754434                workscan = self.copy()
    32764435
    3277             #if mask         is None: mask         = [True for i in \
    3278             #                                           xrange(workscan.nchan())]
    32794436            if mask         is None: mask         = []
    32804437            if order        is None: order        = 0
     4438            if clipthresh   is None: clipthresh   = 3.0
     4439            if clipniter    is None: clipniter    = 0
    32814440            if plot         is None: plot         = False
    32824441            if getresidual  is None: getresidual  = True
     
    32844443            if minnrow      is None: minnrow      = 1000
    32854444            if outlog       is None: outlog       = False
    3286             if blfile       is None: blfile       = ""
     4445            if blfile       is None: blfile       = ''
    32874446            if csvformat    is None: csvformat    = False
    3288 
    3289             if csvformat:
    3290                 scsvformat = "T"
    3291             else:
    3292                 scsvformat = "F"
     4447            if bltable      is None: bltable      = ''
     4448
     4449            scsvformat = 'T' if csvformat else 'F'
    32934450
    32944451            if plot:
     
    33544511                    blf.close()
    33554512            else:
    3356                 workscan._poly_baseline(mask, order, getresidual,
     4513                workscan._poly_baseline(mask, order,
     4514                                        clipthresh, clipniter, #
     4515                                        getresidual,
    33574516                                        pack_progress_params(showprogress,
    33584517                                                             minnrow),
    3359                                         outlog, scsvformat+blfile)
     4518                                        outlog, scsvformat+blfile,
     4519                                        bltable)  #
    33604520           
    33614521            workscan._add_history("poly_baseline", varlist)
     
    33704530
    33714531    @asaplog_post_dec
    3372     def auto_poly_baseline(self, mask=None, order=None, edge=None,
    3373                            threshold=None, chan_avg_limit=None,
    3374                            plot=None, insitu=None,
    3375                            getresidual=None, showprogress=None,
    3376                            minnrow=None, outlog=None, blfile=None, csvformat=None):
     4532    def auto_poly_baseline(self, mask=None, order=None, insitu=None,
     4533                           clipthresh=None, clipniter=None,
     4534                           edge=None, threshold=None, chan_avg_limit=None,
     4535                           getresidual=None, plot=None,
     4536                           showprogress=None, minnrow=None, outlog=None,
     4537                           blfile=None, csvformat=None, bltable=None):
    33774538        """\
    33784539        Return a scan which has been baselined (all rows) by a polynomial.
     
    33814542
    33824543        Parameters:
     4544            mask:           an optional mask retreived from scantable
     4545            order:          the order of the polynomial (default is 0)
    33834546            insitu:         if False a new scantable is returned.
    33844547                            Otherwise, the scaling is done in-situ
    33854548                            The default is taken from .asaprc (False)
    3386             mask:           an optional mask retreived from scantable
    3387             order:          the order of the polynomial (default is 0)
     4549            clipthresh:     Clipping threshold. (default is 3.0, unit: sigma)
     4550            clipniter:      maximum number of iteration of 'clipthresh'-sigma
     4551                            clipping (default is 0)
    33884552            edge:           an optional number of channel to drop at
    33894553                            the edge of spectrum. If only one value is
     
    34214585                            (default is "": no file/logger output)
    34224586            csvformat:      if True blfile is csv-formatted, default is False.
     4587            bltable:        name of a baseline table where fitting results
     4588                            (coefficients, rms, etc.) are to be written.
     4589                            if given, fitting results will NOT be output to
     4590                            scantable (insitu=True) or None will be
     4591                            returned (insitu=False).
     4592                            (default is "": no table output)
    34234593
    34244594        Example:
     
    34364606                workscan = self.copy()
    34374607
    3438             #if mask           is None: mask           = [True for i in xrange(workscan.nchan())]
    34394608            if mask           is None: mask           = []
    34404609            if order          is None: order          = 0
     4610            if clipthresh     is None: clipthresh     = 3.0
     4611            if clipniter      is None: clipniter      = 0
    34414612            if edge           is None: edge           = (0, 0)
    34424613            if threshold      is None: threshold      = 3
     
    34494620            if blfile         is None: blfile         = ''
    34504621            if csvformat      is None: csvformat      = False
    3451 
    3452             if csvformat:
    3453                 scsvformat = "T"
    3454             else:
    3455                 scsvformat = "F"
     4622            if bltable        is None: bltable        = ''
     4623
     4624            scsvformat = 'T' if csvformat else 'F'
    34564625
    34574626            edge = normalise_edge_param(edge)
     
    35234692                if outblfile: blf.close()
    35244693            else:
    3525                 workscan._auto_poly_baseline(mask, order, edge, threshold,
     4694                workscan._auto_poly_baseline(mask, order,
     4695                                             clipthresh, clipniter,
     4696                                             edge, threshold,
    35264697                                             chan_avg_limit, getresidual,
    35274698                                             pack_progress_params(showprogress,
    35284699                                                                  minnrow),
    3529                                              outlog, scsvformat+blfile)
    3530 
     4700                                             outlog, scsvformat+blfile,
     4701                                             bltable)
    35314702            workscan._add_history("auto_poly_baseline", varlist)
    3532            
    3533             if insitu:
    3534                 self._assign(workscan)
     4703
     4704            if bltable == '':
     4705                if insitu:
     4706                    self._assign(workscan)
     4707                else:
     4708                    return workscan
    35354709            else:
    3536                 return workscan
     4710                if not insitu:
     4711                    return None
    35374712           
    35384713        except RuntimeError, e:
     
    36444819        self._math._setinsitu(insitu)
    36454820        varlist = vars()
    3646         s = scantable(self._math._unaryop(self, offset, "ADD", False))
     4821        s = scantable(self._math._unaryop(self, offset, "ADD", False, False))
    36474822        s._add_history("add", varlist)
    36484823        if insitu:
     
    36674842            tsys:        if True (default) then apply the operation to Tsys
    36684843                         as well as the data
    3669 
    36704844        """
    36714845        if insitu is None: insitu = rcParams['insitu']
     
    36784852                                                         numpy.ndarray):
    36794853                from asapmath import _array2dOp
    3680                 s = _array2dOp( self, factor, "MUL", tsys, insitu )
     4854                s = _array2dOp( self, factor, "MUL", tsys, insitu, True )
    36814855            else:
    36824856                s = scantable( self._math._arrayop( self, factor,
    3683                                                     "MUL", tsys ) )
     4857                                                    "MUL", tsys, True ) )
    36844858        else:
    3685             s = scantable(self._math._unaryop(self, factor, "MUL", tsys))
     4859            s = scantable(self._math._unaryop(self, factor, "MUL", tsys, True ))
    36864860        s._add_history("scale", varlist)
    36874861        if insitu:
     
    37304904        self._add_history("set_sourcetype", varlist)
    37314905
     4906
     4907    def set_sourcename(self, name):
     4908        varlist = vars()
     4909        self._setsourcename(name)
     4910        self._add_history("set_sourcename", varlist)
     4911
    37324912    @asaplog_post_dec
    37334913    @preserve_selection
     
    37664946        s = None
    37674947        if mode.lower() == "paired":
     4948            from asap._asap import srctype
    37684949            sel = self.get_selection()
    3769             sel.set_query("SRCTYPE==psoff")
     4950            #sel.set_query("SRCTYPE==psoff")
     4951            sel.set_types(srctype.psoff)
    37704952            self.set_selection(sel)
    37714953            offs = self.copy()
    3772             sel.set_query("SRCTYPE==pson")
     4954            #sel.set_query("SRCTYPE==pson")
     4955            sel.set_types(srctype.pson)
    37734956            self.set_selection(sel)
    37744957            ons = self.copy()
     
    38875070            if other == 0.0:
    38885071                raise ZeroDivisionError("Dividing by zero is not recommended")
    3889             s = scantable(self._math._unaryop(self, other, mode, False))
     5072            s = scantable(self._math._unaryop(self, other, mode, False, True))
    38905073        elif isinstance(other, list) or isinstance(other, numpy.ndarray):
    38915074            if isinstance(other[0], list) \
    38925075                    or isinstance(other[0], numpy.ndarray):
    38935076                from asapmath import _array2dOp
    3894                 s = _array2dOp( self, other, mode, False )
     5077                s = _array2dOp(self, other, mode, False)
    38955078            else:
    3896                 s = scantable( self._math._arrayop( self, other,
    3897                                                     mode, False ) )
     5079                s = scantable(self._math._arrayop(self, other, mode, False, True))
    38985080        else:
    38995081            raise TypeError("Other input is not a scantable or float value")
     
    39285110            self.set_selection(basesel+sel)
    39295111            nans = numpy.isnan(self._getspectrum(0))
    3930         if numpy.any(nans):
    3931             bnans = [ bool(v) for v in nans]
    3932             self.flag(bnans)
     5112            if numpy.any(nans):
     5113                bnans = [ bool(v) for v in nans]
     5114                self.flag(bnans)
     5115       
     5116        self.set_selection(basesel)
    39335117
    39345118    def get_row_selector(self, rowno):
Note: See TracChangeset for help on using the changeset viewer.