Ignore:
Location:
trunk/python
Files:
1 deleted
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/python/CMakeLists.txt

    r3112 r2704  
    3535     ${PYTHONDIR}/opacity.py
    3636     ${PYTHONDIR}/parameters.py
    37      ${PYTHONDIR}/plotter2.py
     37#     ${PYTHONDIR}/plotter2.py
    3838     ${PYTHONDIR}/sbseparator.py
    3939     ${PYTHONDIR}/scantable.py
  • trunk/python/__init__.py

    r3112 r2704  
    5454from asapgrid import asapgrid, asapgrid2
    5555from edgemarker import edgemarker
    56 if is_casapy():
    57     from plotter2 import plotter2
     56#from plotter2 import plotter2
    5857from sbseparator import sbseparator
    5958from _asap import srctype
    6059
    61 __date__ = get_asap_revdate()
    62 __version__  = '4.0.0a'
     60__date__ = '$Date$'.split()[1]
     61__version__  = 'trunk'
    6362__revision__ = get_revision()
    6463
  • trunk/python/asapfitter.py

    r3112 r2704  
    157157
    158158        if self.data is not None:
    159             if self.data._getflagrow(row):
    160                 raise RuntimeError,"Can not fit flagged row."
    161159            self.x = self.data._getabcissa(row)
    162160            self.y = self.data._getspectrum(row)
  • trunk/python/asapgrid.py

    r3112 r2704  
    486486                    #print irow
    487487        # show image
    488         extent=[self.blc[0]-0.5*self.cellx,
    489                 self.trc[0]+0.5*self.cellx,
     488        extent=[self.trc[0]+0.5*self.cellx,
     489                self.blc[0]-0.5*self.cellx,
    490490                self.blc[1]-0.5*self.celly,
    491491                self.trc[1]+0.5*self.celly]
  • trunk/python/asaplotbase.py

    r3112 r2704  
    99from matplotlib.figure import Figure, Text
    1010from matplotlib.font_manager import FontProperties as FP
    11 from numpy import sqrt, ceil
     11from numpy import sqrt
    1212from matplotlib import rc, rcParams
    1313from matplotlib.ticker import OldScalarFormatter
     
    100100        return False
    101101
    102     def _subplotsOk(self, rows, cols, npanel=0):
    103         """
    104         Check if the axes in subplots are actually the ones plotted on
    105         the figure. Returns a bool.
    106         This method is to detect manual layout changes using mpl methods.
    107         """
    108         # compare with user defined layout
    109         if (rows is not None) and (rows != self.rows):
    110             return False
    111         if (cols is not None) and (cols != self.cols):
    112             return False
    113         # check number of subplots
    114         figaxes = self.figure.get_axes()
    115         np = self.rows*self.cols
    116         if npanel > np:
    117             return False
    118         if len(figaxes) != np:
    119             return False
    120         if len(self.subplots) != len(figaxes):
    121             return False
    122         # compare axes instance in this class and on the plotter
    123         ok = True
    124         for ip in range(np):
    125             if self.subplots[ip]['axes'] != figaxes[ip]:
    126                 ok = False
    127                 break
    128         return ok
    129102
    130103    ### Delete artists ###
  • trunk/python/asapmath.py

    r3112 r2704  
    1 import re
    21from asap.scantable import scantable
    32from asap.parameters import rcParams
     
    9190    else:
    9291        #s = scantable(stm._average(alignedlst, mask, weight.upper(), scanav))
    93         s = scantable(stm._new_average(alignedlst, compel, mask,
    94                                        weight.upper(), scanav))
     92        s = scantable(stm._new_average(alignedlst, compel, mask, weight.upper(), scanav))
    9593    s._add_history("average_time",varlist)
    9694
     
    393391            p.quit()
    394392            del p
    395             return scantab
     393            return scabtab
    396394        p.quit()
    397395        del p
     
    613611            p.quit()
    614612            del p
    615             return scantab
     613            return scabtab
    616614        p.quit()
    617615        del p
     
    816814            p.quit()
    817815            del p
    818             return scantab
     816            return scabtab
    819817        p.quit()
    820818        del p
     
    824822
    825823@asaplog_post_dec
    826 def merge(*args, **kwargs):
     824def merge(*args):
    827825    """
    828826    Merge a list of scanatables, or comma-sperated scantables into one
     
    830828    Parameters:
    831829        A list [scan1, scan2] or scan1, scan2.
    832         freq_tol: frequency tolerance for merging IFs. numeric values
    833                   in units of Hz (1.0e6 -> 1MHz) and string ('1MHz')
    834                   is allowed.
    835830    Example:
    836831        myscans = [scan1, scan2]
     
    838833        # or equivalent
    839834        sameallscans = merge(scan1, scan2)
    840         # with freqtol
    841         allscans = merge(scan1, scan2, freq_tol=1.0e6)
    842         # or equivalently
    843         allscans = merge(scan1, scan2, freq_tol='1MHz')
    844835    """
    845836    varlist = vars()
     
    850841    else:
    851842        lst = tuple(args)
    852     if kwargs.has_key('freq_tol'):
    853         freq_tol = str(kwargs['freq_tol'])
    854         if len(freq_tol) > 0 and re.match('.+[GMk]Hz$', freq_tol) is None:
    855             freq_tol += 'Hz'
    856     else:
    857         freq_tol = ''
    858843    varlist["args"] = "%d scantables" % len(lst)
    859844    # need special formatting her for history...
     
    864849            msg = "Please give a list of scantables"
    865850            raise TypeError(msg)
    866     s = scantable(stm._merge(lst, freq_tol))
     851    s = scantable(stm._merge(lst))
    867852    s._add_history("merge", varlist)
    868853    return s
     
    964949
    965950@asaplog_post_dec
    966 def splitant(filename, outprefix='',overwrite=False, getpt=True):
     951def splitant(filename, outprefix='',overwrite=False):
    967952    """
    968953    Split Measurement set by antenna name, save data as a scantables,
    969     and return a list of filename. Note that frequency reference frame
    970     is imported as it is in Measurement set.
     954    and return a list of filename.
    971955    Notice this method can only be available from CASA.
    972956    Prameter
     
    979963                    The default False is to return with warning
    980964                    without writing the output. USE WITH CARE.
    981        getpt        Whether to import direction from MS/POINTING
    982                     table or not. Default is True (import direction).
     965
    983966    """
    984967    # Import the table toolkit from CASA
    985     from taskinit import gentools
     968    from casac import casac
    986969    from asap.scantable import is_ms
    987     tb = gentools(['tb'])[0]
     970    tb = casac.table()
    988971    # Check the input filename
    989972    if isinstance(filename, str):
     
    995978            raise IOError(s)
    996979        # check if input file is MS
     980        #if not os.path.isdir(filename) \
     981        #       or not os.path.exists(filename+'/ANTENNA') \
     982        #       or not os.path.exists(filename+'/table.f1'):
    997983        if not is_ms(filename):
    998984            s = "File '%s' is not a Measurement set." % (filename)
     
    1010996    tb.open(tablename=filename,nomodify=True)
    1011997    ant1=tb.getcol('ANTENNA1',0,-1,1)
     998    #anttab=tb.getkeyword('ANTENNA').split()[-1]
    1012999    anttab=tb.getkeyword('ANTENNA').lstrip('Table: ')
    10131000    tb.close()
     1001    #tb.open(tablename=filename+'/ANTENNA',nomodify=True)
    10141002    tb.open(tablename=anttab,nomodify=True)
    10151003    nant=tb.nrows()
    10161004    antnames=tb.getcol('NAME',0,nant,1)
    10171005    tb.close()
     1006    tmpname='asapmath.splitant.tmp'
    10181007    for antid in set(ant1):
    1019         scan=scantable(filename,average=False,antenna=int(antid),getpt=getpt)
     1008        tb.open(tablename=filename,nomodify=True)
     1009        tbsel=tb.query('ANTENNA1 == %s && ANTENNA2 == %s'%(antid,antid),tmpname)
     1010        scan=scantable(tmpname,average=False,getpt=True,antenna=int(antid))
    10201011        outname=prefix+antnames[antid]+'.asap'
    10211012        scan.save(outname,format='ASAP',overwrite=overwrite)
     1013        tbsel.close()
     1014        tb.close()
     1015        del tbsel
    10221016        del scan
    10231017        outfiles.append(outname)
     1018        os.system('rm -rf '+tmpname)
     1019    del tb
    10241020    return outfiles
    10251021
    10261022@asaplog_post_dec
    1027 def _array2dOp( scan, value, mode="ADD", tsys=False, insitu=None, skip_flaggedrow=False):
     1023def _array2dOp( scan, value, mode="ADD", tsys=False, insitu=None):
    10281024    """
    10291025    This function is workaround on the basic operation of scantable
     
    10361032    insitu:  if False, a new scantable is returned.
    10371033             Otherwise, the array operation is done in-sitsu.
    1038     skip_flaggedrow: skip operation for row-flagged spectra.
    10391034    """
    10401035    if insitu is None: insitu = rcParams['insitu']
     
    10451040    stm._setinsitu(insitu)
    10461041    if len( value ) == 1:
    1047         s = scantable( stm._arrayop( scan, value[0], mode, tsys, skip_flaggedrow ) )
     1042        s = scantable( stm._arrayop( scan, value[0], mode, tsys ) )
    10481043    elif len( value ) != nrow:
    10491044        raise ValueError( 'len(value) must be 1 or conform to scan.nrow()' )
     
    10631058            s.set_selection( sel )
    10641059            if len( value[irow] ) == 1:
    1065                 stm._unaryop( s, value[irow][0], mode, tsys, skip_flaggedrow )
     1060                stm._unaryop( s, value[irow][0], mode, tsys )
    10661061            else:
    10671062                #stm._arrayop( s, value[irow], mode, tsys, 'channel' )
    1068                 stm._arrayop( s, value[irow], mode, tsys, skip_flaggedrow )
     1063                stm._arrayop( s, value[irow], mode, tsys )
    10691064        s.set_selection(basesel)
    10701065    return s
  • trunk/python/asapplotter.py

    r3112 r2704  
    112112        self._plotter.legend(self._legendloc)
    113113
    114     ### TODO: it's probably better to define following two methods in
    115     ###       backend dependent class.
    116114    def _new_custombar(self):
    117115        backend=matplotlib.get_backend()
     
    132130            return True
    133131        return False
    134     ### end of TODO
    135132
    136133    def _assert_plotter(self,action="status",errmsg=None):
     
    279276
    280277
    281     ### Forwards to methods in matplotlib axes ###
     278    ### Forwards to matplotlib axes ###
    282279    def text(self, *args, **kwargs):
    283280        self._assert_plotter(action="reload")
     
    418415                del self._data
    419416                msg = "A new scantable is set to the plotter. "\
    420                       "The masks, data selections, and labels are reset."
    421                 asaplog.push(msg)
     417                      "The masks and data selections are reset."
     418                asaplog.push( msg )
    422419            self._data = scan
    423420            # reset
     
    517514        self._rows = rows
    518515        self._cols = cols
    519         # new layout is set. need to reset counters for multi page plotting
    520         self._reset_counters()
    521516        if refresh and self._data: self.plot(self._data)
    522517        return
     
    910905            msg = "Can only set mask after a first call to plot()"
    911906            raise RuntimeError(msg)
    912         if (mask is not None) and len(mask):
     907        if len(mask):
    913908            if isinstance(mask, list) or isinstance(mask, tuple):
    914909                self._usermask = array(mask)
     
    931926    ### Reset methods ###
    932927    def _reset(self):
    933         """Reset method called when new data is set"""
    934         # reset selections and masks
     928        self._usermask = []
     929        self._usermaskspectra = None
     930        self._offset = None
    935931        self.set_selection(None, False)
    936         self.set_mask(None, None, False)
    937         # reset offset
    938         self._offset = None
    939         # reset header
    940932        self._reset_header()
    941         # reset labels
    942         self._lmap = None # related to stack
    943         self.set_title(None, None, False)
    944         self.set_ordinate(None, None, False)
    945         self.set_abcissa(None, None, False)
    946933
    947934    def _reset_header(self):
     
    951938        self._startrow = 0
    952939        self._ipanel = -1
     940        self._reset_header()
    953941        self._panelrows = []
    954         self._reset_header()
    955942        if self.casabar_exists():
    956943            self._plotter.figmgr.casabar.set_pagecounter(1)
     
    10441031        if self._panelling == 'i':
    10451032            ganged = False
    1046         if (not firstpage) and \
    1047                self._plotter._subplotsOk(self._rows, self._cols, n):
    1048             # Not the first page and subplot number is ok.
    1049             # Just clear the axis
     1033        if not firstpage:
     1034            # not the first page just clear the axis
    10501035            nx = self._plotter.cols
    10511036            ipaxx = n - nx - 1 #the max panel id to supress x-label
     
    13171302            return start,end
    13181303
    1319     def _get_date_axis_setup(self, dates, axlim=None):
    1320         """
    1321         Returns proper axis title and formatters for a list of dates
    1322         Input
    1323             dates : a list of datetime objects returned by,
    1324                     e.g. scantable.get_time(asdatetime=True)
    1325             axlim : a tuple of min and max day range in the plot axis.
    1326                     if defined, the values are taken into account.
    1327         Output
    1328             a set of
    1329             * date axis title string
    1330             * formatter of date axis
    1331             * major axis locator
    1332             * minor axis locator
    1333         """
    1334         from matplotlib import pylab as PL
    1335         from matplotlib.dates import DateFormatter
    1336         from matplotlib.dates import HourLocator, MinuteLocator,SecondLocator, DayLocator, YearLocator, MonthLocator
    1337         t = PL.date2num(dates)
    1338         tmin = min(t)
    1339         tmax = max(t)
    1340         if axlim is not None:
    1341             tmin = min(tmin, min(axlim))
    1342             tmax = max(tmax, max(axlim))
    1343         tdel = tmax - tmin # interval in day
    1344         dstr = dates[0].strftime('%Y/%m/%d')
    1345         if tdel > 365.0: # >1year (also the case for single or very small time range)
    1346             majloc = YearLocator()
    1347             minloc = MonthLocator(range(1,12,6))
    1348             timefmt = DateFormatter('%Y/%m/%d')
    1349         elif tdel > 1.0: # >1day
    1350             dstr2 = dates[len(dates)-1].strftime('%Y/%m/%d')
    1351             dstr = dstr + " - " + dstr2
    1352             majloc = DayLocator()
    1353             minloc = HourLocator(range(0,23,12))
    1354             timefmt = DateFormatter("%b%d")
    1355         elif tdel > 24./60.: # 9.6h - 1day
    1356             timefmt = DateFormatter('%H:%M')
    1357             majloc = HourLocator()
    1358             minloc = MinuteLocator(range(0,60,30))
    1359         elif tdel > 2./24.: # 2h-9.6h
    1360             timefmt = DateFormatter('%H:%M')
    1361             majloc = HourLocator()
    1362             minloc = MinuteLocator(range(0,60,10))
    1363         elif tdel> 10./24./60.: # 10min-2h
    1364             timefmt = DateFormatter('%H:%M')
    1365             majloc = MinuteLocator(range(0,60,10))
    1366             minloc = MinuteLocator()
    1367         else: # <10min
    1368             timefmt = DateFormatter('%H:%M')
    1369             majloc = MinuteLocator()
    1370             minloc = SecondLocator(30)
    1371         return (dstr, timefmt, majloc, minloc)
    1372 
    13731304    def plotazel(self, scan=None, outfile=None):
    13741305        """
     
    13781309        visible = rcParams['plotter.gui']
    13791310        from matplotlib import pylab as PL
     1311        from matplotlib.dates import DateFormatter
    13801312        from pytz import timezone
     1313        from matplotlib.dates import HourLocator, MinuteLocator,SecondLocator, DayLocator
    13811314        from matplotlib.ticker import MultipleLocator
    1382         from numpy import array, pi, ma
     1315        from numpy import array, pi
    13831316        if self._plotter and (PL.gcf() == self._plotter.figure):
    13841317            # the current figure is ASAP plotter. Use mpl plotter
     
    13921325        self._data = scan
    13931326        dates = self._data.get_time(asdatetime=True)
    1394         # for flag handling
    1395         mask = [ self._data._is_all_chan_flagged(i) for i in range(self._data.nrow())]
    13961327        t = PL.date2num(dates)
    13971328        tz = timezone('UTC')
     
    14061337                                 wspace=wsp,hspace=hsp)
    14071338
    1408         tdel = max(t) - min(t) # interval in day
     1339        tdel = max(t) - min(t)
    14091340        ax = PL.subplot(2,1,1)
    1410         el = ma.masked_array(array(self._data.get_elevation())*180./pi, mask)
     1341        el = array(self._data.get_elevation())*180./pi
    14111342        PL.ylabel('El [deg.]')
    1412         (dstr, timefmt, majloc, minloc) = self._get_date_axis_setup(dates)
    1413        
     1343        dstr = dates[0].strftime('%Y/%m/%d')
     1344        if tdel > 1.0:
     1345            dstr2 = dates[len(dates)-1].strftime('%Y/%m/%d')
     1346            dstr = dstr + " - " + dstr2
     1347            majloc = DayLocator()
     1348            minloc = HourLocator(range(0,23,12))
     1349            timefmt = DateFormatter("%b%d")
     1350        elif tdel > 24./60.:
     1351            timefmt = DateFormatter('%H:%M')
     1352            majloc = HourLocator()
     1353            minloc = MinuteLocator(30)
     1354        else:
     1355            timefmt = DateFormatter('%H:%M')
     1356            majloc = MinuteLocator(interval=5)
     1357            minloc = SecondLocator(30)
     1358
    14141359        PL.title(dstr)
    14151360        if tdel == 0.0:
     
    14181363        else:
    14191364            PL.plot_date(t,el,'o', markersize=2, markerfacecolor='b', markeredgecolor='b',tz=tz)
    1420             #ax.xaxis.set_major_formatter(timefmt)
    1421             #ax.xaxis.set_major_locator(majloc)
    1422             #ax.xaxis.set_minor_locator(minloc)
     1365            #ax.grid(True)
     1366            ax.xaxis.set_major_formatter(timefmt)
     1367            ax.xaxis.set_major_locator(majloc)
     1368            ax.xaxis.set_minor_locator(minloc)
    14231369        ax.yaxis.grid(True)
     1370        yloc = MultipleLocator(30)
    14241371        ax.set_ylim(0,90)
    1425         #yloc = MultipleLocator(30)
    1426         #ax.yaxis.set_major_locator(yloc)
     1372        ax.yaxis.set_major_locator(yloc)
    14271373        if tdel > 1.0:
    14281374            labels = ax.get_xticklabels()
     
    14311377
    14321378        # Az plot
    1433         az = ma.masked_array(array(self._data.get_azimuth())*180./pi, mask)
     1379        az = array(self._data.get_azimuth())*180./pi
    14341380        if min(az) < 0:
    14351381            for irow in range(len(az)):
     
    14431389        else:
    14441390            PL.plot_date(t,az,'o', markersize=2,markeredgecolor='b',markerfacecolor='b',tz=tz)
    1445             #ax2.xaxis.set_major_formatter(timefmt)
    1446             #ax2.xaxis.set_major_locator(majloc)
    1447             #ax2.xaxis.set_minor_locator(minloc)
     1391            ax2.xaxis.set_major_formatter(timefmt)
     1392            ax2.xaxis.set_major_locator(majloc)
     1393            ax2.xaxis.set_minor_locator(minloc)
     1394        #ax2.grid(True)
    14481395        ax2.set_ylim(0,360)
    14491396        ax2.yaxis.grid(True)
    14501397        #hfmt = DateFormatter('%H')
    14511398        #hloc = HourLocator()
    1452         #yloc = MultipleLocator(60)
    1453         #ax2.yaxis.set_major_locator(yloc)
     1399        yloc = MultipleLocator(60)
     1400        ax2.yaxis.set_major_locator(yloc)
    14541401        if tdel > 1.0:
    14551402            labels = ax2.get_xticklabels()
    14561403            PL.setp(labels, fontsize=10)
    1457         #    PL.xlabel('Time (UT [day])')
    1458         #else:
    1459         #    PL.xlabel('Time (UT [hour])')
    1460         PL.xlabel('Time (UT)')
     1404            PL.xlabel('Time (UT [day])')
     1405        else:
     1406            PL.xlabel('Time (UT [hour])')
    14611407
    14621408        PL.ion()
     
    14711417        plot telescope pointings
    14721418        Parameters:
    1473             scan    : input scantable instance
     1419            infile  : input filename or scantable instance
    14741420            colorby : change color by either
    14751421                      'type'(source type)|'scan'|'if'|'pol'|'beam'
     
    14791425        """
    14801426        self._plotmode = "pointing"
    1481         from numpy import array, pi, ma
     1427        from numpy import array, pi
    14821428        from asap import scantable
    14831429        # check for scantable
     
    15551501                self._data.set_selection(basesel)
    15561502                continue
    1557             #print "Plotting direction of %s = %s" % (colorby, str(idx))
     1503            print "Plotting direction of %s = %s" % (colorby, str(idx))
    15581504            # getting data to plot
    15591505            dir = array(self._data.get_directionval()).transpose()
    1560             # for flag handling
    1561             mask = [ self._data._is_all_chan_flagged(i) for i in range(self._data.nrow())]
    15621506            ra = dir[0]*180./pi
    1563             dec = ma.masked_array(dir[1]*180./pi, mask)
     1507            dec = dir[1]*180./pi
    15641508            # actual plot
    15651509            self._plotter.set_line(label=(sellab+str(idx)))
     
    15871531        # reverse x-axis
    15881532        xmin, xmax = self.gca().get_xlim()
    1589         ymin, ymax = self.gca().get_ylim()
    1590         # expand plotrange if xmin==xmax or ymin==ymax
    1591         if abs(ymax-ymin) < 1.e-3: #~4arcsec
    1592             delx = 0.5*abs(xmax - xmin)
    1593             if delx < 5.e-4:
    1594                 dxy = 5.e-4 #~2arcsec
    1595                 (ymin, ymax) = (ymin-dxy, ymax+dxy)
    1596                 (xmin, xmax) = (xmin-dxy, xmax+dxy)
    1597             (ymin, ymax) = (ymin-delx, ymax+delx)
    1598         elif abs(xmax-xmin) < 1.e-3:
    1599             dely = 0.5*abs(ymax - ymin)
    1600             (xmin, xmax) = (xmin-dely, xmax+dely)
    1601         self._plotter.set_limits(xlim=[xmax,xmin], ylim=[ymin, ymax])
     1533        self._plotter.set_limits(xlim=[xmax,xmin])
    16021534
    16031535        self._plotter.release()
     
    16551587    # plotting in time is not yet implemented..
    16561588    @asaplog_post_dec
    1657     def plottp(self, scan=None, colorby=''):
    1658         """
    1659         Plot averaged spectra (total power) in time or in row ID (colorby='')
    1660         Parameters:
    1661             scan    : input scantable instance
    1662             colorby : change color by either
    1663                       'type'(source type)|'scan'|'if'|'pol'|'beam'|''
    1664         """
     1589    def plottp(self, scan=None):
    16651590        self._plotmode = "totalpower"
    16661591        from asap import scantable
     
    16931618            left=lef,bottom=bot,right=rig,top=top,wspace=wsp,hspace=hsp)
    16941619        if self.casabar_exists(): self._plotter.figmgr.casabar.disable_button()
    1695         if len(colorby) == 0:
    1696             self._plottp(self._data)
    1697         else:
    1698             self._plottp_in_time(self._data,colorby)
     1620        self._plottp(self._data)
    16991621        if self._minmaxy is not None:
    17001622            self._plotter.set_limits(ylim=self._minmaxy)
     
    17031625        self._plotter.show(hardrefresh=False)
    17041626        return
    1705 
    1706     def _plottp_in_time(self,scan,colorby):
    1707         """
    1708         private method for plotting total power data in time
    1709         Parameters:
    1710             scan    : input scantable instance
    1711             colorby : change color by either
    1712                       'type'(source type)|'scan'|'if'|'pol'|'beam'
    1713         """
    1714         from numpy import ma, array, arange, logical_not
    1715         r=0
    1716         nr = scan.nrow()
    1717         a0,b0 = -1,-1
    1718         allxlim = []
    1719         allylim = []
    1720         y=[]
    1721         self._plotter.set_panels()
    1722         self._plotter.palette(0)
    1723         # check of overlay settings
    1724         time_types = ['type','scan'] # time dependent meta-data
    1725         misc_types = ['if','pol','beam'] # time independent meta-data
    1726         validtypes=time_types + misc_types
    1727         stype = None
    1728         col_msg = "Invalid choice of 'colorby' (choices: %s)" % str(validtypes)
    1729         colorby = colorby.lower()
    1730         if (colorby in validtypes):
    1731             stype = colorby[0]
    1732         elif len(colorby) > 0:
    1733             raise ValueError(col_msg)
    1734         if not stype:
    1735             raise ValueError(col_msg)
    1736         # Selection and sort order
    1737         basesel = scan.get_selection()
    1738         if colorby in misc_types: misc_types.pop(misc_types.index(colorby))
    1739         sel_lbl = ""
    1740         for meta in misc_types:
    1741             idx = getattr(scan,'get'+meta+'nos')()
    1742             if len(idx) > 1: getattr(basesel, 'set_'+meta+'s')([idx[0]])
    1743             sel_lbl += ("%s%d, " % (meta.upper(), idx[0]))
    1744         sel_lbl = sel_lbl.rstrip(', ')
    1745         scan.set_selection(basesel)
    1746         if len(sel_lbl) > 0:
    1747             asaplog.push("Selection contains multiple IFs/Pols/Beams. Plotting the first ones: %s" % sel_lbl)
    1748             asaplog.post("WARN")
    1749         if stype == 't':
    1750             selIds = range(15)
    1751             sellab = "src type "
    1752         else:
    1753             selIds = getattr(scan,'get'+colorby+'nos')()
    1754             sellab = colorby.upper()
    1755         selFunc = "set_"+colorby+"s"
    1756         basesel.set_order(["TIME"])
    1757         # define axes labels
    1758         xlab = self._abcissa or 'Time (UTC)'
    1759         ylab = self._ordinate or scan._get_ordinate_label()
    1760         self._plotter.set_axes('xlabel',xlab)
    1761         self._plotter.set_axes('ylabel',ylab)
    1762         # define the panel title
    1763         if len(sel_lbl) > 0: lbl = sel_lbl
    1764         else: lbl = self._get_label(scan, r, 's', self._title)
    1765         if isinstance(lbl, list) or isinstance(lbl, tuple):
    1766             # get default label
    1767             lbl = self._get_label(scan, r, self._panelling, None)
    1768         self._plotter.set_axes('title',lbl)
    1769         # linestyle
    1770         lstyle = '' if colorby in time_types else ':'
    1771         alldates = []
    1772         for idx in selIds:
    1773             sel = selector() + basesel
    1774             bid = getattr(basesel,'get_'+colorby+"s")()
    1775             if (len(bid) > 0) and (not idx in bid):
    1776                 # base selection doesn't contain idx
    1777                 # Note summation of selector is logical sum if
    1778                 continue
    1779             getattr(sel, selFunc)([idx])
    1780             if not sel.is_empty():
    1781                 try:
    1782                     scan.set_selection(sel)
    1783                 except RuntimeError, instance:
    1784                     if stype == 't' and str(instance).startswith("Selection contains no data."):
    1785                         continue
    1786                     else:
    1787                         scan.set_selection(basesel)
    1788                         raise RuntimeError, instance
    1789             if scan.nrow() == 0:
    1790                 scan.set_selection(basesel)
    1791                 continue
    1792             y=array(scan._get_column(scan._getspectrum,-1))
    1793             m = array(scan._get_column(scan._getmask,-1))
    1794             y = ma.masked_array(y,mask=logical_not(array(m,copy=False)))
    1795             # try to handle spectral data somewhat...
    1796             try:
    1797                 l,m = y.shape
    1798             except ValueError, e:
    1799                 raise ValueError(str(e)+" This error usually occurs when you select multiple spws with different number of channels. Try selecting single spw and retry.")
    1800             if m > 1:
    1801                 y=y.mean(axis=1)
    1802             # flag handling
    1803             m = [ scan._is_all_chan_flagged(i) for i in range(scan.nrow()) ]
    1804             y = ma.masked_array(y,mask=m)
    1805             if len(y) == 0: continue
    1806             # line label
    1807             llbl=sellab+str(idx)
    1808             from matplotlib.dates import date2num
    1809             from pytz import timezone
    1810             dates = self._data.get_time(asdatetime=True)
    1811             alldates += list(dates)
    1812             x = date2num(dates)
    1813             tz = timezone('UTC')
    1814             # get color
    1815             lc = self._plotter.colormap[self._plotter.color]
    1816             self._plotter.palette( (self._plotter.color+1) % len(self._plotter.colormap) )
    1817             # actual plotting
    1818             self._plotter.axes.plot_date(x,y,tz=tz,label=llbl,linestyle=lstyle,color=lc,
    1819                                          marker='o',markersize=3,markeredgewidth=0)
    1820 
    1821         # legend and axis formatting
    1822         ax = self.gca()
    1823         (dstr, timefmt, majloc, minloc) = self._get_date_axis_setup(alldates, ax.get_xlim())
    1824         ax.xaxis.set_major_formatter(timefmt)
    1825         ax.xaxis.set_major_locator(majloc)
    1826         ax.xaxis.set_minor_locator(minloc)
    1827         self._plotter.axes.legend(loc=self._legendloc)
    18281627
    18291628    def _plottp(self,scan):
     
    18621661        x = arange(len(y))
    18631662        # try to handle spectral data somewhat...
    1864         try:
    1865             l,m = y.shape
    1866         except ValueError, e:
    1867                 raise ValueError(str(e)+" This error usually occurs when you select multiple spws with different number of channels. Try selecting single spw and retry.")
     1663        l,m = y.shape
    18681664        if m > 1:
    18691665            y=y.mean(axis=1)
    1870         # flag handling
    1871         m = [ scan._is_all_chan_flagged(i) for i in range(scan.nrow()) ]
    1872         y = ma.masked_array(y,mask=m)
    18731666        plotit = self._plotter.plot
    18741667        llbl = self._get_label(scan, r, self._stacking, None)
     
    19081701            selstr += '\n'
    19091702            self._headtext['selstr'] = selstr
    1910         #ssel=(selstr+self._data.get_selection().__str__()+self._selection.__str__() or 'none')
    1911         curr_selstr = selstr+self._data.get_selection().__str__() or "none"
    1912         ssel=(curr_selstr+"\n" +self._selection.__str__())
    1913         headstr.append('\n\n***Selections***\n'+ssel.replace('$','\$'))
     1703        ssel=(selstr+self._data.get_selection().__str__()+self._selection.__str__() or 'none')
     1704        headstr.append('***Selections***\n'+ssel)
    19141705
    19151706        if plot:
     
    19611752    # plot spectra by pointing
    19621753    @asaplog_post_dec
    1963     def plotgrid(self, scan=None,center="",spacing=[],rows=None,cols=None):
     1754    def plotgrid(self, scan=None,center=None,spacing=None,rows=None,cols=None):
    19641755        """
    19651756        Plot spectra based on direction.
     
    19671758        Parameters:
    19681759            scan:      a scantable to plot
    1969             center:    the grid center direction (a string)
     1760            center:    the grid center direction (a list) of plots in the
     1761                       unit of DIRECTION column.
    19701762                       (default) the center of map region
    1971                        (example) 'J2000 19h30m00s -25d00m00s'
    19721763            spacing:   a list of horizontal (R.A.) and vertical (Dec.)
    1973                        spacing.
     1764                       spacing in the unit of DIRECTION column.
    19741765                       (default) Calculated by the extent of map region and
    1975                        (example) ['1arcmin', '1arcmin']
    19761766                       the number of rows and cols to cover
    19771767            rows:      number of panels (grid points) in horizontal direction
     
    19971787
    19981788        # Rows and cols
    1999         if (self._rows is None):
    2000             rows = max(1, rows)
    2001         if (self._cols is None):
    2002             cols = max(1, cols)
    2003         self.set_layout(rows,cols,False)
    2004 
    2005         # Select the first IF, POL, and BEAM for plotting
     1789        if rows:
     1790            self._rows = int(rows)
     1791        else:
     1792            msg = "Number of rows to plot are not specified. "
     1793            if self._rows:
     1794                msg += "Using previous value = %d" % (self._rows)
     1795                asaplog.push(msg)
     1796            else:
     1797                self._rows = 1
     1798                msg += "Setting rows = %d" % (self._rows)
     1799                asaplog.post()
     1800                asaplog.push(msg)
     1801                asaplog.post("WARN")
     1802        if cols:
     1803            self._cols = int(cols)
     1804        else:
     1805            msg = "Number of cols to plot are not specified. "
     1806            if self._cols:
     1807                msg += "Using previous value = %d" % (self._cols)
     1808                asaplog.push(msg)
     1809            else:
     1810                self._cols = 1
     1811                msg += "Setting cols = %d" % (self._cols)
     1812                asaplog.post()
     1813                asaplog.push(msg)
     1814                asaplog.post("WARN")
     1815
     1816        # Center and spacing
     1817        dirarr = array(self._data.get_directionval()).transpose()
     1818        print "Pointing range: (x, y) = (%f - %f, %f - %f)" %\
     1819              (dirarr[0].min(),dirarr[0].max(),dirarr[1].min(),dirarr[1].max())
     1820        dircent = [0.5*(dirarr[0].max() + dirarr[0].min()),
     1821                   0.5*(dirarr[1].max() + dirarr[1].min())]
     1822        del dirarr
     1823        if center is None:
     1824            #asaplog.post()
     1825            asaplog.push("Grid center is not specified. Automatically calculated from pointing center.")
     1826            #asaplog.post("WARN")
     1827            #center = [dirarr[0].mean(), dirarr[1].mean()]
     1828            center = dircent
     1829        elif (type(center) in (list, tuple)) and len(center) > 1:
     1830            from numpy import pi
     1831            # make sure center_x is in +-pi of pointing center
     1832            # (assumes dirs are in rad)
     1833            rotnum = round(abs(center[0] - dircent[0])/(2*pi))
     1834            if center[0] < dircent[0]: rotnum *= -1
     1835            cenx = center[0] - rotnum*2*pi
     1836            center = [cenx, center[1]]
     1837        else:
     1838            msg = "Direction of grid center should be a list of float (R.A., Dec.)"
     1839            raise ValueError, msg
     1840        asaplog.push("Grid center: (%f, %f) " % (center[0],center[1]))
     1841
     1842        if spacing is None:
     1843            #asaplog.post()
     1844            asaplog.push("Grid spacing not specified. Automatically calculated from map coverage")
     1845            #asaplog.post("WARN")
     1846            # automatically get spacing
     1847            dirarr = array(self._data.get_directionval()).transpose()
     1848            wx = 2. * max(abs(dirarr[0].max()-center[0]),
     1849                          abs(dirarr[0].min()-center[0]))
     1850            wy = 2. * max(abs(dirarr[1].max()-center[1]),
     1851                          abs(dirarr[1].min()-center[1]))
     1852            ## slightly expand area to plot the edges
     1853            #wx *= 1.1
     1854            #wy *= 1.1
     1855            xgrid = wx/max(self._cols-1.,1.)
     1856            #xgrid = wx/float(max(self._cols,1.))
     1857            xgrid *= cos(center[1])
     1858            ygrid = wy/max(self._rows-1.,1.)
     1859            #ygrid = wy/float(max(self._rows,1.))
     1860            # single pointing (identical R.A. and/or Dec. for all spectra.)
     1861            if xgrid == 0:
     1862                xgrid = 1.
     1863            if ygrid == 0:
     1864                ygrid = 1.
     1865            # spacing should be negative to transpose plot
     1866            spacing = [- xgrid, - ygrid]
     1867            del dirarr, xgrid, ygrid
     1868        #elif isinstance(spacing, str):
     1869        #    # spacing is a quantity
     1870        elif (type(spacing) in (list, tuple)) and len(spacing) > 1:
     1871            for i in xrange(2):
     1872                val = spacing[i]
     1873                if not isinstance(val, float):
     1874                    raise TypeError("spacing should be a list of float")
     1875                if val > 0.:
     1876                    spacing[i] = -val
     1877            spacing = spacing[0:2]
     1878        else:
     1879            msg = "Invalid spacing."
     1880            raise TypeError(msg)
     1881        asaplog.push("Spacing: (%f, %f) (projected)" % (spacing[0],spacing[1]))
     1882
    20061883        ntotpl = self._rows * self._cols
    20071884        ifs = self._data.getifnos()
     
    20301907            asaplog.push(msg)
    20311908            asaplog.post("WARN")
    2032 
    2033         # Prepare plotter
     1909       
    20341910        self._assert_plotter(action="reload")
    20351911        self._plotter.hold()
     
    20471923        from asap._asap import plothelper as plhelper
    20481924        ph = plhelper(self._data)
    2049         #ph.set_gridval(self._cols, self._rows, spacing[0], spacing[1],
    2050         #                  center[0], center[1], epoch="J2000", projname="SIN")
    2051         if type(spacing) in (list, tuple, array):
    2052             if len(spacing) == 0:
    2053                 spacing = ["", ""]
    2054             elif len(spacing) == 1:
    2055                 spacing = [spacing[0], spacing[0]]
    2056         else:
    2057             spacing = [spacing, spacing]
    2058         ph.set_grid(self._cols, self._rows, spacing[0], spacing[1], \
    2059                     center, projname="SIN")
    2060 
     1925        ph.set_gridval(self._cols, self._rows, spacing[0], spacing[1],
     1926                          center[0], center[1], epoch="J2000", projname="SIN")
    20611927        # Actual plot
    20621928        npl = 0
  • trunk/python/customgui_base.py

    r3112 r2704  
    11import os
    2 import weakref
    32import matplotlib, numpy
    43from asap.logging import asaplog, asaplog_post_dec
     
    1413class CustomToolbarCommon:
    1514    def __init__(self,parent):
    16         self.plotter = weakref.ref(parent)
     15        self.plotter = parent
    1716        #self.figmgr=self.plotter._plotter.figmgr
    18 
    19     def _get_plotter(self):
    20         # check for the validity of the plotter and
    21         # return the plotter class instance if its valid.
    22         if self.plotter() is None:
    23             raise RuntimeError, "Internal Error. The plotter has been destroyed."
    24         else:
    25             return self.plotter()
    2617
    2718    ### select the nearest spectrum in pick radius
     
    3829        if event.button != 1:
    3930            return
    40 
    41         # check for the validity of plotter and get the plotter
    42         theplotter = self._get_plotter()
    4331
    4432        xclick = event.xdata
     
    7462        del pind, inds, xlin, ylin
    7563        # Spectra are Picked
    76         theplot = theplotter._plotter
     64        theplot = self.plotter._plotter
    7765        thetoolbar = self.figmgr.toolbar
    7866        thecanvas = self.figmgr.canvas
     
    166154            return
    167155
    168         # check for the validity of plotter and get the plotter
    169         theplotter = self._get_plotter()
    170 
    171156        self._thisregion = {'axes': event.inaxes,'xs': event.x,
    172157                            'worldx': [event.xdata,event.xdata],
     
    175160        self.xdataold = event.xdata
    176161
    177         theplotter._plotter.register('button_press',None)
    178         theplotter._plotter.register('motion_notify', self._xspan_draw)
    179         theplotter._plotter.register('button_press', self._xspan_end)
     162        self.plotter._plotter.register('button_press',None)
     163        self.plotter._plotter.register('motion_notify', self._xspan_draw)
     164        self.plotter._plotter.register('button_press', self._xspan_end)
    180165
    181166    def _xspan_draw(self,event):
     
    218203            xdataend = self.xdataold
    219204
    220         # check for the validity of plotter and get the plotter
    221         theplotter = self._get_plotter()
    222 
    223205        self._thisregion['worldx'][1] = xdataend
    224206        # print statistics of spectra in subplot
     
    226208       
    227209        # release event
    228         theplotter._plotter.register('button_press',None)
    229         theplotter._plotter.register('motion_notify',None)
     210        self.plotter._plotter.register('button_press',None)
     211        self.plotter._plotter.register('motion_notify',None)
    230212        # Clear up region selection
    231213        self._thisregion = None
     
    233215        self.xold = None
    234216        # finally recover region selection event
    235         theplotter._plotter.register('button_press',self._single_mask)
     217        self.plotter._plotter.register('button_press',self._single_mask)
    236218
    237219    def _subplot_stats(self,selection):
     
    339321    ### actual plotting of the new page
    340322    def _new_page(self,goback=False):
    341         # check for the validity of plotter and get the plotter
    342         theplotter = self._get_plotter()
    343 
    344323        top = None
    345         header = theplotter._headtext
     324        header = self.plotter._headtext
    346325        reset = False
    347326        doheader = (isinstance(header['textobj'],list) and \
    348327                    len(header['textobj']) > 0)
    349328        if doheader:
    350             top = theplotter._plotter.figure.subplotpars.top
     329            top = self.plotter._plotter.figure.subplotpars.top
    351330            fontsize = header['textobj'][0].get_fontproperties().get_size()
    352         if theplotter._startrow <= 0:
     331        if self.plotter._startrow <= 0:
    353332            msg = "The page counter is reset due to chages of plot settings. "
    354333            msg += "Plotting from the first page."
     
    363342                if header.has_key('selstr'):
    364343                    selstr = header['selstr']
    365             theplotter._reset_header()
    366 
    367         theplotter._plotter.hold()
     344            self.plotter._reset_header()
     345
     346        self.plotter._plotter.hold()
    368347        if goback:
    369348            self._set_prevpage_counter()
    370         #theplotter._plotter.clear()
    371         theplotter._plot(theplotter._data)
     349        #self.plotter._plotter.clear()
     350        self.plotter._plot(self.plotter._data)
    372351        pagenum = self._get_pagenum()
    373352        self.set_pagecounter(pagenum)
     
    375354        #if header['textobj']:
    376355        if doheader and pagenum == 1:
    377             if top and top != theplotter._margins[3]:
     356            if top and top != self.plotter._margins[3]:
    378357                # work around for sdplot in CASA. complete checking in future?
    379                 theplotter._plotter.figure.subplots_adjust(top=top)
     358                self.plotter._plotter.figure.subplots_adjust(top=top)
    380359            if reset:
    381                 theplotter.print_header(plot=True,fontsize=fontsize,selstr=selstr, extrastr=extrastr)
     360                self.plotter.print_header(plot=True,fontsize=fontsize,selstr=selstr, extrastr=extrastr)
    382361            else:
    383                 theplotter._header_plot(header['string'],fontsize=fontsize)
    384         theplotter._plotter.release()
    385         theplotter._plotter.tidy()
    386         theplotter._plotter.show(hardrefresh=False)
     362                self.plotter._header_plot(header['string'],fontsize=fontsize)
     363        self.plotter._plotter.release()
     364        self.plotter._plotter.tidy()
     365        self.plotter._plotter.show(hardrefresh=False)
    387366        del top
    388367
    389368    ### calculate the panel ID and start row to plot the previous page
    390369    def _set_prevpage_counter(self):
    391         # check for the validity of plotter and get the plotter
    392         theplotter = self._get_plotter()
    393 
    394370        # set row and panel counters to those of the 1st panel of previous page
    395371        maxpanel = 16
    396372        # the ID of the last panel in current plot
    397         lastpanel = theplotter._ipanel
     373        lastpanel = self.plotter._ipanel
    398374        # the number of current subplots
    399         currpnum = len(theplotter._plotter.subplots)
     375        currpnum = len(self.plotter._plotter.subplots)
    400376        # the nuber of previous subplots
    401377        prevpnum = None
    402         if theplotter._rows and theplotter._cols:
     378        if self.plotter._rows and self.plotter._cols:
    403379            # when user set layout
    404             prevpnum = theplotter._rows*theplotter._cols
     380            prevpnum = self.plotter._rows*self.plotter._cols
    405381        else:
    406382            # no user specification
     
    409385        start_ipanel = max(lastpanel-currpnum-prevpnum+1, 0)
    410386        # set the pannel ID of the last panel of prev-prev page
    411         theplotter._ipanel = start_ipanel-1
    412         if theplotter._panelling == 'r':
    413             theplotter._startrow = start_ipanel
     387        self.plotter._ipanel = start_ipanel-1
     388        if self.plotter._panelling == 'r':
     389            self.plotter._startrow = start_ipanel
    414390        else:
    415391            # the start row number of the next panel
    416             theplotter._startrow = theplotter._panelrows[start_ipanel]
     392            self.plotter._startrow = self.plotter._panelrows[start_ipanel]
    417393        del lastpanel,currpnum,prevpnum,start_ipanel
    418394
     
    429405
    430406    def _get_pagenum(self):
    431         # check for the validity of plotter and get the plotter
    432         theplotter = self._get_plotter()
    433        
    434407        # get the ID of last panel in the current page
    435         idlastpanel = theplotter._ipanel
     408        idlastpanel = self.plotter._ipanel
    436409        # max panels in a page
    437         ppp = theplotter._plotter.rows*theplotter._plotter.cols
     410        ppp = self.plotter._plotter.rows*self.plotter._plotter.cols
    438411        return int(idlastpanel/ppp)+1
    439412
     
    710683class CustomFlagToolbarCommon:
    711684    def __init__(self,parent):
    712         self.plotter=weakref.ref(parent)
     685        self.plotter=parent
    713686        #self.figmgr=self.plotter._plotter.figmgr
    714687        self._selregions = {}
     
    718691        self.xdataold=None
    719692
    720     def _get_plotter(self):
    721         # check for the validity of the plotter and
    722         # return the plotter class instance if its valid.
    723         if self.plotter() is None:
    724             raise RuntimeError, "Internal Error. The plotter has been destroyed."
    725         else:
    726             return self.plotter()
    727 
    728693    ### select the nearest spectrum in pick radius
    729694    ###    and display spectral value on the toolbar.
     
    739704        if event.button != 1:
    740705            return
    741 
    742         # check for the validity of plotter and get the plotter
    743         theplotter = self._get_plotter()
    744706
    745707        xclick = event.xdata
     
    775737        del pind, inds, xlin, ylin
    776738        # Spectra are Picked
    777         theplot = theplotter._plotter
     739        theplot = self.plotter._plotter
    778740        thetoolbar = self.figmgr.toolbar
    779741        thecanvas = self.figmgr.canvas
     
    857819        if event.button != 1 or event.inaxes == None:
    858820            return
    859         # check for the validity of plotter and get the plotter
    860         theplotter = self._get_plotter()
    861821        # this row resolution assumes row panelling
    862822        irow = int(self._getrownum(event.inaxes))
     
    869829        self._thisregion = {'axes': event.inaxes,'xs': event.x,
    870830                            'worldx': [event.xdata,event.xdata]}
    871         theplotter._plotter.register('button_press',None)
     831        self.plotter._plotter.register('button_press',None)
    872832        self.xold = event.x
    873833        self.xdataold = event.xdata
    874         theplotter._plotter.register('motion_notify', self._xspan_draw)
    875         theplotter._plotter.register('button_press', self._xspan_end)
     834        self.plotter._plotter.register('motion_notify', self._xspan_draw)
     835        self.plotter._plotter.register('button_press', self._xspan_end)
    876836
    877837    def _xspan_draw(self,event):
     
    922882        self._thisregion['axes'].set_xlim(axlimx)
    923883       
    924         # check for the validity of plotter and get the plotter
    925         theplotter = self._get_plotter()
    926 
    927         theplotter._plotter.canvas.draw()
     884        self.plotter._plotter.canvas.draw()
    928885        self._polygons.append(pregion)
    929886        srow = self._getrownum(self._thisregion['axes'])
     
    938895
    939896        # release event
    940         theplotter._plotter.register('button_press',None)
    941         theplotter._plotter.register('motion_notify',None)
     897        self.plotter._plotter.register('button_press',None)
     898        self.plotter._plotter.register('motion_notify',None)
    942899        # Clear up region selection
    943900        self._thisregion = None
     
    945902        self.xold = None
    946903        # finally recover region selection event
    947         theplotter._plotter.register('button_press',self._add_region)
     904        self.plotter._plotter.register('button_press',self._add_region)
    948905
    949906    ### add panels to selections
     
    954911        if event.button != 1 or event.inaxes == None:
    955912            return
    956         # check for the validity of plotter and get the plotter
    957         theplotter = self._get_plotter()
    958 
    959913        selax = event.inaxes
    960914        # this row resolution assumes row panelling
     
    965919        shadow = Rectangle((0,0),1,1,facecolor='0.7',transform=selax.transAxes,visible=True)
    966920        self._polygons.append(selax.add_patch(shadow))
    967         #theplotter._plotter.show(False)
    968         theplotter._plotter.canvas.draw()
     921        #self.plotter._plotter.show(False)
     922        self.plotter._plotter.canvas.draw()
    969923        asaplog.push("row "+str(irow)+" is selected")
    970924        ## check for region selection of the spectra and overwrite it.
     
    1002956            asaplog.push("Invalid panel specification")
    1003957            asaplog.post('ERROR')
    1004 
    1005         # check for the validity of plotter and get the plotter
    1006         theplotter = self._get_plotter()
    1007 
    1008         strow = self._getrownum(theplotter._plotter.subplots[0]['axes'])
    1009         enrow = self._getrownum(theplotter._plotter.subplots[-1]['axes'])
     958        strow = self._getrownum(self.plotter._plotter.subplots[0]['axes'])
     959        enrow = self._getrownum(self.plotter._plotter.subplots[-1]['axes'])
    1010960        for irow in range(int(strow),int(enrow)+1):
    1011961            if regions.has_key(str(irow)):
    1012                 ax = theplotter._plotter.subplots[irow - int(strow)]['axes']
     962                ax = self.plotter._plotter.subplots[irow - int(strow)]['axes']
    1013963                mlist = regions.pop(str(irow))
    1014964                # WORKAROUND for the issue axvspan started to reset xlim.
     
    1020970                del ax,mlist,axlimx
    1021971            if irow in panels:
    1022                 ax = theplotter._plotter.subplots[irow - int(strow)]['axes']
     972                ax = self.plotter._plotter.subplots[irow - int(strow)]['axes']
    1023973                shadow = Rectangle((0,0),1,1,facecolor='0.7',
    1024974                                   transform=ax.transAxes,visible=True)
    1025975                self._polygons.append(ax.add_patch(shadow))
    1026976                del ax,shadow
    1027         theplotter._plotter.canvas.draw()
     977        self.plotter._plotter.canvas.draw()
    1028978        del regions,panels,strow,enrow
    1029979
     
    1033983            for shadow in self._polygons:
    1034984                shadow.remove()
    1035             if refresh:
    1036                 # check for the validity of plotter and get the plotter
    1037                 theplotter = self._get_plotter()
    1038                 theplotter._plotter.canvas.draw()
     985            if refresh: self.plotter._plotter.canvas.draw()
    1039986        self._polygons = []
    1040987
     
    10601007            asaplog.post('WARN')
    10611008            return
    1062 
    10631009        self._pause_buttons(operation="start",msg="Flagging data...")
    10641010        self._flag_operation(rows=self._selpanels,
     
    10691015        asaplog.push(sout)
    10701016        del sout
    1071         # check for the validity of plotter and get the plotter
    1072         theplotter = self._get_plotter()
    1073 
    1074         theplotter._ismodified = True
     1017        self.plotter._ismodified = True
    10751018        self._clearup_selections(refresh=False)
    10761019        self._plot_page(pagemode="current")
     
    10931036        asaplog.push(sout)
    10941037        del sout
    1095 
    1096         # check for the validity of plotter and get the plotter
    1097         theplotter = self._get_plotter()
    1098         theplotter._ismodified = True
     1038        self.plotter._ismodified = True
    10991039        self._clearup_selections(refresh=False)
    11001040        self._plot_page(pagemode="current")
     
    11041044    @asaplog_post_dec
    11051045    def _flag_operation(self,rows=None,regions=None,unflag=False):
    1106         # check for the validity of plotter and get the plotter
    1107         theplotter = self._get_plotter()
    1108 
    1109         scan = theplotter._data
     1046        scan = self.plotter._data
    11101047        if not scan:
    11111048            asaplog.post()
     
    11421079    @asaplog_post_dec
    11431080    def _selected_stats(self,rows=None,regions=None):
    1144         # check for the validity of plotter and get the plotter
    1145         theplotter = self._get_plotter()
    1146 
    1147         scan = theplotter._data
     1081        scan = self.plotter._data
    11481082        if not scan:
    11491083            asaplog.post()
     
    12301164    ### actual plotting of the new page
    12311165    def _plot_page(self,pagemode="next"):
    1232         # check for the validity of plotter and get the plotter
    1233         theplotter = self._get_plotter()
    1234         if theplotter._startrow <= 0:
     1166        if self.plotter._startrow <= 0:
    12351167            msg = "The page counter is reset due to chages of plot settings. "
    12361168            msg += "Plotting from the first page."
     
    12401172            goback = False
    12411173
    1242         theplotter._plotter.hold()
    1243         #theplotter._plotter.legend(1)
     1174        self.plotter._plotter.hold()
     1175        #self.plotter._plotter.legend(1)
    12441176        self._set_plot_counter(pagemode)
    1245         theplotter._plot(theplotter._data)
     1177        self.plotter._plot(self.plotter._data)
    12461178        self.set_pagecounter(self._get_pagenum())
    1247         theplotter._plotter.release()
    1248         theplotter._plotter.tidy()
    1249         theplotter._plotter.show(hardrefresh=False)
     1179        self.plotter._plotter.release()
     1180        self.plotter._plotter.tidy()
     1181        self.plotter._plotter.show(hardrefresh=False)
    12501182
    12511183    ### calculate the panel ID and start row to plot a page
     
    12621194            # nothing necessary to plot the next page
    12631195            return
    1264 
    1265         # check for the validity of plotter and get the plotter
    1266         theplotter = self._get_plotter()
    1267 
    12681196        # set row and panel counters to those of the 1st panel of previous page
    12691197        maxpanel = 25
    12701198        # the ID of the last panel in current plot
    1271         lastpanel = theplotter._ipanel
     1199        lastpanel = self.plotter._ipanel
    12721200        # the number of current subplots
    1273         currpnum = len(theplotter._plotter.subplots)
     1201        currpnum = len(self.plotter._plotter.subplots)
    12741202
    12751203        # the nuber of previous subplots
     
    12801208            ## previous page
    12811209            prevpnum = None
    1282             if theplotter._rows and theplotter._cols:
     1210            if self.plotter._rows and self.plotter._cols:
    12831211                # when user set layout
    1284                 prevpnum = theplotter._rows*theplotter._cols
     1212                prevpnum = self.plotter._rows*self.plotter._cols
    12851213            else:
    12861214                # no user specification
     
    12901218
    12911219        # set the pannel ID of the last panel of the prev(-prev) page
    1292         theplotter._ipanel = start_ipanel-1
    1293         if theplotter._panelling == 'r':
    1294             theplotter._startrow = start_ipanel
     1220        self.plotter._ipanel = start_ipanel-1
     1221        if self.plotter._panelling == 'r':
     1222            self.plotter._startrow = start_ipanel
    12951223        else:
    12961224            # the start row number of the next panel
    1297             theplotter._startrow = theplotter._panelrows[start_ipanel]
     1225            self.plotter._startrow = self.plotter._panelrows[start_ipanel]
    12981226        del lastpanel,currpnum,start_ipanel
    12991227
     
    13101238
    13111239    def _get_pagenum(self):
    1312         # check for the validity of plotter and get the plotter
    1313         theplotter = self._get_plotter()
    13141240        # get the ID of last panel in the current page
    1315         idlastpanel = theplotter._ipanel
     1241        idlastpanel = self.plotter._ipanel
    13161242        # max panels in a page
    1317         ppp = theplotter._plotter.rows*theplotter._plotter.cols
     1243        ppp = self.plotter._plotter.rows*self.plotter._plotter.cols
    13181244        return int(idlastpanel/ppp)+1
    13191245
  • trunk/python/env.py

    r3112 r2704  
    22"""
    33__all__ = ["is_casapy", "is_ipython", "setup_env", "get_revision",
    4            "is_asap_cli", "get_asap_revdate"]
     4           "is_asap_cli"]
    55
    66import sys
     
    5252        os.environ["CASAPATH"] = "%s %s somwhere" % ( asapdata, plf)
    5353
    54 def get_revinfo_file():
     54def get_revision():
    5555    """Get the revision of the software. Only useful within casapy."""
    5656    if not is_casapy:
     
    5959    versioninfo = sys.version_info
    6060    pyversion = '%s.%s'%(versioninfo[0],versioninfo[1])
    61     revinfo = None
    6261    if os.path.isdir(casapath[0]+'/'+casapath[1]+'/python/%s/asap'%(pyversion)):
    6362        # for casa developer environment (linux or darwin)
     
    6968        else:
    7069            revinfo=casapath[0]+'/lib/python%s/asap/svninfo.txt'%(pyversion)
    71     return revinfo
    72 
    73 def get_revision():
    74     revinfo=get_revinfo_file()
    7570    if os.path.isfile(revinfo):
    7671        f = file(revinfo)
     
    8075        return revsionno.rstrip()
    8176    return ' unknown '
    82 
    83 
    84 def get_asap_revdate():
    85     revinfo=get_revinfo_file()
    86     if os.path.isfile(revinfo):
    87         f = file(revinfo)
    88         f.readline()
    89         f.readline()
    90         revdate=f.readline()
    91         return revdate.rstrip().lstrip()
    92     return 'unknown'
    93 
    94 
  • trunk/python/sbseparator.py

    r3112 r2704  
    99from asap.selector import selector
    1010from asap.asapgrid import asapgrid2
    11 from asap._asap import SBSeparator
     11#from asap._asap import sidebandsep
    1212
    1313class sbseparator:
     
    2121      information in scantable in sideband sparation. Frequency
    2222      setting of SIGNAL sideband is stored in output table for now.
     23    - Flag information (stored in FLAGTRA) is ignored.
    2324
    2425    Example:
     
    3738    """
    3839    def __init__(self, infiles):
    39         self._separator = SBSeparator(infiles)
    40 
    41 
     40        self.intables = None
     41        self.signalShift = []
     42        self.imageShift = []
     43        self.dsbmode = True
     44        self.getboth = False
     45        self.rejlimit = 0.2
     46        self.baseif = -1
     47        self.freqtol = 10.
     48        self.freqframe = ""
     49        self.solveother = False
     50        self.dirtol = [1.e-5, 1.e-5] # direction tolerance in rad (2 arcsec)
     51
     52        self.tables = []
     53        self.nshift = -1
     54        self.nchan = -1
     55
     56        self.set_data(infiles)
     57       
     58        #self.separator = sidebandsep()
     59
     60    @asaplog_post_dec
     61    def set_data(self, infiles):
     62        """
     63        Set data to be processed.
     64
     65        infiles  : a list of filenames or scantables
     66        """
     67        if not (type(infiles) in (list, tuple, numpy.ndarray)):
     68            infiles = [infiles]
     69        if isinstance(infiles[0], scantable):
     70            # a list of scantable
     71            for stab in infiles:
     72                if not isinstance(stab, scantable):
     73                    asaplog.post()
     74                    raise TypeError, "Input data is not a list of scantables."
     75
     76            #self.separator._setdata(infiles)
     77            self._reset_data()
     78            self.intables = infiles
     79        else:
     80            # a list of filenames
     81            for name in infiles:
     82                if not os.path.exists(name):
     83                    asaplog.post()
     84                    raise ValueError, "Could not find input file '%s'" % name
     85           
     86            #self.separator._setdataname(infiles)
     87            self._reset_data()
     88            self.intables = infiles
     89
     90        asaplog.push("%d files are set to process" % len(self.intables))
     91
     92
     93    def _reset_data(self):
     94        del self.intables
     95        self.intables = None
     96        self.signalShift = []
     97        #self.imageShift = []
     98        self.tables = []
     99        self.nshift = -1
     100        self.nchan = -1
     101
     102    @asaplog_post_dec
    42103    def set_frequency(self, baseif, freqtol, frame=""):
    43104        """
     
    46107        Parameters:
    47108          - reference IFNO to process in the first table in the list
    48           - frequency tolerance from reference IF to select data (string)
     109          - frequency tolerance from reference IF to select data
    49110          frame  : frequency frame to select IF
    50111        """
    51         if type(freqtol) in (float, int):
    52             freqtol = str(freqtol)
    53         elif isinstance(freqtol, dict):
    54             try:
    55                 freqtol = str(freqtol['value']) + freqtol['unit']
    56             except:
    57                 raise ValueError, "Invalid frequency tolerance."
    58         self._separator.set_freq(baseif, freqtol, frame)
    59 
    60 
    61     def set_dirtol(self, dirtol=["2arcsec", "2arcsec"]):
     112        self._reset_if()
     113        self.baseif = baseif
     114        if isinstance(freqtol,dict) and freqtol["unit"] == "Hz":
     115            if freqtol['value'] > 0.:
     116                self.freqtol = freqtol
     117            else:
     118                asaplog.post()
     119                asaplog.push("Frequency tolerance should be positive value.")
     120                asaplog.post("ERROR")
     121                return
     122        else:
     123            # torelance in channel unit
     124            if freqtol > 0:
     125                self.freqtol = float(freqtol)
     126            else:
     127                asaplog.post()
     128                asaplog.push("Frequency tolerance should be positive value.")
     129                asaplog.post("ERROR")
     130                return
     131        self.freqframe = frame
     132
     133    def _reset_if(self):
     134        self.baseif = -1
     135        self.freqtol = 0
     136        self.freqframe = ""
     137        self.signalShift = []
     138        #self.imageShift = []
     139        self.tables = []
     140        self.nshift = 0
     141        self.nchan = -1
     142
     143    @asaplog_post_dec
     144    def set_dirtol(self, dirtol=[1.e-5,1.e-5]):
    62145        """
    63146        Set tolerance of direction to select data
    64147        """
    65         if isinstance(dirtol, str):
    66             dirtol = [dirtol]
    67 
    68         self._separator.set_dirtol(dirtol)
    69    
    70            
    71     def set_shift(self, imageshift=[]):
     148        # direction tolerance in rad
     149        if not (type(dirtol) in [list, tuple, numpy.ndarray]):
     150            dirtol = [dirtol, dirtol]
     151        if len(dirtol) == 1:
     152            dirtol = [dirtol[0], dirtol[0]]
     153        if len(dirtol) > 1:
     154            self.dirtol = dirtol[0:2]
     155        else:
     156            asaplog.post()
     157            asaplog.push("Invalid direction tolerance. Should be a list of float in unit radian")
     158            asaplog.post("ERROR")
     159            return
     160        asaplog.post("Set direction tolerance [%f, %f] (rad)" % \
     161                     (self.dirtol[0], self.dirtol[1]))
     162
     163    @asaplog_post_dec
     164    def set_shift(self, mode="DSB", imageshift=None):
    72165        """
    73166        Set shift mode and channel shift of image band.
    74167
    75         imageshift : a list of number of channels shifted in image
    76                      side band of each scantable.
    77                      If the shifts are not set, they are assumed to be
    78                      equal to those of signal side band, but in opposite
    79                      direction as usual by LO1 offsetting of DSB receivers.
    80         """
    81         if not imageshift:
    82             imageshift = []
    83         self._separator.set_shift(imageshift)
    84 
     168        mode       : shift mode ['DSB'|'SSB']
     169                     When mode='DSB', imageshift is assumed to be equal
     170                     to the shift of signal sideband but in opposite direction.
     171        imageshift : a list of number of channel shift in image band of
     172                     each scantable. valid only mode='SSB'
     173        """
     174        if mode.upper().startswith("S"):
     175            if not imageshift:
     176                raise ValueError, "Need to set shift value of image sideband"
     177            self.dsbmode = False
     178            self.imageShift = imageshift
     179            asaplog.push("Image sideband shift is set manually: %s" % str(self.imageShift))
     180        else:
     181            # DSB mode
     182            self.dsbmode = True
     183            self.imageShift = []
    85184
    86185    @asaplog_post_dec
     
    89188        Resolve both image and signal sideband when True.
    90189        """
    91         self._separator.solve_both(flag)
    92         if flag:
    93             asaplog.push("Both signal and image sidebands will be solved and stored in separate tables.")
    94         else:
    95             asaplog.push("Only signal sideband will be solved and stored in an table.")
     190        self.getboth = flag
     191        if self.getboth:
     192            asaplog.push("Both signal and image sidebands are solved and output as separate tables.")
     193        else:
     194            asaplog.push("Only signal sideband is solved and output as an table.")
    96195
    97196    @asaplog_post_dec
     
    100199        Set rejection limit of solution.
    101200        """
    102         self._separator.set_limit(threshold)
     201        #self.separator._setlimit(abs(threshold))
     202        self.rejlimit = threshold
     203        asaplog.push("The threshold of rejection is set to %f" % self.rejlimit)
    103204
    104205
     
    109210        when True.
    110211        """
    111         self._separator.subtract_other(flag)
     212        self.solveother = flag
    112213        if flag:
    113214            asaplog.push("Expert mode: solution are obtained by subtraction of the other sideband.")
    114215
    115216
    116     def set_lo1(self, lo1, frame="TOPO", reftime=-1, refdir=""):
    117         """
    118         Set LO1 frequency to calculate frequency of image sideband.
    119 
    120         lo1     : LO1 frequency
    121         frame   : the frequency frame of LO1
    122         reftime : the reference time used in frequency frame conversion.
    123         refdir  : the reference direction used in frequency frame conversion.
    124         """
    125         self._separator.set_lo1(lo1, frame, reftime, refdir)
    126 
    127 
    128     def set_lo1root(self, name):
    129         """
    130         Set MS name which stores LO1 frequency of signal side band.
    131         It is used to calculate frequency of image sideband.
    132 
    133         name : MS name which contains 'ASDM_SPECTRALWINDOW' and
    134                'ASDM_RECEIVER' tables.
    135         """
    136         self._separator.set_lo1root(name)
    137 
    138217    @asaplog_post_dec
    139218    def separate(self, outname="", overwrite=False):
     
    144223        overwrite : overwrite existing table
    145224        """
    146         out_default = "sbseparated.asap"
    147         if len(outname) == 0:
    148             outname = out_default
    149             asaplog.post()
    150             asaplog.push("The output file name is not specified.")
    151             asaplog.push("Using default name '%s'" % outname)
     225        # List up valid scantables and IFNOs to convolve.
     226        #self.separator._separate()
     227        self._setup_shift()
     228        #self._preprocess_tables()
     229
     230        nshift = len(self.tables)
     231        signaltab = self._grid_outtable(self.tables[0].copy())
     232        if self.getboth:
     233            imagetab = signaltab.copy()
     234
     235        rejrow = []
     236        for irow in xrange(signaltab.nrow()):
     237            currpol = signaltab.getpol(irow)
     238            currbeam = signaltab.getbeam(irow)
     239            currdir = signaltab.get_directionval(irow)
     240            spec_array, tabidx = self._get_specarray(polid=currpol,\
     241                                                     beamid=currbeam,\
     242                                                     dir=currdir)
     243            #if not spec_array:
     244            if len(tabidx) == 0:
     245                asaplog.post()
     246                asaplog.push("skipping row %d" % irow)
     247                rejrow.append(irow)
     248                continue
     249            signal = self._solve_signal(spec_array, tabidx)
     250            signaltab.set_spectrum(signal, irow)
     251            if self.getboth:
     252                image = self._solve_image(spec_array, tabidx)
     253                imagetab.set_spectrum(image, irow)
     254       
     255        # TODO: Need to remove rejrow form scantables here
     256        signaltab.flag_row(rejrow)
     257        if self.getboth:
     258            imagetab.flag_row(rejrow)
     259       
     260        if outname == "":
     261            outname = "sbsepareted.asap"
     262        signalname = outname + ".signalband"
     263        if os.path.exists(signalname):
     264            if not overwrite:
     265                raise Exception, "Output file '%s' exists." % signalname
     266            else:
     267                shutil.rmtree(signalname)
     268        signaltab.save(signalname)
     269        if self.getboth:
     270            # Warnings
     271            asaplog.post()
     272            asaplog.push("Saving IMAGE sideband.")
     273            asaplog.push("Note, frequency information of IMAGE sideband cannot be properly filled so far. (future development)")
     274            asaplog.push("Storing frequency setting of SIGNAL sideband in FREQUENCIES table for now.")
    152275            asaplog.post("WARN")
    153276
    154         if os.path.exists(outname):
    155             if overwrite:
    156                 asaplog.push("removing the old file '%s'" % outname)
    157                 shutil.rmtree(outname)
     277            imagename = outname + ".imageband"
     278            if os.path.exists(imagename):
     279                if not overwrite:
     280                    raise Exception, "Output file '%s' exists." % imagename
     281                else:
     282                    shutil.rmtree(imagename)
     283            imagetab.save(imagename)
     284
     285
     286    def _solve_signal(self, data, tabidx=None):
     287        if not tabidx:
     288            tabidx = range(len(data))
     289
     290        tempshift = []
     291        dshift = []
     292        if self.solveother:
     293            for idx in tabidx:
     294                tempshift.append(-self.imageShift[idx])
     295                dshift.append(self.signalShift[idx] - self.imageShift[idx])
     296        else:
     297            for idx in tabidx:
     298                tempshift.append(-self.signalShift[idx])
     299                dshift.append(self.imageShift[idx] - self.signalShift[idx])
     300
     301        shiftdata = numpy.zeros(data.shape, numpy.float)
     302        for i in range(len(data)):
     303            shiftdata[i] = self._shiftSpectrum(data[i], tempshift[i])
     304        ifftdata = self._Deconvolution(shiftdata, dshift, self.rejlimit)
     305        result_image = self._combineResult(ifftdata)
     306        if not self.solveother:
     307            return result_image
     308        result_signal = self._subtractOtherSide(shiftdata, dshift, result_image)
     309        return result_signal
     310
     311
     312    def _solve_image(self, data, tabidx=None):
     313        if not tabidx:
     314            tabidx = range(len(data))
     315
     316        tempshift = []
     317        dshift = []
     318        if self.solveother:
     319            for idx in tabidx:
     320                tempshift.append(-self.signalShift[idx])
     321                dshift.append(self.imageShift[idx] - self.signalShift[idx])
     322        else:
     323            for idx in tabidx:
     324                tempshift.append(-self.imageShift[idx])
     325                dshift.append(self.signalShift[idx] - self.imageShift[idx])
     326
     327        shiftdata = numpy.zeros(data.shape, numpy.float)
     328        for i in range(len(data)):
     329            shiftdata[i] = self._shiftSpectrum(data[i], tempshift[i])
     330        ifftdata = self._Deconvolution(shiftdata, dshift, self.rejlimit)
     331        result_image = self._combineResult(ifftdata)
     332        if not self.solveother:
     333            return result_image
     334        result_signal = self._subtractOtherSide(shiftdata, dshift, result_image)
     335        return result_signal
     336
     337    @asaplog_post_dec
     338    def _grid_outtable(self, table):
     339        # Generate gridded table for output (Just to get rows)
     340        gridder = asapgrid2(table)
     341        gridder.setIF(self.baseif)
     342       
     343        cellx = str(self.dirtol[0])+"rad"
     344        celly = str(self.dirtol[1])+"rad"
     345        dirarr = numpy.array(table.get_directionval()).transpose()
     346        mapx = dirarr[0].max() - dirarr[0].min()
     347        mapy = dirarr[1].max() - dirarr[1].min()
     348        nx = max(1, numpy.ceil(mapx/self.dirtol[0]))
     349        ny = max(1, numpy.ceil(mapy/self.dirtol[0]))
     350
     351        asaplog.push("Regrid output scantable with cell = [%s, %s]" % \
     352                     (cellx, celly))
     353        gridder.defineImage(nx=nx, ny=ny, cellx=cellx, celly=celly)
     354        gridder.setFunc(func='box', convsupport=1)
     355        gridder.setWeight(weightType='uniform')
     356        gridder.grid()
     357        return gridder.getResult()
     358
     359    @asaplog_post_dec
     360    def _get_specarray(self, polid=None, beamid=None, dir=None):
     361        ntable = len(self.tables)
     362        spec_array = numpy.zeros((ntable, self.nchan), numpy.float)
     363        nspec = 0
     364        asaplog.push("Start data selection by POL=%d, BEAM=%d, direction=[%f, %f]" % (polid, beamid, dir[0], dir[1]))
     365        tabidx = []
     366        for itab in range(ntable):
     367            tab = self.tables[itab]
     368            # Select rows by POLNO and BEAMNO
     369            try:
     370                tab.set_selection(pols=[polid], beams=[beamid])
     371                if tab.nrow() > 0: tabidx.append(itab)
     372            except: # no selection
     373                asaplog.post()
     374                asaplog.push("table %d - No spectrum ....skipping the table" % (itab))
     375                asaplog.post("WARN")
     376                continue
     377
     378            # Select rows by direction
     379            spec = numpy.zeros(self.nchan, numpy.float)
     380            selrow = []
     381            for irow in range(tab.nrow()):
     382                currdir = tab.get_directionval(irow)
     383                if (abs(currdir[0] - dir[0]) > self.dirtol[0]) or \
     384                   (abs(currdir[1] - dir[1]) > self.dirtol[1]):
     385                    continue
     386                selrow.append(irow)
     387            if len(selrow) == 0:
     388                asaplog.post()
     389                asaplog.push("table %d - No spectrum ....skipping the table" % (itab))
     390                asaplog.post("WARN")
     391                continue
    158392            else:
    159                 asaplog.post()
    160                 asaplog.push("Output file '%s' already exists." % outname)
     393                seltab = tab.copy()
     394                seltab.set_selection(selector(rows=selrow))
     395           
     396            if tab.nrow() > 1:
     397                asaplog.push("table %d - More than a spectrum selected. averaging rows..." % (itab))
     398                tab = seltab.average_time(scanav=False, weight="tintsys")
     399            else:
     400                tab = seltab
     401
     402            spec_array[nspec] = tab._getspectrum()
     403            nspec += 1
     404
     405        if nspec != ntable:
     406            asaplog.post()
     407            #asaplog.push("Some tables has no spectrum with POL=%d BEAM=%d. averaging rows..." % (polid, beamid))
     408            asaplog.push("Could not find corresponding rows in some tables.")
     409            asaplog.push("Number of spectra selected = %d (table: %d)" % (nspec, ntable))
     410            if nspec < 2:
     411                asaplog.push("At least 2 spectra are necessary for convolution")
    161412                asaplog.post("ERROR")
    162                 return False
    163 
    164         self._separator.separate(outname)
    165 
     413                return False, tabidx
     414
     415        return spec_array[0:nspec], tabidx
     416           
     417
     418    @asaplog_post_dec
     419    def _setup_shift(self):
     420        ### define self.tables, self.signalShift, and self.imageShift
     421        if not self.intables:
     422            asaplog.post()
     423            raise RuntimeError, "Input data is not defined."
     424        #if self.baseif < 0:
     425        #    asaplog.post()
     426        #    raise RuntimeError, "Reference IFNO is not defined."
     427       
     428        byname = False
     429        #if not self.intables:
     430        if isinstance(self.intables[0], str):
     431            # A list of file name is given
     432            if not os.path.exists(self.intables[0]):
     433                asaplog.post()
     434                raise RuntimeError, "Could not find '%s'" % self.intables[0]
     435           
     436            stab = scantable(self.intables[0],average=False)
     437            ntab = len(self.intables)
     438            byname = True
     439        else:
     440            stab = self.intables[0]
     441            ntab = len(self.intables)
     442
     443        if len(stab.getbeamnos()) > 1:
     444            asaplog.post()
     445            asaplog.push("Mult-beam data is not supported by this module.")
     446            asaplog.post("ERROR")
     447            return
     448
     449        valid_ifs = stab.getifnos()
     450        if self.baseif < 0:
     451            self.baseif = valid_ifs[0]
     452            asaplog.post()
     453            asaplog.push("IFNO is not selected. Using the first IF in the first scantable. Reference IFNO = %d" % (self.baseif))
     454       
     455        if not (self.baseif in valid_ifs):
     456            asaplog.post()
     457            errmsg = "IF%d does not exist in the first scantable" %  \
     458                     self.baseif
     459            raise RuntimeError, errmsg
     460
     461        asaplog.push("Start selecting tables and IFNOs to solve.")
     462        asaplog.push("Cheching frequency of the reference IF")
     463        unit_org = stab.get_unit()
     464        coord = stab._getcoordinfo()
     465        frame_org = coord[1]
     466        stab.set_unit("Hz")
     467        if len(self.freqframe) > 0:
     468            stab.set_freqframe(self.freqframe)
     469        stab.set_selection(ifs=[self.baseif])
     470        spx = stab._getabcissa()
     471        stab.set_selection()
     472        basech0 = spx[0]
     473        baseinc = spx[1]-spx[0]
     474        self.nchan = len(spx)
     475        if isinstance(self.freqtol, float):
     476            vftol = abs(baseinc * self.freqtol)
     477            self.freqtol = dict(value=vftol, unit="Hz")
     478        else:
     479            vftol = abs(self.freqtol['value'])
     480        inctol = abs(baseinc/float(self.nchan))
     481        asaplog.push("Reference frequency setup (Table = 0, IFNO = %d):  nchan = %d, chan0 = %f Hz, incr = %f Hz" % (self.baseif, self.nchan, basech0, baseinc))
     482        asaplog.push("Allowed frequency tolerance = %f Hz ( %f channels)" % (vftol, vftol/baseinc))
     483        poltype0 = stab.poltype()
     484       
     485        self.tables = []
     486        self.signalShift = []
     487        if self.dsbmode:
     488            self.imageShift = []
     489
     490        for itab in range(ntab):
     491            asaplog.push("Table %d:" % itab)
     492            tab_selected = False
     493            if itab > 0:
     494                if byname:
     495                    stab = scantable(self.intables[itab],average=False)
     496                else:
     497                    stab = self.intables[itab]
     498                unit_org = stab.get_unit()
     499                coord = stab._getcoordinfo()
     500                frame_org = coord[1]
     501                stab.set_unit("Hz")
     502                if len(self.freqframe) > 0:
     503                    stab.set_freqframe(self.freqframe)
     504
     505            # Check POLTYPE should be equal to the first table.
     506            if stab.poltype() != poltype0:
     507                asaplog.post()
     508                raise Exception, "POLTYPE should be equal to the first table."
     509            # Multiple beam data may not handled properly
     510            if len(stab.getbeamnos()) > 1:
     511                asaplog.post()
     512                asaplog.push("table contains multiple beams. It may not be handled properly.")
     513                asaplog.push("WARN")
     514
     515            for ifno in stab.getifnos():
     516                stab.set_selection(ifs=[ifno])
     517                spx = stab._getabcissa()
     518                if (len(spx) != self.nchan) or \
     519                   (abs(spx[0]-basech0) > vftol) or \
     520                   (abs(spx[1]-spx[0]-baseinc) > inctol):
     521                    continue
     522                tab_selected = True
     523                seltab = stab.copy()
     524                seltab.set_unit(unit_org)
     525                seltab.set_freqframe(frame_org)
     526                self.tables.append(seltab)
     527                self.signalShift.append((spx[0]-basech0)/baseinc)
     528                if self.dsbmode:
     529                    self.imageShift.append(-self.signalShift[-1])
     530                asaplog.push("- IF%d selected: sideband shift = %16.12e channels" % (ifno, self.signalShift[-1]))
     531            stab.set_selection()
     532            stab.set_unit(unit_org)
     533            stab.set_freqframe(frame_org)
     534            if not tab_selected:
     535                asaplog.post()
     536                asaplog.push("No data selected in Table %d" % itab)
     537                asaplog.post("WARN")
     538
     539        asaplog.push("Total number of IFs selected = %d" % len(self.tables))
     540        if len(self.tables) < 2:
     541            asaplog.post()
     542            raise RuntimeError, "At least 2 IFs are necessary for convolution!"
     543
     544        if not self.dsbmode and len(self.imageShift) != len(self.signalShift):
     545            asaplog.post()
     546            errmsg = "User defined channel shift of image sideband has %d elements, while selected IFNOs are %d" % (len(self.imageShift), len(self.signalShift))
     547            raise RuntimeError, errmsg
     548
     549        self.signalShift = numpy.array(self.signalShift)
     550        self.imageShift = numpy.array(self.imageShift)
     551        self.nshift = len(self.tables)
     552
     553    @asaplog_post_dec
     554    def _preprocess_tables(self):
     555        ### temporary method to preprocess data
     556        ### Do time averaging for now.
     557        for itab in range(len(self.tables)):
     558            self.tables[itab] = self.tables[itab].average_time(scanav=False, weight="tintsys")
     559       
     560
     561#     def save(self, outfile, outform="ASAP", overwrite=False):
     562#         if not overwrite and os.path.exists(outfile):
     563#             raise RuntimeError, "Output file '%s' already exists" % outfile
     564#
     565#         #self.separator._save(outfile, outform)
     566
     567#     def done(self):
     568#         self.close()
     569
     570#     def close(self):
     571#         pass
     572#         #del self.separator
     573   
     574
     575
     576########################################################################
     577    def _Deconvolution(self, data_array, shift, threshold=0.00000001):
     578        FObs = []
     579        Reject = 0
     580        nshift, nchan = data_array.shape
     581        nspec = nshift*(nshift-1)/2
     582        ifftObs  = numpy.zeros((nspec, nchan), numpy.float)
     583        for i in range(nshift):
     584           F = FFT.fft(data_array[i])
     585           FObs.append(F)
     586        z = 0
     587        for i in range(nshift):
     588            for j in range(i+1, nshift):
     589                Fobs = (FObs[i]+FObs[j])/2.0
     590                dX = (shift[j]-shift[i])*2.0*math.pi/float(self.nchan)
     591                #print 'dX,i,j=',dX,i,j
     592                for k in range(1,self.nchan):
     593                    if math.fabs(math.sin(dX*k)) > threshold:
     594                        Fobs[k] += ((FObs[i][k]-FObs[j][k])/2.0/(1.0-math.cos(dX*k))*math.sin(dX*k))*1.0j
     595                    else: Reject += 1
     596                ifftObs[z] = FFT.ifft(Fobs)
     597                z += 1
     598        print 'Threshold=%s Reject=%d' % (threshold, Reject)
     599        return ifftObs
     600
     601    def _combineResult(self, ifftObs):
     602        nspec = len(ifftObs)
     603        sum = ifftObs[0]
     604        for i in range(1,nspec):
     605            sum += ifftObs[i]
     606        return(sum/float(nspec))
     607
     608    def _subtractOtherSide(self, data_array, shift, Data):
     609        sum = numpy.zeros(len(Data), numpy.float)
     610        numSP = len(data_array)
     611        for i in range(numSP):
     612            SPsub = data_array[i] - Data
     613            sum += self._shiftSpectrum(SPsub, -shift[i])
     614        return(sum/float(numSP))
     615
     616    def _shiftSpectrum(self, data, Shift):
     617        Out = numpy.zeros(self.nchan, numpy.float)
     618        w2 = Shift % 1
     619        w1 = 1.0 - w2
     620        for i in range(self.nchan):
     621            c1 = int((Shift + i) % self.nchan)
     622            c2 = (c1 + 1) % self.nchan
     623            Out[c1] += data[i] * w1
     624            Out[c2] += data[i] * w2
     625        return Out.copy()
  • trunk/python/scantable.py

    r3112 r2704  
    22
    33import os
    4 import re
    54import tempfile
    65import numpy
     
    4645        l=f.readline()
    4746        f.close()
    48         match_pattern = '^Type = (Scantable)? *$'
    49         if re.match(match_pattern,l):
     47        if ( l.find('Scantable') != -1 ):
     48            return True
     49        elif ( l.find('Measurement Set') == -1 and
     50               l.find('Image') == -1 ):
    5051            return True
    5152        else:
     
    174175    return str(showprogress).lower() + ',' + str(minnrow)
    175176
    176 def 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 
    192 def 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 
    281 def 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 
    302 def 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 
    313 def is_frequency(s):
    314     s = s.strip()
    315     return (s[-2:].lower() == "hz")
    316 
    317 def 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 
    338 def is_velocity(s):
    339     s = s.strip()
    340     return (s[-3:].lower() == "m/s")
    341 
    342 def 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 
    364 def 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 
    380 def 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 
    432 def 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 
    475 def set_restfreq(s, restfreq):
    476     rfset = (restfreq != '') and (restfreq != [])
    477     if rfset:
    478         s.set_restfreqs(normalise_restfreq(restfreq))
    479 
    480177class scantable(Scantable):
    481178    """\
     
    513210                          Default (false) is taken from rc file.
    514211
    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.
    520212        """
    521213        if average is None:
     
    552244                    self._fill([filename], unit, average, opts)
    553245                elif os.path.isfile(filename):
    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)
     246                    self._fill([filename], unit, average)
    560247                    # only apply to new data not "copy constructor"
    561248                    self.parallactify(parallactify)
     
    891578
    892579    @asaplog_post_dec
    893     def stats(self, stat='stddev', mask=None, form='3.3f', row=None, skip_flaggedrow=False):
     580    def stats(self, stat='stddev', mask=None, form='3.3f', row=None):
    894581        """\
    895582        Determine the specified statistic of the current beam/if/pol
     
    909596            row:     row number of spectrum to process.
    910597                     (default is None: for all rows)
    911 
    912             skip_flaggedrow: if True, skip outputting text for flagged
    913                              spectra. default is False.
    914598
    915599        Example:
     
    924608                             "number of channels. Please use setselection() "
    925609                             "to select individual IFs")
     610        rtnabc = False
     611        if stat.lower().endswith('_abc'): rtnabc = True
    926612        getchan = False
    927613        if stat.lower().startswith('min') or stat.lower().startswith('max'):
     
    929615            getchan = True
    930616            statvals = []
    931 
    932         rtnabc = False
    933         if stat.lower().endswith('_abc'):
    934             rtnabc = True
    935         else:
     617        if not rtnabc:
    936618            if row == None:
    937619                statvals = self._math._stats(self, mask, stat)
     
    959641            statunit= ''
    960642            if getchan:
    961                 if self._is_all_chan_flagged(i):
    962                     if rtnabc:
    963                         statvals.append(None)
     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']+']'
    964648                else:
    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
     649                    refstr = ('(@ %'+form) % (qx['value'])+' ['+qx['unit']+'])'
    978650
    979651            tm = self._gettime(i)
     
    987659            if len(rows) > 1:
    988660                # out += ('= %'+form) % (outvec[i]) +'   '+refstr+'\n'
    989                 if statvals[i] is None:
    990                     out += ('= None(flagged)') + '   '+refstr+'\n'
    991                 else:
    992                     out += ('= %'+form) % (statvals[i]) +'   '+refstr+'\n'
     661                out += ('= %'+form) % (statvals[i]) +'   '+refstr+'\n'
    993662            else:
    994663                # out += ('= %'+form) % (outvec[0]) +'   '+refstr+'\n'
    995                 if statvals[0] is None:
    996                     out += ('= None(flagged)') + '   '+refstr+'\n'
    997                 else:
    998                     out += ('= %'+form) % (statvals[0]) +'   '+refstr+'\n'
     664                out += ('= %'+form) % (statvals[0]) +'   '+refstr+'\n'
    999665            out +=  sep+"\n"
    1000666
     
    1017683        asaplog.push(''.join(x), False)
    1018684
    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]
    1024685        return statvals
    1025686
     
    1104765        return self._get_column( self._gettsysspectrum, row )
    1105766
    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 
    1123767    def get_weather(self, row=-1):
    1124768        """\
    1125         Return the weather information.
     769        Return the weather informations.
    1126770
    1127771        Parameters:
     
    1134778
    1135779        """
    1136         if row >= len(self):
    1137             raise IndexError("row out of range")
     780
    1138781        values = self._get_column(self._get_weather, row)
    1139782        if row > -1:
     
    1145788            out = []
    1146789            for r in values:
     790
    1147791                out.append({'temperature': r[0],
    1148792                            'pressure': r[1], 'humidity' : r[2],
     
    13611005        self._add_history("set_feedtype", vars())
    13621006
    1363     @asaplog_post_dec
    1364     def get_doppler(self):
    1365         """\
    1366         Get the doppler.
    1367         """
    1368         return self._getcoordinfo()[2]
    1369    
    13701007    @asaplog_post_dec
    13711008    def set_doppler(self, doppler='RADIO'):
     
    18341471
    18351472    @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
    22541473    def parse_maskexpr(self, maskstring):
    22551474        """
     
    22821501            maskstring = str(valid_ifs)[1:-1]
    22831502        ## split each selection "IF range[:CHAN range]"
    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*')
     1503        sellist = maskstring.split(',')
    22891504        for currselstr in sellist:
    2290             selset = collon_sep.split(currselstr)
     1505            selset = currselstr.split(':')
    22911506            # spw and mask string (may include ~, < or >)
    22921507            spwmasklist = self._parse_selection(selset[0], typestr='integer',
     
    24221637        if smode == 'r':
    24231638            minidx = 0
    2424             maxidx = self.nrow()-1
     1639            maxidx = self.nrow()
    24251640        else:
    24261641            idx = getattr(self,"get"+mode+"nos")()
     
    24281643            maxidx = max(idx)
    24291644            del idx
    2430         # split selexpr by "<spaces>,<spaces>"
    2431         comma_sep = re.compile('\s*,\s*')
    2432         sellist = comma_sep.split(selexpr)
     1645        sellist = selexpr.split(',')
    24331646        idxlist = []
    24341647        for currselstr in sellist:
     
    24381651            for thelist in currlist:
    24391652                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        
    24511653        msg = "Selected %s: %s" % (mode.upper()+"NO", str(idxlist))
    24521654        asaplog.push(msg)
     
    24741676            --> returns [[0.,2.5],[5.0,7.0],[9.,9.]]
    24751677        """
    2476         # split selstr by '<spaces>;<spaces>'
    2477         semi_sep = re.compile('\s*;\s*')
    2478         selgroups = semi_sep.split(selstr)
     1678        selgroups = selstr.split(';')
    24791679        sellists = []
    24801680        if typestr.lower().startswith('int'):
     
    24851685       
    24861686        for currsel in  selgroups:
    2487             if currsel.strip() == '*' or len(currsel.strip()) == 0:
    2488                 minsel = minval
    2489                 maxsel = maxval
    24901687            if currsel.find('~') > 0:
    24911688                # val0 <= x <= val1
    24921689                minsel = formatfunc(currsel.split('~')[0].strip())
    2493                 maxsel = formatfunc(currsel.split('~')[1].strip())
     1690                maxsel = formatfunc(currsel.split('~')[1].strip()) 
    24941691            elif currsel.strip().find('<=') > -1:
    24951692                bound = currsel.split('<=')
     
    27101907
    27111908    @asaplog_post_dec
    2712     def history(self, filename=None, nrows=-1, start=0):
     1909    def history(self, filename=None):
    27131910        """\
    27141911        Print the history. Optionally to a file.
     
    27191916
    27201917        """
    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))
     1918        hist = list(self._gethistory())
    27321919        out = "-"*80
    27331920        for h in hist:
    2734             if not h.strip():
    2735                 continue
    2736             if h.find("---") >-1:
    2737                 continue
     1921            if h.startswith("---"):
     1922                out = "\n".join([out, h])
    27381923            else:
    27391924                items = h.split("##")
     
    27481933                    s = i.split("=")
    27491934                    out += "\n   %s = %s" % (s[0], s[1])
    2750                 out = "\n".join([out, "*"*80])
     1935                out = "\n".join([out, "-"*80])
    27511936        if filename is not None:
    27521937            if filename is "":
    27531938                filename = 'scantable_history.txt'
     1939            import os
    27541940            filename = os.path.expandvars(os.path.expanduser(filename))
    27551941            if not os.path.isdir(filename):
     
    27661952    #
    27671953    @asaplog_post_dec
    2768     def average_time(self, mask=None, scanav=False, weight='tint', align=False,
    2769                      avmode="NONE"):
     1954    def average_time(self, mask=None, scanav=False, weight='tint', align=False):
    27701955        """\
    27711956        Return the (time) weighted average of a scan. Scans will be averaged
     
    27951980            align:    align the spectra in velocity before averaging. It takes
    27961981                      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
    28001982
    28011983        Example::
     
    28081990        weight = weight or 'TINT'
    28091991        mask = mask or ()
    2810         scanav = (scanav and 'SCAN') or avmode.upper()
     1992        scanav = (scanav and 'SCAN') or 'NONE'
    28111993        scan = (self, )
    28121994
    28131995        if align:
    28141996            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           
    28181997        s = None
    28191998        if weight.upper() == 'MEDIAN':
     
    33602539            raise RuntimeError(msg)
    33612540
    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,
     2541
     2542    @asaplog_post_dec
     2543    def sinusoid_baseline(self, insitu=None, mask=None, applyfft=None,
    36222544                          fftmethod=None, fftthresh=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):
     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):
    36322549        """\
    36332550        Return a scan which has been baselined (all rows) with sinusoidal
     
    36352552
    36362553        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)
    36372557            mask:          an optional mask
    36382558            applyfft:      if True use some method, such as FFT, to find
     
    36662586                           wave numbers which are specified both in addwn
    36672587                           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)
    36712588            clipthresh:    Clipping threshold. (default is 3.0, unit: sigma)
    36722589            clipniter:     maximum number of iteration of 'clipthresh'-sigma
     
    36882605                           (default is '': no file/logger output)
    36892606            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)
    36962607
    36972608        Example:
     
    37152626                workscan = self.copy()
    37162627           
     2628            #if mask          is None: mask          = [True for i in xrange(workscan.nchan())]
    37172629            if mask          is None: mask          = []
    37182630            if applyfft      is None: applyfft      = True
     
    37302642            if blfile        is None: blfile        = ''
    37312643            if csvformat     is None: csvformat     = False
    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'
     2644
     2645            if csvformat:
     2646                scsvformat = "T"
     2647            else:
     2648                scsvformat = "F"
    37382649
    37392650            #CURRENTLY, PLOT=true is UNAVAILABLE UNTIL sinusoidal fitting is implemented as a fitter method.
    3740             workscan._sinusoid_baseline(mask,
    3741                                         fftinfo,
    3742                                         #applyfft, fftmethod.lower(),
    3743                                         #str(fftthresh).lower(),
     2651            workscan._sinusoid_baseline(mask, applyfft, fftmethod.lower(),
     2652                                        str(fftthresh).lower(),
    37442653                                        workscan._parse_wn(addwn),
    37452654                                        workscan._parse_wn(rejwn),
     
    37482657                                        pack_progress_params(showprogress,
    37492658                                                             minnrow),
    3750                                         outlog, scsvformat+blfile,
    3751                                         bltable)
     2659                                        outlog, scsvformat+blfile)
    37522660            workscan._add_history('sinusoid_baseline', varlist)
    3753 
    3754             if bltable == '':
    3755                 if insitu:
    3756                     self._assign(workscan)
    3757                 else:
    3758                     return workscan
    3759             else:
    3760                 if not insitu:
    3761                     return None
     2661           
     2662            if insitu:
     2663                self._assign(workscan)
     2664            else:
     2665                return workscan
    37622666           
    37632667        except RuntimeError, e:
     
    37662670
    37672671    @asaplog_post_dec
    3768     def auto_sinusoid_baseline(self, mask=None, applyfft=None,
     2672    def auto_sinusoid_baseline(self, insitu=None, mask=None, applyfft=None,
    37692673                               fftmethod=None, fftthresh=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):
     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):
    37802679        """\
    37812680        Return a scan which has been baselined (all rows) with sinusoidal
     
    37852684
    37862685        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)
    37872689            mask:           an optional mask retreived from scantable
    37882690            applyfft:       if True use some method, such as FFT, to find
     
    38162718                            wave numbers which are specified both in addwn
    38172719                            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)
    38212720            clipthresh:     Clipping threshold. (default is 3.0, unit: sigma)
    38222721            clipniter:      maximum number of iteration of 'clipthresh'-sigma
     
    38582757                            (default is "": no file/logger output)
    38592758            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)
    38662759
    38672760        Example:
     
    38822775                workscan = self.copy()
    38832776           
     2777            #if mask           is None: mask           = [True for i in xrange(workscan.nchan())]
    38842778            if mask           is None: mask           = []
    38852779            if applyfft       is None: applyfft       = True
     
    39002794            if blfile         is None: blfile         = ''
    39012795            if csvformat      is None: csvformat      = False
    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'
     2796
     2797            if csvformat:
     2798                scsvformat = "T"
     2799            else:
     2800                scsvformat = "F"
    39082801
    39092802            #CURRENTLY, PLOT=true is UNAVAILABLE UNTIL sinusoidal fitting is implemented as a fitter method.
    3910             workscan._auto_sinusoid_baseline(mask,
    3911                                              fftinfo,
     2803            workscan._auto_sinusoid_baseline(mask, applyfft,
     2804                                             fftmethod.lower(),
     2805                                             str(fftthresh).lower(),
    39122806                                             workscan._parse_wn(addwn),
    39132807                                             workscan._parse_wn(rejwn),
     
    39182812                                             pack_progress_params(showprogress,
    39192813                                                                  minnrow),
    3920                                              outlog, scsvformat+blfile, bltable)
     2814                                             outlog, scsvformat+blfile)
    39212815            workscan._add_history("auto_sinusoid_baseline", varlist)
    3922 
    3923             if bltable == '':
    3924                 if insitu:
    3925                     self._assign(workscan)
    3926                 else:
    3927                     return workscan
    3928             else:
    3929                 if not insitu:
    3930                     return None
     2816           
     2817            if insitu:
     2818                self._assign(workscan)
     2819            else:
     2820                return workscan
    39312821           
    39322822        except RuntimeError, e:
     
    39342824
    39352825    @asaplog_post_dec
    3936     def cspline_baseline(self, mask=None, npiece=None, insitu=None,
     2826    def cspline_baseline(self, insitu=None, mask=None, npiece=None,
    39372827                         clipthresh=None, clipniter=None, plot=None,
    39382828                         getresidual=None, showprogress=None, minnrow=None,
    3939                          outlog=None, blfile=None, csvformat=None,
    3940                          bltable=None):
     2829                         outlog=None, blfile=None, csvformat=None):
    39412830        """\
    39422831        Return a scan which has been baselined (all rows) by cubic spline
     
    39442833
    39452834        Parameters:
    3946             mask:         An optional mask
    3947             npiece:       Number of pieces. (default is 2)
    39482835            insitu:       If False a new scantable is returned.
    39492836                          Otherwise, the scaling is done in-situ
    39502837                          The default is taken from .asaprc (False)
     2838            mask:         An optional mask
     2839            npiece:       Number of pieces. (default is 2)
    39512840            clipthresh:   Clipping threshold. (default is 3.0, unit: sigma)
    39522841            clipniter:    maximum number of iteration of 'clipthresh'-sigma
     
    39682857                          (default is "": no file/logger output)
    39692858            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)
    39762859
    39772860        Example:
     
    39952878                workscan = self.copy()
    39962879
     2880            #if mask         is None: mask         = [True for i in xrange(workscan.nchan())]
    39972881            if mask         is None: mask         = []
    39982882            if npiece       is None: npiece       = 2
     
    40052889            if outlog       is None: outlog       = False
    40062890            if blfile       is None: blfile       = ''
    4007             if csvformat    is None: csvformat    = False
    4008             if bltable      is None: bltable      = ''
    4009 
    4010             scsvformat = 'T' if csvformat else 'F'
     2891            if csvformat     is None: csvformat     = False
     2892
     2893            if csvformat:
     2894                scsvformat = "T"
     2895            else:
     2896                scsvformat = "F"
    40112897
    40122898            #CURRENTLY, PLOT=true UNAVAILABLE UNTIL cubic spline fitting is implemented as a fitter method.
    4013             workscan._cspline_baseline(mask, npiece,
    4014                                        clipthresh, clipniter,
     2899            workscan._cspline_baseline(mask, npiece, clipthresh, clipniter,
    40152900                                       getresidual,
    40162901                                       pack_progress_params(showprogress,
    40172902                                                            minnrow),
    4018                                        outlog, scsvformat+blfile,
    4019                                        bltable)
     2903                                       outlog, scsvformat+blfile)
    40202904            workscan._add_history("cspline_baseline", varlist)
    4021 
    4022             if bltable == '':
    4023                 if insitu:
    4024                     self._assign(workscan)
    4025                 else:
    4026                     return workscan
    4027             else:
    4028                 if not insitu:
    4029                     return None
     2905           
     2906            if insitu:
     2907                self._assign(workscan)
     2908            else:
     2909                return workscan
    40302910           
    40312911        except RuntimeError, e:
     
    40332913
    40342914    @asaplog_post_dec
    4035     def auto_cspline_baseline(self, mask=None, npiece=None, insitu=None,
     2915    def auto_cspline_baseline(self, insitu=None, mask=None, npiece=None,
    40362916                              clipthresh=None, clipniter=None,
    40372917                              edge=None, threshold=None, chan_avg_limit=None,
    40382918                              getresidual=None, plot=None,
    40392919                              showprogress=None, minnrow=None, outlog=None,
    4040                               blfile=None, csvformat=None, bltable=None):
     2920                              blfile=None, csvformat=None):
    40412921        """\
    40422922        Return a scan which has been baselined (all rows) by cubic spline
     
    40462926
    40472927        Parameters:
    4048             mask:           an optional mask retreived from scantable
    4049             npiece:         Number of pieces. (default is 2)
    40502928            insitu:         if False a new scantable is returned.
    40512929                            Otherwise, the scaling is done in-situ
    40522930                            The default is taken from .asaprc (False)
     2931            mask:           an optional mask retreived from scantable
     2932            npiece:         Number of pieces. (default is 2)
    40532933            clipthresh:     Clipping threshold. (default is 3.0, unit: sigma)
    40542934            clipniter:      maximum number of iteration of 'clipthresh'-sigma
     
    40902970                            (default is "": no file/logger output)
    40912971            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)
    40982972
    40992973        Example:
     
    41293003            if blfile         is None: blfile         = ''
    41303004            if csvformat      is None: csvformat      = False
    4131             if bltable        is None: bltable        = ''
    4132 
    4133             scsvformat = 'T' if csvformat else 'F'
     3005
     3006            if csvformat:
     3007                scsvformat = "T"
     3008            else:
     3009                scsvformat = "F"
    41343010
    41353011            #CURRENTLY, PLOT=true UNAVAILABLE UNTIL cubic spline fitting is implemented as a fitter method.
    4136             workscan._auto_cspline_baseline(mask, npiece,
    4137                                             clipthresh, clipniter,
     3012            workscan._auto_cspline_baseline(mask, npiece, clipthresh,
     3013                                            clipniter,
    41383014                                            normalise_edge_param(edge),
    41393015                                            threshold,
     
    41413017                                            pack_progress_params(showprogress,
    41423018                                                                 minnrow),
    4143                                             outlog,
    4144                                             scsvformat+blfile,
    4145                                             bltable)
     3019                                            outlog, scsvformat+blfile)
    41463020            workscan._add_history("auto_cspline_baseline", varlist)
    4147 
    4148             if bltable == '':
    4149                 if insitu:
    4150                     self._assign(workscan)
    4151                 else:
    4152                     return workscan
    4153             else:
    4154                 if not insitu:
    4155                     return None
     3021           
     3022            if insitu:
     3023                self._assign(workscan)
     3024            else:
     3025                return workscan
    41563026           
    41573027        except RuntimeError, e:
     
    41593029
    41603030    @asaplog_post_dec
    4161     def chebyshev_baseline(self, mask=None, order=None, insitu=None,
     3031    def chebyshev_baseline(self, insitu=None, mask=None, order=None,
    41623032                           clipthresh=None, clipniter=None, plot=None,
    41633033                           getresidual=None, showprogress=None, minnrow=None,
    4164                            outlog=None, blfile=None, csvformat=None,
    4165                            bltable=None):
     3034                           outlog=None, blfile=None, csvformat=None):
    41663035        """\
    41673036        Return a scan which has been baselined (all rows) by Chebyshev polynomials.
    41683037
    41693038        Parameters:
    4170             mask:         An optional mask
    4171             order:        the maximum order of Chebyshev polynomial (default is 5)
    41723039            insitu:       If False a new scantable is returned.
    41733040                          Otherwise, the scaling is done in-situ
    41743041                          The default is taken from .asaprc (False)
     3042            mask:         An optional mask
     3043            order:        the maximum order of Chebyshev polynomial (default is 5)
    41753044            clipthresh:   Clipping threshold. (default is 3.0, unit: sigma)
    41763045            clipniter:    maximum number of iteration of 'clipthresh'-sigma
     
    41923061                          (default is "": no file/logger output)
    41933062            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)
    42003063
    42013064        Example:
     
    42193082                workscan = self.copy()
    42203083
     3084            #if mask         is None: mask         = [True for i in xrange(workscan.nchan())]
    42213085            if mask         is None: mask         = []
    42223086            if order        is None: order        = 5
     
    42293093            if outlog       is None: outlog       = False
    42303094            if blfile       is None: blfile       = ''
    4231             if csvformat    is None: csvformat    = False
    4232             if bltable      is None: bltable      = ''
    4233 
    4234             scsvformat = 'T' if csvformat else 'F'
     3095            if csvformat     is None: csvformat     = False
     3096
     3097            if csvformat:
     3098                scsvformat = "T"
     3099            else:
     3100                scsvformat = "F"
    42353101
    42363102            #CURRENTLY, PLOT=true UNAVAILABLE UNTIL cubic spline fitting is implemented as a fitter method.
    4237             workscan._chebyshev_baseline(mask, order,
    4238                                          clipthresh, clipniter,
     3103            workscan._chebyshev_baseline(mask, order, clipthresh, clipniter,
    42393104                                         getresidual,
    42403105                                         pack_progress_params(showprogress,
    42413106                                                              minnrow),
    4242                                          outlog, scsvformat+blfile,
    4243                                          bltable)
     3107                                         outlog, scsvformat+blfile)
    42443108            workscan._add_history("chebyshev_baseline", varlist)
    4245 
    4246             if bltable == '':
    4247                 if insitu:
    4248                     self._assign(workscan)
    4249                 else:
    4250                     return workscan
    4251             else:
    4252                 if not insitu:
    4253                     return None
     3109           
     3110            if insitu:
     3111                self._assign(workscan)
     3112            else:
     3113                return workscan
    42543114           
    42553115        except RuntimeError, e:
     
    42573117
    42583118    @asaplog_post_dec
    4259     def auto_chebyshev_baseline(self, mask=None, order=None, insitu=None,
     3119    def auto_chebyshev_baseline(self, insitu=None, mask=None, order=None,
    42603120                              clipthresh=None, clipniter=None,
    42613121                              edge=None, threshold=None, chan_avg_limit=None,
    42623122                              getresidual=None, plot=None,
    42633123                              showprogress=None, minnrow=None, outlog=None,
    4264                               blfile=None, csvformat=None, bltable=None):
     3124                              blfile=None, csvformat=None):
    42653125        """\
    42663126        Return a scan which has been baselined (all rows) by Chebyshev polynomials.
     
    42693129
    42703130        Parameters:
    4271             mask:           an optional mask retreived from scantable
    4272             order:          the maximum order of Chebyshev polynomial (default is 5)
    42733131            insitu:         if False a new scantable is returned.
    42743132                            Otherwise, the scaling is done in-situ
    42753133                            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)
    42763136            clipthresh:     Clipping threshold. (default is 3.0, unit: sigma)
    42773137            clipniter:      maximum number of iteration of 'clipthresh'-sigma
     
    43133173                            (default is "": no file/logger output)
    43143174            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)
    43213175
    43223176        Example:
     
    43373191                workscan = self.copy()
    43383192           
     3193            #if mask           is None: mask           = [True for i in xrange(workscan.nchan())]
    43393194            if mask           is None: mask           = []
    43403195            if order          is None: order          = 5
     
    43513206            if blfile         is None: blfile         = ''
    43523207            if csvformat      is None: csvformat      = False
    4353             if bltable        is None: bltable        = ''
    4354 
    4355             scsvformat = 'T' if csvformat else 'F'
     3208
     3209            if csvformat:
     3210                scsvformat = "T"
     3211            else:
     3212                scsvformat = "F"
    43563213
    43573214            #CURRENTLY, PLOT=true UNAVAILABLE UNTIL cubic spline fitting is implemented as a fitter method.
    4358             workscan._auto_chebyshev_baseline(mask, order,
    4359                                               clipthresh, clipniter,
     3215            workscan._auto_chebyshev_baseline(mask, order, clipthresh,
     3216                                              clipniter,
    43603217                                              normalise_edge_param(edge),
    43613218                                              threshold,
     
    43633220                                              pack_progress_params(showprogress,
    43643221                                                                   minnrow),
    4365                                               outlog, scsvformat+blfile,
    4366                                               bltable)
     3222                                              outlog, scsvformat+blfile)
    43673223            workscan._add_history("auto_chebyshev_baseline", varlist)
    4368 
    4369             if bltable == '':
    4370                 if insitu:
    4371                     self._assign(workscan)
    4372                 else:
    4373                     return workscan
    4374             else:
    4375                 if not insitu:
    4376                     return None
     3224           
     3225            if insitu:
     3226                self._assign(workscan)
     3227            else:
     3228                return workscan
    43773229           
    43783230        except RuntimeError, e:
     
    43803232
    43813233    @asaplog_post_dec
    4382     def poly_baseline(self, mask=None, order=None, insitu=None,
    4383                       clipthresh=None, clipniter=None, plot=None,
     3234    def poly_baseline(self, mask=None, order=None, insitu=None, plot=None,
    43843235                      getresidual=None, showprogress=None, minnrow=None,
    4385                       outlog=None, blfile=None, csvformat=None,
    4386                       bltable=None):
     3236                      outlog=None, blfile=None, csvformat=None):
    43873237        """\
    43883238        Return a scan which has been baselined (all rows) by a polynomial.
    43893239        Parameters:
    4390             mask:         an optional mask
    4391             order:        the order of the polynomial (default is 0)
    43923240            insitu:       if False a new scantable is returned.
    43933241                          Otherwise, the scaling is done in-situ
    43943242                          The default is taken from .asaprc (False)
    4395             clipthresh:   Clipping threshold. (default is 3.0, unit: sigma)
    4396             clipniter:    maximum number of iteration of 'clipthresh'-sigma
    4397                           clipping (default is 0)
     3243            mask:         an optional mask
     3244            order:        the order of the polynomial (default is 0)
    43983245            plot:         plot the fit and the residual. In this each
    43993246                          indivual fit has to be approved, by typing 'y'
     
    44113258                          (default is "": no file/logger output)
    44123259            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)
    44193260
    44203261        Example:
     
    44343275                workscan = self.copy()
    44353276
     3277            #if mask         is None: mask         = [True for i in \
     3278            #                                           xrange(workscan.nchan())]
    44363279            if mask         is None: mask         = []
    44373280            if order        is None: order        = 0
    4438             if clipthresh   is None: clipthresh   = 3.0
    4439             if clipniter    is None: clipniter    = 0
    44403281            if plot         is None: plot         = False
    44413282            if getresidual  is None: getresidual  = True
     
    44433284            if minnrow      is None: minnrow      = 1000
    44443285            if outlog       is None: outlog       = False
    4445             if blfile       is None: blfile       = ''
     3286            if blfile       is None: blfile       = ""
    44463287            if csvformat    is None: csvformat    = False
    4447             if bltable      is None: bltable      = ''
    4448 
    4449             scsvformat = 'T' if csvformat else 'F'
     3288
     3289            if csvformat:
     3290                scsvformat = "T"
     3291            else:
     3292                scsvformat = "F"
    44503293
    44513294            if plot:
     
    45113354                    blf.close()
    45123355            else:
    4513                 workscan._poly_baseline(mask, order,
    4514                                         clipthresh, clipniter, #
    4515                                         getresidual,
     3356                workscan._poly_baseline(mask, order, getresidual,
    45163357                                        pack_progress_params(showprogress,
    45173358                                                             minnrow),
    4518                                         outlog, scsvformat+blfile,
    4519                                         bltable)  #
     3359                                        outlog, scsvformat+blfile)
    45203360           
    45213361            workscan._add_history("poly_baseline", varlist)
     
    45303370
    45313371    @asaplog_post_dec
    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):
     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):
    45383377        """\
    45393378        Return a scan which has been baselined (all rows) by a polynomial.
     
    45423381
    45433382        Parameters:
    4544             mask:           an optional mask retreived from scantable
    4545             order:          the order of the polynomial (default is 0)
    45463383            insitu:         if False a new scantable is returned.
    45473384                            Otherwise, the scaling is done in-situ
    45483385                            The default is taken from .asaprc (False)
    4549             clipthresh:     Clipping threshold. (default is 3.0, unit: sigma)
    4550             clipniter:      maximum number of iteration of 'clipthresh'-sigma
    4551                             clipping (default is 0)
     3386            mask:           an optional mask retreived from scantable
     3387            order:          the order of the polynomial (default is 0)
    45523388            edge:           an optional number of channel to drop at
    45533389                            the edge of spectrum. If only one value is
     
    45853421                            (default is "": no file/logger output)
    45863422            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)
    45933423
    45943424        Example:
     
    46063436                workscan = self.copy()
    46073437
     3438            #if mask           is None: mask           = [True for i in xrange(workscan.nchan())]
    46083439            if mask           is None: mask           = []
    46093440            if order          is None: order          = 0
    4610             if clipthresh     is None: clipthresh     = 3.0
    4611             if clipniter      is None: clipniter      = 0
    46123441            if edge           is None: edge           = (0, 0)
    46133442            if threshold      is None: threshold      = 3
     
    46203449            if blfile         is None: blfile         = ''
    46213450            if csvformat      is None: csvformat      = False
    4622             if bltable        is None: bltable        = ''
    4623 
    4624             scsvformat = 'T' if csvformat else 'F'
     3451
     3452            if csvformat:
     3453                scsvformat = "T"
     3454            else:
     3455                scsvformat = "F"
    46253456
    46263457            edge = normalise_edge_param(edge)
     
    46923523                if outblfile: blf.close()
    46933524            else:
    4694                 workscan._auto_poly_baseline(mask, order,
    4695                                              clipthresh, clipniter,
    4696                                              edge, threshold,
     3525                workscan._auto_poly_baseline(mask, order, edge, threshold,
    46973526                                             chan_avg_limit, getresidual,
    46983527                                             pack_progress_params(showprogress,
    46993528                                                                  minnrow),
    4700                                              outlog, scsvformat+blfile,
    4701                                              bltable)
     3529                                             outlog, scsvformat+blfile)
     3530
    47023531            workscan._add_history("auto_poly_baseline", varlist)
    4703 
    4704             if bltable == '':
    4705                 if insitu:
    4706                     self._assign(workscan)
    4707                 else:
    4708                     return workscan
    4709             else:
    4710                 if not insitu:
    4711                     return None
     3532           
     3533            if insitu:
     3534                self._assign(workscan)
     3535            else:
     3536                return workscan
    47123537           
    47133538        except RuntimeError, e:
     
    48193644        self._math._setinsitu(insitu)
    48203645        varlist = vars()
    4821         s = scantable(self._math._unaryop(self, offset, "ADD", False, False))
     3646        s = scantable(self._math._unaryop(self, offset, "ADD", False))
    48223647        s._add_history("add", varlist)
    48233648        if insitu:
     
    48423667            tsys:        if True (default) then apply the operation to Tsys
    48433668                         as well as the data
     3669
    48443670        """
    48453671        if insitu is None: insitu = rcParams['insitu']
     
    48523678                                                         numpy.ndarray):
    48533679                from asapmath import _array2dOp
    4854                 s = _array2dOp( self, factor, "MUL", tsys, insitu, True )
     3680                s = _array2dOp( self, factor, "MUL", tsys, insitu )
    48553681            else:
    48563682                s = scantable( self._math._arrayop( self, factor,
    4857                                                     "MUL", tsys, True ) )
     3683                                                    "MUL", tsys ) )
    48583684        else:
    4859             s = scantable(self._math._unaryop(self, factor, "MUL", tsys, True ))
     3685            s = scantable(self._math._unaryop(self, factor, "MUL", tsys))
    48603686        s._add_history("scale", varlist)
    48613687        if insitu:
     
    49043730        self._add_history("set_sourcetype", varlist)
    49053731
    4906 
    4907     def set_sourcename(self, name):
    4908         varlist = vars()
    4909         self._setsourcename(name)
    4910         self._add_history("set_sourcename", varlist)
    4911 
    49123732    @asaplog_post_dec
    49133733    @preserve_selection
     
    49463766        s = None
    49473767        if mode.lower() == "paired":
    4948             from asap._asap import srctype
    49493768            sel = self.get_selection()
    4950             #sel.set_query("SRCTYPE==psoff")
    4951             sel.set_types(srctype.psoff)
     3769            sel.set_query("SRCTYPE==psoff")
    49523770            self.set_selection(sel)
    49533771            offs = self.copy()
    4954             #sel.set_query("SRCTYPE==pson")
    4955             sel.set_types(srctype.pson)
     3772            sel.set_query("SRCTYPE==pson")
    49563773            self.set_selection(sel)
    49573774            ons = self.copy()
     
    50703887            if other == 0.0:
    50713888                raise ZeroDivisionError("Dividing by zero is not recommended")
    5072             s = scantable(self._math._unaryop(self, other, mode, False, True))
     3889            s = scantable(self._math._unaryop(self, other, mode, False))
    50733890        elif isinstance(other, list) or isinstance(other, numpy.ndarray):
    50743891            if isinstance(other[0], list) \
    50753892                    or isinstance(other[0], numpy.ndarray):
    50763893                from asapmath import _array2dOp
    5077                 s = _array2dOp(self, other, mode, False)
    5078             else:
    5079                 s = scantable(self._math._arrayop(self, other, mode, False, True))
     3894                s = _array2dOp( self, other, mode, False )
     3895            else:
     3896                s = scantable( self._math._arrayop( self, other,
     3897                                                    mode, False ) )
    50803898        else:
    50813899            raise TypeError("Other input is not a scantable or float value")
     
    51103928            self.set_selection(basesel+sel)
    51113929            nans = numpy.isnan(self._getspectrum(0))
    5112             if numpy.any(nans):
    5113                 bnans = [ bool(v) for v in nans]
    5114                 self.flag(bnans)
    5115        
    5116         self.set_selection(basesel)
     3930        if numpy.any(nans):
     3931            bnans = [ bool(v) for v in nans]
     3932            self.flag(bnans)
    51173933
    51183934    def get_row_selector(self, rowno):
  • trunk/python/selector.py

    r3112 r2704  
    11import re
    2 import math
    3 import string
    42from asap._asap import selector as _selector, srctype
    53from asap.utils import unique, _to_list
     
    202200            raise TypeError('Unknown row number type. Use lists of integers.')
    203201
    204     def set_msselection_field(self, selection):
    205         """
    206         Set a field selection in msselection syntax. The msselection
    207         suppports the following syntax:
    208 
    209         pattern match:
    210             - UNIX style pattern match for source name using '*'
    211               (compatible with set_name)
    212 
    213         field id selection:
    214             - simple number in string ('0', '1', etc.)
    215             - range specification using '~' ('0~1', etc.)
    216             - range specification using '>' or '<' in combination
    217               with '=' ('>=1', '<3', etc.)
    218 
    219         comma separated multiple selection:
    220             - selections can be combined by using ',' ('0,>1',
    221               'mysource*,2~4', etc.)
    222         """
    223         selection_list =  map(string.strip, selection.split(','))
    224         query_list = list(self.generate_query(selection_list))
    225         if len(query_list) > 0:
    226             original_query = self.get_query()
    227             if len(original_query) == 0 or re.match('.*(SRC|FIELD)NAME.*',original_query):
    228                 query = 'SELECT FROM $1 WHERE ' + ' || '.join(query_list)
    229             else:
    230                 query = 'SELECT FROM $1 WHERE (' + original_query + ') && (' + ' || '.join(query_list) + ')'
    231             self._settaql(query)
    232 
    233     def generate_query(self, selection_list):
    234         for s in selection_list:
    235             if s.isdigit() or re.match('^[<>]=?[0-9]*$', s) or \
    236                     re.match('^[0-9]+~[0-9]+$', s):
    237                 #print '"%s" is ID selection using < or <='%(s)
    238                 a = FieldIdRegexGenerator(s)
    239                 yield '(%s)'%(a.get_regex())
    240             elif len(s) > 0:
    241                 #print '"%s" is UNIX style pattern match'%(s)
    242                 yield '(SRCNAME == pattern(\'%s\'))'%(s)
    243        
    244202    def get_scans(self):
    245203        return list(self._getscans())
     
    317275                union.set_query(qs)
    318276        return union
    319 
    320 class FieldIdRegexGenerator(object):
    321     def __init__(self, pattern):
    322         if pattern.isdigit():
    323             self.regex = 'FIELDNAME == regex(\'.+__%s$\')'%(pattern)
    324         else:
    325             self.regex = None
    326             ineq = None
    327             if pattern.find('<') >= 0:
    328                 ineq = '<'
    329                 s = pattern.strip().lstrip(ineq).lstrip('=')
    330                 if not s.isdigit():
    331                     raise RuntimeError('Invalid syntax: %s'%(pattern))
    332                 self.id = int(s) + (-1 if pattern.find('=') < 0 else 0)
    333                 self.template = string.Template('FIELDNAME == regex(\'.+__${reg}$\')')
    334             elif pattern.find('>') >= 0:
    335                 ineq = '>'
    336                 s = pattern.strip().lstrip(ineq).lstrip('=')
    337                 if not s.isdigit():
    338                     raise RuntimeError('Invalid syntax: %s'%(pattern))
    339                 self.id = int(s) + (-1 if pattern.find('=') >= 0 else 0)
    340                 self.template = string.Template('FIELDNAME == regex(\'.+__[0-9]+$\') && FIELDNAME != regex(\'.+__${reg}$\')')
    341             elif pattern.find('~') >= 0:
    342                 s = map(string.strip, pattern.split('~'))
    343                 if len(s) == 2 and s[0].isdigit() and s[1].isdigit():
    344                     id0 = int(s[0])
    345                     id1 = int(s[1])
    346                     if id0 == 0:
    347                         self.id = id1
    348                         self.template = string.Template('FIELDNAME == regex(\'.+__${reg}$\')')
    349                     else:
    350                         self.id = [id0-1,id1]
    351                         self.template = string.Template('FIELDNAME == regex(\'.+__${reg}$\') && FIELDNAME != regex(\'.+__${optreg}$\')')
    352                 else:
    353                     raise RuntimeError('Invalid syntax: %s'%(pattern))
    354             else:
    355                 raise RuntimeError('Invalid syntax: %s'%(pattern))
    356             #print 'self.id=',self.id
    357 
    358     def get_regex(self):
    359         if self.regex is not None:
    360             # 'X'
    361             return self.regex
    362         elif isinstance(self.id, list):
    363             # 'X~Y'
    364             return self.template.safe_substitute(reg=self.__compile(self.id[1]),
    365                                                  optreg=self.__compile(self.id[0]))
    366         else:
    367             # '<(=)X' or '>(=)X'
    368             return self.template.safe_substitute(reg=self.__compile(self.id))
    369 
    370     def __compile(self, idx):
    371         pattern = ''
    372         if idx >= 0:
    373             numerics = map(int,list(str(idx)))
    374             #numerics.reverse()
    375             num_digits = len(numerics)
    376             #print 'numerics=',numerics
    377             if num_digits == 1:
    378                 if numerics[0] == 0:
    379                     pattern = '0'
    380                 else:
    381                     pattern = '[0-%s]'%(numerics[0])
    382             elif num_digits == 2:
    383                 pattern = '(%s)'%('|'.join(
    384                         list(self.__gen_two_digit_pattern(numerics))))
    385             elif num_digits == 3:
    386                 pattern = '(%s)'%('|'.join(
    387                         list(self.__gen_three_digit_pattern(numerics))))
    388             else:
    389                 raise RuntimeError('ID > 999 is not supported')
    390         else:
    391             raise RuntimeError('ID must be >= 0')
    392         return pattern
    393 
    394     def __gen_two_digit_pattern(self, numerics):
    395         assert len(numerics) == 2
    396         yield '[0-9]'
    397         if numerics[0] == 2:
    398             yield '1[0-9]'
    399         elif numerics[0] > 2:
    400             yield '[1-%s][0-9]'%(numerics[0]-1)
    401         if numerics[1] == 0:
    402             yield '%s%s'%(numerics[0],numerics[1])
    403         else:
    404             yield '%s[0-%s]'%(numerics[0],numerics[1])
    405 
    406     def __gen_three_digit_pattern(self, numerics):
    407         assert len(numerics) == 3
    408         yield '[0-9]'
    409         yield '[1-9][0-9]'
    410         if numerics[0] == 2:
    411             yield '1[0-9][0-9]'
    412         elif numerics[0] > 2:
    413             yield '[1-%s][0-9][0-9]'%(numerics[0]-1)
    414         if numerics[1] == 0:
    415             if numerics[2] == 0:
    416                 yield '%s00'%(numerics[0])
    417             else:
    418                 yield '%s0[0-%s]'%(numerics[0],numerics[2])
    419         else:
    420             if numerics[1] > 1:
    421                 yield '%s[0-%s][0-9]'%(numerics[0],numerics[1]-1)
    422             elif numerics[1] == 1:
    423                 yield '%s0[0-9]'%(numerics[0])
    424             if numerics[0] == 0:
    425                 yield '%s%s%s'%(numerics[0],numerics[1],numerics[2])
    426             else:
    427                 yield '%s%s[0-%s]'%(numerics[0],numerics[1],numerics[2])
  • trunk/python/utils.py

    r3112 r2704  
    1616
    1717def _is_sequence_or_number(param, ptype=int):
    18     import numpy
    19     #if isinstance(param,tuple) or isinstance(param,list):
    20     if type(param) in (tuple, list, numpy.ndarray):
     18    if isinstance(param,tuple) or isinstance(param,list):
    2119        if len(param) == 0: return True # empty list
    2220        out = True
     
    3331        else: return [param]
    3432    if _is_sequence_or_number(param, ptype):
    35         return list(param)
     33        return param
    3634    return None
    3735
Note: See TracChangeset for help on using the changeset viewer.