Changeset 1819


Ignore:
Timestamp:
08/02/10 17:28:20 (14 years ago)
Author:
Kana Sugimoto
Message:

New Development: No

JIRA Issue: No (merge alma branch to trunk)

Ready for Test: Yes

Interface Changes: No

Test Programs: regressions may work

Module(s): all single dish modules

Description:

Merged all changes in alma (r1386:1818) and newfiller (r1774:1818) branch.


Location:
trunk
Files:
46 edited
41 copied

Legend:

Unmodified
Added
Removed
  • trunk/Makefile

  • trunk/SConstruct

    r1740 r1819  
    161161    env = conf.Finish()
    162162
    163 env["version"] = "3.x"
     163env["version"] = "3.0.0"
    164164
    165165if env['mode'] == 'release':
     
    174174
    175175# build externals
    176 env.SConscript("external/SConscript")
     176env.SConscript("external-alma/SConscript")
    177177# build library
    178178so = env.SConscript("src/SConscript", build_dir="build", duplicate=0)
  • trunk/apps

  • trunk/apps/asap2to3.cpp

    r1665 r1819  
    2626  pa.setDefault(Float(0.0));
    2727  tfocus.addColumn(pa);
     28  //tfocus.rwKeywordSet().define("PARALLACTIFY", False)
     29  Int verid=tab.rwKeywordSet().fieldNumber("VERSION");
     30  tab.rwKeywordSet().define(verid,uInt(3));
    2831  cout << "WARNING: This has invalidated the parallactic angle in the data. Reprocess the data in ASAP 3 "
    2932       << "if you need to handle polarisation conversions"
  • trunk/external-alma

  • trunk/getsvnrev.sh

  • trunk/python

  • trunk/python/__init__.py

    r1739 r1819  
    99    from asap.compatibility import wraps as wraps_dec
    1010
    11 # Set up AIPSPATH and first time use of asap i.e. ~/.asap/*
     11# Set up CASAPATH and first time use of asap i.e. ~/.asap/*
    1212plf = None
    1313if sys.platform == "linux2":
     
    2626    if os.path.exists(os.environ["ASAPDATA"]):
    2727        asapdata = os.environ["ASAPDATA"]
    28 # use AIPSPATH if defined and "data" dir present
    29 if not os.environ.has_key("AIPSPATH") or \
    30         not os.path.exists(os.environ["AIPSPATH"].split()[0]+"/data"):
    31     os.environ["AIPSPATH"] = "%s %s somwhere" % ( asapdata, plf)
     28# use CASAPATH if defined and "data" dir present
     29if not os.environ.has_key("CASAPATH") or \
     30        not os.path.exists(os.environ["CASAPATH"].split()[0]+"/data"):
     31    os.environ["CASAPATH"] = "%s %s somwhere" % ( asapdata, plf)
    3232# set up user space
    3333userdir = os.environ["HOME"]+"/.asap"
     
    3535    print 'First time ASAP use. Setting up ~/.asap'
    3636    os.mkdir(userdir)
    37     shutil.copyfile(asapdata+"/data/ipythonrc-asap", userdir+"/ipythonrc-asap")
    38     shutil.copyfile(asapdata+"/data/ipy_user_conf.py",
    39                     userdir+"/ipy_user_conf.py")
     37    #shutil.copyfile(asapdata+"/data/ipythonrc-asap", userdir+"/ipythonrc-asap")
     38    # commented out by TT on 2009.06.23 for casapy use
     39    ##shutil.copyfile(asapdata+"/data/ipy_user_conf.py",
     40    ##                userdir+"/ipy_user_conf.py")
    4041    f = file(userdir+"/asapuserfuncs.py", "w")
    4142    f.close()
    4243    f = file(userdir+"/ipythonrc", "w")
    4344    f.close()
    44 else:
     45# commented out by TT on 2009.06.23 for casapy use
     46##else:
    4547    # upgrade to support later ipython versions
    46     if not os.path.exists(userdir+"/ipy_user_conf.py"):
    47         shutil.copyfile(asapdata+"/data/ipy_user_conf.py",
    48                         userdir+"/ipy_user_conf.py")
     48    ##if not os.path.exists(userdir+"/ipy_user_conf.py"):
     49    ##    shutil.copyfile(asapdata+"/data/ipy_user_conf.py",
     50    ##                    userdir+"/ipy_user_conf.py")
    4951
    5052# remove from namespace
     
    110112    'plotter.histogram'  : [False, _validate_bool],
    111113    'plotter.papertype'  : ['A4', str],
    112     'plotter.axesformatting' : ['mpl', str],
     114    ## for older Matplotlib version
     115    #'plotter.axesformatting' : ['mpl', str],
     116    'plotter.axesformatting' : ['asap', str],
    113117
    114118    # scantable
     
    218222        tup = line.split(':',1)
    219223        if len(tup) !=2:
    220             print ('Illegal line #%d\n\t%s\n\tin file "%s"' % (cnt, line, fname))
     224            #print ('Illegal line #%d\n\t%s\n\tin file "%s"' % (cnt, line, fname))
     225            asaplog.push('Illegal line #%d\n\t%s\n\tin file "%s"' % (cnt, line, fname))
     226            print_log('WARN')
    221227            continue
    222228
     
    224230        key = key.strip()
    225231        if not defaultParams.has_key(key):
    226             print ('Bad key "%s" on line %d in %s' % (key, cnt, fname))
     232            #print ('Bad key "%s" on line %d in %s' % (key, cnt, fname))
     233            asaplog.push('Bad key "%s" on line %d in %s' % (key, cnt, fname))
     234            print_log('WARN')
    227235            continue
    228236
     
    234242        try: cval = converter(val)   # try to convert to proper type or raise
    235243        except ValueError, msg:
    236             print ('Bad val "%s" on line #%d\n\t"%s"\n\tin file "%s"\n\t%s' % (val, cnt, line, fname, msg))
     244            #print ('Bad val "%s" on line #%d\n\t"%s"\n\tin file "%s"\n\t%s' % (val, cnt, line, fname, msg))
     245            asaplog.push('Bad val "%s" on line #%d\n\t"%s"\n\tin file "%s"\n\t%s' % (val, cnt, line, fname, str(msg)))
     246            print_log('WARN')
    237247            continue
    238248        else:
     
    366376    return wrap_it
    367377
    368 def print_log():
    369     log = asaplog.pop().strip()
    370     if len(log) and rcParams['verbose']: print log
     378def print_log(level='INFO'):
     379    from taskinit import casalog
     380    log = asaplog.pop()
     381    #if len(log) and rcParams['verbose']: print log
     382    if len(log) and rcParams['verbose']: casalog.post( log, priority=level )
    371383    return
    372384
     
    391403from simplelinefinder import simplelinefinder
    392404from linecatalog import linecatalog
     405from interactivemask import interactivemask
    393406from opacity import skydip
    394407from opacity import model as opacity_model
     
    400413        if gui:
    401414            import matplotlib
    402             matplotlib.use("TkAgg")
     415            if not matplotlib.sys.modules['matplotlib.backends']: matplotlib.use("TkAgg")
    403416        from matplotlib import pylab
    404417        xyplotter = pylab
     
    406419        del gui
    407420    except ImportError:
    408         print "Matplotlib not installed. No plotting available"
     421        #print "Matplotlib not installed. No plotting available"
     422        asaplog.post( "Matplotlib not installed. No plotting available")
     423        print_log('WARN')
    409424
    410425__date__ = '$Date$'.split()[1]
    411 __version__  = '$Revision$'
     426__version__  = '3.0.0 alma'
     427# nrao casapy specific, get revision number
     428#__revision__ = ' unknown '
     429casapath=os.environ["CASAPATH"].split()
     430#svninfo.txt path
     431if os.path.isdir(casapath[0]+'/'+casapath[1]+'/python/2.5/asap'):
     432    # for casa developer environment (linux or darwin)
     433    revinfo=casapath[0]+'/'+casapath[1]+'/python/2.5/asap/svninfo.txt'
     434else:
     435    # for end-user environments
     436    if casapath[1]=='darwin':
     437        revinfo=casapath[0]+'/Resources/python/asap/svninfo.txt'
     438    else:
     439        revinfo=casapath[0]+'/lib/python2.5/asap/svninfo.txt'
     440if os.path.isfile(revinfo):
     441    f = file(revinfo)
     442    f.readline()
     443    revsionno=f.readline()
     444    f.close()
     445    del f
     446    __revision__ = revsionno.rstrip()
     447else:
     448    __revision__ = ' unknown '
    412449
    413450def is_ipython():
    414451    return 'IPython' in sys.modules.keys()
    415 
    416452if is_ipython():
    417453    def version(): print  "ASAP %s(%s)"% (__version__, __date__)
  • trunk/python/asapfitter.py

    r1739 r1819  
    11import _asap
    22from asap import rcParams
    3 from asap import print_log_dec
     3from asap import print_log, print_log_dec
    44from asap import _n_bools
    55from asap import mask_and
     6from asap import asaplog
    67
    78class fitter:
     
    5960            msg = "Please give a correct scan"
    6061            if rcParams['verbose']:
    61                 print msg
     62                #print msg
     63                asaplog.push(msg)
     64                print_log('ERROR')
    6265                return
    6366            else:
     
    7982            lpoly:   use polynomial of the order given with linear least squares fit
    8083            gauss:   fit the number of gaussian specified
     84            lorentz: fit the number of lorentzian specified
    8185        Example:
    82             fitter.set_function(gauss=2) # will fit two gaussians
    8386            fitter.set_function(poly=3)  # will fit a 3rd order polynomial via nonlinear method
    8487            fitter.set_function(lpoly=3)  # will fit a 3rd order polynomial via linear method
     88            fitter.set_function(gauss=2) # will fit two gaussians
     89            fitter.set_function(lorentz=2) # will fit two lorentzians
    8590        """
    8691        #default poly order 0
     
    102107            self.components = [ 3 for i in range(n) ]
    103108            self.uselinear = False
     109        elif kwargs.has_key('lorentz'):
     110            n = kwargs.get('lorentz')
     111            self.fitfunc = 'lorentz'
     112            self.fitfuncs = [ 'lorentz' for i in range(n) ]
     113            self.components = [ 3 for i in range(n) ]
     114            self.uselinear = False
    104115        else:
    105116            msg = "Invalid function type."
    106117            if rcParams['verbose']:
    107                 print msg
     118                #print msg
     119                asaplog.push(msg)
     120                print_log('ERROR')
    108121                return
    109122            else:
     
    135148            msg = "Fitter not yet initialised. Please set data & fit function"
    136149            if rcParams['verbose']:
    137                 print msg
     150                #print msg
     151                asaplog.push(msg)
     152                print_log('ERROR')
    138153                return
    139154            else:
     
    145160                self.y = self.data._getspectrum(row)
    146161                self.mask = mask_and(self.mask, self.data._getmask(row))
    147                 from asap import asaplog
    148162                asaplog.push("Fitting:")
    149163                i = row
     
    155169                asaplog.push(out,False)
    156170        self.fitter.setdata(self.x, self.y, self.mask)
    157         if self.fitfunc == 'gauss':
     171        if self.fitfunc == 'gauss' or self.fitfunc == 'lorentz':
    158172            ps = self.fitter.getparameters()
    159173            if len(ps) == 0 or estimate:
     
    171185        except RuntimeError, msg:
    172186            if rcParams['verbose']:
    173                 print msg
     187                #print msg
     188                print_log()
     189                asaplog.push(str(msg))
     190                print_log('ERROR')
    174191            else:
    175192                raise
    176193        self._fittedrow = row
    177194        self.fitted = True
     195        print_log()
    178196        return
    179197
     
    228246            msg = "Please specify a fitting function first."
    229247            if rcParams['verbose']:
    230                 print msg
     248                #print msg
     249                asaplog.push(msg)
     250                print_log('ERROR')
    231251                return
    232252            else:
    233253                raise RuntimeError(msg)
    234         if self.fitfunc == "gauss" and component is not None:
     254        if (self.fitfunc == "gauss" or self.fitfunc == 'lorentz') and component is not None:
    235255            if not self.fitted and sum(self.fitter.getparameters()) == 0:
    236256                pars = _n_bools(len(self.components)*3, False)
     
    247267        if fixed is not None:
    248268            self.fitter.setfixedparameters(fixed)
     269        print_log()
    249270        return
    250271
     
    269290            msg = "Function only operates on Gaussian components."
    270291            if rcParams['verbose']:
    271                 print msg
     292                #print msg
     293                asaplog.push(msg)
     294                print_log('ERROR')
    272295                return
    273296            else:
     
    280303            msg = "Please select a valid  component."
    281304            if rcParams['verbose']:
    282                 print msg
     305                #print msg
     306                asaplog.push(msg)
     307                print_log('ERROR')
    283308                return
    284309            else:
    285310                raise ValueError(msg)
    286311
     312    def set_lorentz_parameters(self, peak, centre, fwhm,
     313                             peakfixed=0, centrefixed=0,
     314                             fwhmfixed=0,
     315                             component=0):
     316        """
     317        Set the Parameters of a 'Lorentzian' component, set with set_function.
     318        Parameters:
     319            peak, centre, fwhm:  The gaussian parameters
     320            peakfixed,
     321            centrefixed,
     322            fwhmfixed:           Optional parameters to indicate if
     323                                 the paramters should be held fixed during
     324                                 the fitting process. The default is to keep
     325                                 all parameters flexible.
     326            component:           The number of the component (Default is the
     327                                 component 0)
     328        """
     329        if self.fitfunc != "lorentz":
     330            msg = "Function only operates on Lorentzian components."
     331            if rcParams['verbose']:
     332                #print msg
     333                asaplog.push(msg)
     334                print_log('ERROR')
     335                return
     336            else:
     337                raise ValueError(msg)
     338        if 0 <= component < len(self.components):
     339            d = {'params':[peak, centre, fwhm],
     340                 'fixed':[peakfixed, centrefixed, fwhmfixed]}
     341            self.set_parameters(d, component)
     342        else:
     343            msg = "Please select a valid  component."
     344            if rcParams['verbose']:
     345                #print msg
     346                asaplog.push(msg)
     347                print_log('ERROR')
     348                return
     349            else:
     350                raise ValueError(msg)
     351
    287352    def get_area(self, component=None):
    288353        """
    289         Return the area under the fitted gaussian component.
    290         Parameters:
    291               component:   the gaussian component selection,
     354        Return the area under the fitted gaussian/lorentzian component.
     355        Parameters:
     356              component:   the gaussian/lorentzian component selection,
    292357                           default (None) is the sum of all components
    293358        Note:
    294               This will only work for gaussian fits.
     359              This will only work for gaussian/lorentzian fits.
    295360        """
    296361        if not self.fitted: return
    297         if self.fitfunc == "gauss":
     362        if self.fitfunc == "gauss" or self.fitfunc == "lorentz":
    298363            pars = list(self.fitter.getparameters())
    299364            from math import log,pi,sqrt
    300             fac = sqrt(pi/log(16.0))
     365            if self.fitfunc == "gauss":
     366                fac = sqrt(pi/log(16.0))
     367            elif self.fitfunc == "lorentz":
     368                fac = pi/2.0
    301369            areas = []
    302370            for i in range(len(self.components)):
     
    321389            msg = "Not yet fitted."
    322390            if rcParams['verbose']:
    323                 print msg
     391                #print msg
     392                asaplog.push(msg)
     393                print_log('ERROR')
    324394                return
    325395            else:
     
    328398        cerrs = errs
    329399        if component is not None:
    330             if self.fitfunc == "gauss":
     400            if self.fitfunc == "gauss" or self.fitfunc == "lorentz":
    331401                i = 3*component
    332402                if i < len(errs):
     
    344414            msg = "Not yet fitted."
    345415            if rcParams['verbose']:
    346                 print msg
     416                #print msg
     417                asaplog.push(msg)
     418                print_log('ERROR')
    347419                return
    348420            else:
     
    353425        area = []
    354426        if component is not None:
    355             if self.fitfunc == "gauss":
     427            if self.fitfunc == "gauss" or self.fitfunc == "lorentz":
    356428                i = 3*component
    357429                cpars = pars[i:i+3]
     
    368440            cfixed = fixed
    369441            cerrs = errs
    370             if self.fitfunc == "gauss":
     442            if self.fitfunc == "gauss" or self.fitfunc == "lorentz":
    371443                for c in range(len(self.components)):
    372444                  a = self.get_area(c)
     
    374446        fpars = self._format_pars(cpars, cfixed, errors and cerrs, area)
    375447        if rcParams['verbose']:
    376             print fpars
     448            #print fpars
     449            asaplog.push(fpars)
     450            print_log()
    377451        return {'params':cpars, 'fixed':cfixed, 'formatted': fpars,
    378452                'errors':cerrs}
     
    391465                c+=1
    392466            out = out[:-1]  # remove trailing ','
    393         elif self.fitfunc == 'gauss':
     467        elif self.fitfunc == 'gauss' or self.fitfunc == 'lorentz':
    394468            i = 0
    395469            c = 0
     
    415489        fixed = self.fitter.getfixedparameters()
    416490        if rcParams['verbose']:
    417             print self._format_pars(pars,fixed,None)
     491            #print self._format_pars(pars,fixed,None)
     492            asaplog.push(self._format_pars(pars,fixed,None))
     493            print_log()
    418494        return pars
    419495
     
    425501            msg = "Not yet fitted."
    426502            if rcParams['verbose']:
    427                 print msg
     503                #print msg
     504                asaplog.push(msg)
     505                print_log('ERROR')
    428506                return
    429507            else:
     
    438516            msg = "Not yet fitted."
    439517            if rcParams['verbose']:
    440                 print msg
     518                #print msg
     519                asaplog.push(msg)
     520                print_log('ERROR')
    441521                return
    442522            else:
     
    444524        ch2 = self.fitter.getchi2()
    445525        if rcParams['verbose']:
    446             print 'Chi^2 = %3.3f' % (ch2)
     526            #print 'Chi^2 = %3.3f' % (ch2)
     527            asaplog.push( 'Chi^2 = %3.3f' % (ch2) )
     528            print_log()
    447529        return ch2
    448530
     
    454536            msg = "Not yet fitted."
    455537            if rcParams['verbose']:
    456                 print msg
     538                #print msg
     539                asaplog.push(msg)
     540                print_log('ERROR')
    457541                return
    458542            else:
     
    468552            msg = "Not yet fitted."
    469553            if rcParams['verbose']:
    470                 print msg
     554                #print msg
     555                asaplog.push(msg)
     556                print_log('ERROR')
    471557                return
    472558            else:
     
    476562            msg = "Not a scantable"
    477563            if rcParams['verbose']:
    478                 print msg
     564                #print msg
     565                asaplog.push(msg)
     566                print_log('ERROR')
    479567                return
    480568            else:
     
    482570        scan = self.data.copy()
    483571        scan._setspectrum(self.fitter.getresidual())
     572        print_log()
    484573        return scan
    485574
     
    525614
    526615        colours = ["#777777","#dddddd","red","orange","purple","green","magenta", "cyan"]
     616        nomask=True
     617        for i in range(len(m)):
     618            nomask = nomask and m[i]
     619        label0='Masked Region'
     620        label1='Spectrum'
     621        if ( nomask ):
     622            label0=label1
     623        else:
     624            y = ma.masked_array( self.y, mask = m )
     625            self._p.palette(1,colours)
     626            self._p.set_line( label = label1 )
     627            self._p.plot( self.x, y )
    527628        self._p.palette(0,colours)
    528         self._p.set_line(label='Spectrum')
     629        self._p.set_line(label=label0)
    529630        y = ma.masked_array(self.y,mask=logical_not(m))
    530631        self._p.plot(self.x, y)
    531632        if residual:
    532             self._p.palette(1)
     633            self._p.palette(7)
    533634            self._p.set_line(label='Residual')
    534635            y = ma.masked_array(self.get_residual(),
     
    571672        if (not rcParams['plotter.gui']):
    572673            self._p.save(filename)
     674        print_log()
    573675
    574676    @print_log_dec
     
    583685            msg = "Data is not a scantable"
    584686            if rcParams['verbose']:
    585                 print msg
     687                #print msg
     688                asaplog.push(msg)
     689                print_log('ERROR')
    586690                return
    587691            else:
     
    593697            scan = self.data
    594698        rows = xrange(scan.nrow())
    595         from asap import asaplog
     699        # Save parameters of baseline fits as a class attribute.
     700        # NOTICE: This does not reflect changes in scantable!
     701        if len(rows) > 0: self.blpars=[]
    596702        asaplog.push("Fitting:")
    597703        for r in rows:
     
    608714            self.fit()
    609715            x = self.get_parameters()
     716            fpar = self.get_parameters()
    610717            if plot:
    611718                self.plot(residual=True)
    612719                x = raw_input("Accept fit ([y]/n): ")
    613720                if x.upper() == 'N':
     721                    self.blpars.append(None)
    614722                    continue
    615723            scan._setspectrum(self.fitter.getresidual(), r)
     724            self.blpars.append(fpar)
    616725        if plot:
    617726            self._p.unmap()
    618727            self._p = None
     728        print_log()
    619729        return scan
  • trunk/python/asaplot.py

    r1564 r1819  
    66
    77from matplotlib.backends.backend_agg import FigureCanvasAgg
     8from matplotlib.backend_bases import FigureManagerBase
    89
    910class asaplot(asaplotbase):
     
    2223        asaplotbase.__init__(self,**v)
    2324        self.canvas = FigureCanvasAgg(self.figure)
     25        self.figmgr = FigureManagerBase(self.canvas,1)
  • trunk/python/asaplotbase.py

    r1739 r1819  
    2121    from matplotlib.transforms import blend_xy_sep_transform as blended_transform_factory
    2222
     23from asap import asaplog
     24
    2325if int(matplotlib.__version__.split(".")[1]) < 87:
    24     print "Warning: matplotlib version < 0.87. This might cause errors. Please upgrade."
     26    #print "Warning: matplotlib version < 0.87. This might cause errors. Please upgrade."
     27    asaplog.push( "matplotlib version < 0.87. This might cause errors. Please upgrade." )
     28    print_log( 'WARN' )
    2529
    2630class asaplotbase:
     
    147151        from numpy import array
    148152        from numpy.ma import MaskedArray
    149 
    150153        if x is None:
    151154            if y is None: return
     
    168171            ymsk = y.mask
    169172            ydat = y.data
    170 
    171173        for i in range(l2):
    172174            x2[i] = x[i/2]
     
    304306
    305307        def region_start(event):
    306             height = self.canvas.figure.bbox.height()
    307             self.rect = {'fig': None, 'height': height,
    308                          'x': event.x, 'y': height - event.y,
     308            self.rect = {'x': event.x, 'y': event.y,
    309309                         'world': [event.xdata, event.ydata,
    310310                                   event.xdata, event.ydata]}
     
    314314
    315315        def region_draw(event):
    316             self.canvas._tkcanvas.delete(self.rect['fig'])
    317             self.rect['fig'] = self.canvas._tkcanvas.create_rectangle(
    318                                 self.rect['x'], self.rect['y'],
    319                                 event.x, self.rect['height'] - event.y)
    320 
     316            self.figmgr.toolbar.draw_rubberband(event, event.x, event.y,
     317                                                self.rect['x'], self.rect['y'])
     318           
    321319        def region_disable(event):
    322320            self.register('motion_notify', None)
    323321            self.register('button_release', None)
    324 
    325             self.canvas._tkcanvas.delete(self.rect['fig'])
    326322
    327323            self.rect['world'][2:4] = [event.xdata, event.ydata]
     
    329325                self.rect['world'][1], self.rect['world'][2],
    330326                self.rect['world'][3])
     327            self.figmgr.toolbar.release(event)
    331328
    332329        self.register('button_press', region_start)
     
    381378                self.events[type] = None
    382379
    383                 # It seems to be necessary to return events to the toolbar.
    384                 if type == 'motion_notify':
    385                     self.canvas.mpl_connect(type + '_event',
    386                         self.figmgr.toolbar.mouse_move)
    387                 elif type == 'button_press':
    388                     self.canvas.mpl_connect(type + '_event',
    389                         self.figmgr.toolbar.press)
    390                 elif type == 'button_release':
    391                     self.canvas.mpl_connect(type + '_event',
    392                         self.figmgr.toolbar.release)
     380                # It seems to be necessary to return events to the toolbar. <-- Not ture. 2010.Jul.14.kana.
     381                #if type == 'motion_notify':
     382                #    self.canvas.mpl_connect(type + '_event',
     383                #        self.figmgr.toolbar.mouse_move)
     384                #elif type == 'button_press':
     385                #    self.canvas.mpl_connect(type + '_event',
     386                #        self.figmgr.toolbar.press)
     387                #elif type == 'button_release':
     388                #    self.canvas.mpl_connect(type + '_event',
     389                #        self.figmgr.toolbar.release)
    393390
    394391        else:
     
    459456                    print 'Written file %s' % (fname)
    460457            except IOError, msg:
    461                 print 'Failed to save %s: Error msg was\n\n%s' % (fname, msg)
     458                #print 'Failed to save %s: Error msg was\n\n%s' % (fname, err)
     459                print_log()
     460                asaplog.push('Failed to save %s: Error msg was\n\n%s' % (fname, str(msg)))
     461                print_log( 'ERROR' )
    462462                return
    463463        else:
    464             print "Invalid image type. Valid types are:"
    465             print "'ps', 'eps', 'png'"
     464            #print "Invalid image type. Valid types are:"
     465            #print "'ps', 'eps', 'png'"
     466            asaplog.push( "Invalid image type. Valid types are:" )
     467            asaplog.push( "'ps', 'eps', 'png'" )
     468            print_log('WARN')
    466469
    467470
     
    575578
    576579
    577     def set_panels(self, rows=1, cols=0, n=-1, nplots=-1, ganged=True):
     580    #def set_panels(self, rows=1, cols=0, n=-1, nplots=-1, ganged=True):
     581    def set_panels(self, rows=1, cols=0, n=-1, nplots=-1, layout=None,ganged=True):
    578582        """
    579583        Set the panel layout.
     
    598602            self.set_title()
    599603
     604        if layout:
     605            lef, bot, rig, top, wsp, hsp = layout
     606            self.figure.subplots_adjust(
     607                left=lef,bottom=bot,right=rig,top=top,wspace=wsp,hspace=hsp)
     608            del lef,bot,rig,top,wsp,hsp
     609
    600610        if rows < 1: rows = 1
    601611
     
    610620        if 0 <= n < rows*cols:
    611621            i = len(self.subplots)
     622
    612623            self.subplots.append({})
    613624
     
    644655                                                cols, i+1)
    645656                        if asaprcParams['plotter.axesformatting'] != 'mpl':
    646 
     657                           
    647658                            self.subplots[i]['axes'].xaxis.set_major_formatter(OldScalarFormatter())
    648659                    else:
     
    671682                self.cols = cols
    672683            self.subplot(0)
     684        del rows,cols,n,nplots,layout,ganged,i
    673685
    674686    def tidy(self):
     
    725737                        sp['axes'].legend((' '))
    726738
    727 
    728739            from matplotlib.artist import setp
    729740            fpx = FP(size=rcParams['xtick.labelsize'])
     
    734745            fpat = FP(size=rcParams['axes.titlesize'])
    735746            axsize =  fpa.get_size_in_points()
    736             tsize =  fpat.get_size_in_points()
     747            tsize =  fpat.get_size_in_points()-(self.cols)/2
    737748            for sp in self.subplots:
    738749                ax = sp['axes']
    739                 off = 0
    740                 if len(self.subplots) > 1:
    741                     off = self.cols+self.rows
    742                 ax.title.set_size(tsize-off)
     750                ax.title.set_size(tsize)
    743751                setp(ax.get_xticklabels(), fontsize=xts)
    744752                setp(ax.get_yticklabels(), fontsize=yts)
    745753                off = 0
    746                 if self.cols > 1:
    747                     off = self.cols
     754                if self.cols > 1: off = self.cols
    748755                ax.xaxis.label.set_size(axsize-off)
    749                 if self.rows > 1:
    750                     off = self.rows
     756                off = 0
     757                if self.rows > 1: off = self.rows
    751758                ax.yaxis.label.set_size(axsize-off)
    752759
  • trunk/python/asaplotgui.py

    r1563 r1819  
    5656        self.window.lift()
    5757
    58     def position(self):
    59         """
    60         Use the mouse to get a position from a graph.
    61         """
    62 
    63         def position_disable(event):
    64             self.register('button_press', None)
    65             print '%.4f, %.4f' % (event.xdata, event.ydata)
    66 
    67         print 'Press any mouse button...'
    68         self.register('button_press', position_disable)
    69 
    70 
    7158    def quit(self):
    7259        """
     
    7461        """
    7562        self.window.destroy()
    76 
    77 
    78     def region(self):
    79         """
    80         Use the mouse to get a rectangular region from a plot.
    81 
    82         The return value is [x0, y0, x1, y1] in world coordinates.
    83         """
    84 
    85         def region_start(event):
    86             height = self.canvas.figure.bbox.height()
    87             self.rect = {'fig': None, 'height': height,
    88                          'x': event.x, 'y': height - event.y,
    89                          'world': [event.xdata, event.ydata,
    90                                    event.xdata, event.ydata]}
    91             self.register('button_press', None)
    92             self.register('motion_notify', region_draw)
    93             self.register('button_release', region_disable)
    94 
    95         def region_draw(event):
    96             self.canvas._tkcanvas.delete(self.rect['fig'])
    97             self.rect['fig'] = self.canvas._tkcanvas.create_rectangle(
    98                                 self.rect['x'], self.rect['y'],
    99                                 event.x, self.rect['height'] - event.y)
    100 
    101         def region_disable(event):
    102             self.register('motion_notify', None)
    103             self.register('button_release', None)
    104 
    105             self.canvas._tkcanvas.delete(self.rect['fig'])
    106 
    107             self.rect['world'][2:4] = [event.xdata, event.ydata]
    108             print '(%.2f, %.2f)  (%.2f, %.2f)' % (self.rect['world'][0],
    109                 self.rect['world'][1], self.rect['world'][2],
    110                 self.rect['world'][3])
    111 
    112         self.register('button_press', region_start)
    113 
    114         # This has to be modified to block and return the result (currently
    115         # printed by region_disable) when that becomes possible in matplotlib.
    116 
    117         return [0.0, 0.0, 0.0, 0.0]
    118 
    119 
    120     def register(self, type=None, func=None):
    121         """
    122         Register, reregister, or deregister events of type 'button_press',
    123         'button_release', or 'motion_notify'.
    124 
    125         The specified callback function should have the following signature:
    126 
    127             def func(event)
    128 
    129         where event is an MplEvent instance containing the following data:
    130 
    131             name                # Event name.
    132             canvas              # FigureCanvas instance generating the event.
    133             x      = None       # x position - pixels from left of canvas.
    134             y      = None       # y position - pixels from bottom of canvas.
    135             button = None       # Button pressed: None, 1, 2, 3.
    136             key    = None       # Key pressed: None, chr(range(255)), shift,
    137                                   win, or control
    138             inaxes = None       # Axes instance if cursor within axes.
    139             xdata  = None       # x world coordinate.
    140             ydata  = None       # y world coordinate.
    141 
    142         For example:
    143 
    144             def mouse_move(event):
    145                 print event.xdata, event.ydata
    146 
    147             a = asaplot()
    148             a.register('motion_notify', mouse_move)
    149 
    150         If func is None, the event is deregistered.
    151 
    152         Note that in TkAgg keyboard button presses don't generate an event.
    153         """
    154 
    155         if not self.events.has_key(type): return
    156 
    157         if func is None:
    158             if self.events[type] is not None:
    159                 # It's not clear that this does anything.
    160                 self.canvas.mpl_disconnect(self.events[type])
    161                 self.events[type] = None
    162 
    163                 # It seems to be necessary to return events to the toolbar.
    164                 if type == 'motion_notify':
    165                     self.canvas.mpl_connect(type + '_event',
    166                         self.figmgr.toolbar.mouse_move)
    167                 elif type == 'button_press':
    168                     self.canvas.mpl_connect(type + '_event',
    169                         self.figmgr.toolbar.press)
    170                 elif type == 'button_release':
    171                     self.canvas.mpl_connect(type + '_event',
    172                         self.figmgr.toolbar.release)
    173 
    174         else:
    175             self.events[type] = self.canvas.mpl_connect(type + '_event', func)
    176 
    17763
    17864    def show(self, hardrefresh=True):
  • trunk/python/asaplotgui_gtk.py

    r1563 r1819  
    5757        #self.window.lift()
    5858
    59     def position(self):
    60         """
    61         Use the mouse to get a position from a graph.
    62         """
    63 
    64         def position_disable(event):
    65             self.register('button_press', None)
    66             print '%.4f, %.4f' % (event.xdata, event.ydata)
    67 
    68         print 'Press any mouse button...'
    69         self.register('button_press', position_disable)
     59#     def position(self):
     60#         """
     61#         Use the mouse to get a position from a graph.
     62#         """
     63
     64#         def position_disable(event):
     65#             self.register('button_press', None)
     66#             print '%.4f, %.4f' % (event.xdata, event.ydata)
     67
     68#         print 'Press any mouse button...'
     69#         self.register('button_press', position_disable)
    7070
    7171
     
    7777
    7878
    79     def region(self):
    80         """
    81         Use the mouse to get a rectangular region from a plot.
    82 
    83         The return value is [x0, y0, x1, y1] in world coordinates.
    84         """
    85 
    86         def region_start(event):
    87             height = self.canvas.figure.bbox.height()
    88             self.rect = {'fig': None, 'height': height,
    89                          'x': event.x, 'y': height - event.y,
    90                          'world': [event.xdata, event.ydata,
    91                                    event.xdata, event.ydata]}
    92             self.register('button_press', None)
    93             self.register('motion_notify', region_draw)
    94             self.register('button_release', region_disable)
    95 
    96         def region_draw(event):
    97             self.canvas._tkcanvas.delete(self.rect['fig'])
    98             self.rect['fig'] = self.canvas._tkcanvas.create_rectangle(
    99                                 self.rect['x'], self.rect['y'],
    100                                 event.x, self.rect['height'] - event.y)
    101 
    102         def region_disable(event):
    103             self.register('motion_notify', None)
    104             self.register('button_release', None)
    105 
    106             self.canvas._tkcanvas.delete(self.rect['fig'])
    107 
    108             self.rect['world'][2:4] = [event.xdata, event.ydata]
    109             print '(%.2f, %.2f)  (%.2f, %.2f)' % (self.rect['world'][0],
    110                 self.rect['world'][1], self.rect['world'][2],
    111                 self.rect['world'][3])
    112 
    113         self.register('button_press', region_start)
    114 
    115         # This has to be modified to block and return the result (currently
    116         # printed by region_disable) when that becomes possible in matplotlib.
    117 
    118         return [0.0, 0.0, 0.0, 0.0]
    119 
    120 
    121     def register(self, type=None, func=None):
    122         """
    123         Register, reregister, or deregister events of type 'button_press',
    124         'button_release', or 'motion_notify'.
    125 
    126         The specified callback function should have the following signature:
    127 
    128             def func(event)
    129 
    130         where event is an MplEvent instance containing the following data:
    131 
    132             name                # Event name.
    133             canvas              # FigureCanvas instance generating the event.
    134             x      = None       # x position - pixels from left of canvas.
    135             y      = None       # y position - pixels from bottom of canvas.
    136             button = None       # Button pressed: None, 1, 2, 3.
    137             key    = None       # Key pressed: None, chr(range(255)), shift,
    138                                   win, or control
    139             inaxes = None       # Axes instance if cursor within axes.
    140             xdata  = None       # x world coordinate.
    141             ydata  = None       # y world coordinate.
    142 
    143         For example:
    144 
    145             def mouse_move(event):
    146                 print event.xdata, event.ydata
    147 
    148             a = asaplot()
    149             a.register('motion_notify', mouse_move)
    150 
    151         If func is None, the event is deregistered.
    152 
    153         Note that in TkAgg keyboard button presses don't generate an event.
    154         """
    155 
    156         if not self.events.has_key(type): return
    157 
    158         if func is None:
    159             if self.events[type] is not None:
    160                 # It's not clear that this does anything.
    161                 self.canvas.mpl_disconnect(self.events[type])
    162                 self.events[type] = None
    163 
    164                 # It seems to be necessary to return events to the toolbar.
    165                 if type == 'motion_notify':
    166                     self.canvas.mpl_connect(type + '_event',
    167                         self.figmgr.toolbar.mouse_move)
    168                 elif type == 'button_press':
    169                     self.canvas.mpl_connect(type + '_event',
    170                         self.figmgr.toolbar.press)
    171                 elif type == 'button_release':
    172                     self.canvas.mpl_connect(type + '_event',
    173                         self.figmgr.toolbar.release)
    174 
    175         else:
    176             self.events[type] = self.canvas.mpl_connect(type + '_event', func)
     79#     def region(self):
     80#         """
     81#         Use the mouse to get a rectangular region from a plot.
     82
     83#         The return value is [x0, y0, x1, y1] in world coordinates.
     84#         """
     85
     86#         def region_start(event):
     87#             height = self.canvas.figure.bbox.height()
     88#             self.rect = {'fig': None, 'height': height,
     89#                          'x': event.x, 'y': height - event.y,
     90#                          'world': [event.xdata, event.ydata,
     91#                                    event.xdata, event.ydata]}
     92#             self.register('button_press', None)
     93#             self.register('motion_notify', region_draw)
     94#             self.register('button_release', region_disable)
     95
     96#         def region_draw(event):
     97#             self.canvas._tkcanvas.delete(self.rect['fig'])
     98#             self.rect['fig'] = self.canvas._tkcanvas.create_rectangle(
     99#                                 self.rect['x'], self.rect['y'],
     100#                                 event.x, self.rect['height'] - event.y)
     101
     102#         def region_disable(event):
     103#             self.register('motion_notify', None)
     104#             self.register('button_release', None)
     105
     106#             self.canvas._tkcanvas.delete(self.rect['fig'])
     107
     108#             self.rect['world'][2:4] = [event.xdata, event.ydata]
     109#             print '(%.2f, %.2f)  (%.2f, %.2f)' % (self.rect['world'][0],
     110#                 self.rect['world'][1], self.rect['world'][2],
     111#                 self.rect['world'][3])
     112
     113#         self.register('button_press', region_start)
     114
     115#         # This has to be modified to block and return the result (currently
     116#         # printed by region_disable) when that becomes possible in matplotlib.
     117
     118#         return [0.0, 0.0, 0.0, 0.0]
     119
     120
     121#     def register(self, type=None, func=None):
     122#         """
     123#         Register, reregister, or deregister events of type 'button_press',
     124#         'button_release', or 'motion_notify'.
     125
     126#         The specified callback function should have the following signature:
     127
     128#             def func(event)
     129
     130#         where event is an MplEvent instance containing the following data:
     131
     132#             name                # Event name.
     133#             canvas              # FigureCanvas instance generating the event.
     134#             x      = None       # x position - pixels from left of canvas.
     135#             y      = None       # y position - pixels from bottom of canvas.
     136#             button = None       # Button pressed: None, 1, 2, 3.
     137#             key    = None       # Key pressed: None, chr(range(255)), shift,
     138#                                   win, or control
     139#             inaxes = None       # Axes instance if cursor within axes.
     140#             xdata  = None       # x world coordinate.
     141#             ydata  = None       # y world coordinate.
     142
     143#         For example:
     144
     145#             def mouse_move(event):
     146#                 print event.xdata, event.ydata
     147
     148#             a = asaplot()
     149#             a.register('motion_notify', mouse_move)
     150
     151#         If func is None, the event is deregistered.
     152
     153#         Note that in TkAgg keyboard button presses don't generate an event.
     154#         """
     155
     156#         if not self.events.has_key(type): return
     157
     158#         if func is None:
     159#             if self.events[type] is not None:
     160#                 # It's not clear that this does anything.
     161#                 self.canvas.mpl_disconnect(self.events[type])
     162#                 self.events[type] = None
     163
     164#                 # It seems to be necessary to return events to the toolbar.
     165#                 if type == 'motion_notify':
     166#                     self.canvas.mpl_connect(type + '_event',
     167#                         self.figmgr.toolbar.mouse_move)
     168#                 elif type == 'button_press':
     169#                     self.canvas.mpl_connect(type + '_event',
     170#                         self.figmgr.toolbar.press)
     171#                 elif type == 'button_release':
     172#                     self.canvas.mpl_connect(type + '_event',
     173#                         self.figmgr.toolbar.release)
     174
     175#         else:
     176#             self.events[type] = self.canvas.mpl_connect(type + '_event', func)
    177177
    178178
  • trunk/python/asapmath.py

    r1591 r1819  
    11from asap.scantable import scantable
    22from asap import rcParams
    3 from asap import print_log_dec
     3from asap import print_log, print_log_dec
    44from asap import selector
     5from asap import asaplog
     6from asap import asaplotgui
    57
    68@print_log_dec
     
    4648    if kwargs.has_key('align'):
    4749        align = kwargs.get('align')
     50    compel = False
     51    if kwargs.has_key('compel'):
     52        compel = kwargs.get('compel')
    4853    varlist = vars()
    4954    if isinstance(args[0],list):
     
    6469            msg = "Please give a list of scantables"
    6570            if rcParams['verbose']:
    66                 print msg
     71                #print msg
     72                asaplog.push(msg)
     73                print_log('ERROR')
    6774                return
    6875            else:
     
    8794        del merged
    8895    else:
    89         s = scantable(stm._average(alignedlst, mask, weight.upper(), scanav))
     96        #s = scantable(stm._average(alignedlst, mask, weight.upper(), scanav))
     97        s = scantable(stm._new_average(alignedlst, compel, mask, weight.upper(), scanav))
    9098    s._add_history("average_time",varlist)
     99    print_log()
    91100    return s
    92101
     
    111120    s = scantable(stm._quotient(source, reference, preserve))
    112121    s._add_history("quotient",varlist)
     122    print_log()
    113123    return s
    114124
     
    129139    s = scantable(stm._dototalpower(calon, caloff, tcalval))
    130140    s._add_history("dototalpower",varlist)
     141    print_log()
    131142    return s
    132143
     
    149160    s = scantable(stm._dosigref(sig, ref, smooth, tsysval, tauval))
    150161    s._add_history("dosigref",varlist)
     162    print_log()
    151163    return s
    152164
    153165@print_log_dec
    154 def calps(scantab, scannos, smooth=1, tsysval=0.0, tauval=0.0, tcalval=0.0):
     166def calps(scantab, scannos, smooth=1, tsysval=0.0, tauval=0.0, tcalval=0.0, verify=False):
    155167    """
    156168    Calibrate GBT position switched data
     
    176188    varlist = vars()
    177189    # check for the appropriate data
    178     s = scantab.get_scan('*_ps*')
    179     if s is None:
     190##    s = scantab.get_scan('*_ps*')
     191##     if s is None:
     192##         msg = "The input data appear to contain no position-switch mode data."
     193##         if rcParams['verbose']:
     194##             #print msg
     195##             asaplog.push(msg)
     196##             print_log('ERROR')
     197##             return
     198##         else:
     199##             raise TypeError(msg)
     200    s = scantab.copy()
     201    from asap._asap import srctype
     202    sel = selector()
     203    sel.set_types( srctype.pson )
     204    try:
     205        scantab.set_selection( sel )
     206    except Exception, e:
    180207        msg = "The input data appear to contain no position-switch mode data."
    181208        if rcParams['verbose']:
    182             print msg
     209            #print msg
     210            asaplog.push(msg)
     211            print_log('ERROR')
    183212            return
    184213        else:
    185214            raise TypeError(msg)
     215    s.set_selection()
     216    sel.reset()
    186217    ssub = s.get_scan(scannos)
    187218    if ssub is None:
    188219        msg = "No data was found with given scan numbers!"
    189220        if rcParams['verbose']:
    190             print msg
     221            #print msg
     222            asaplog.push(msg)
     223            print_log('ERROR')
    191224            return
    192225        else:
    193226            raise TypeError(msg)
    194     ssubon = ssub.get_scan('*calon')
    195     ssuboff = ssub.get_scan('*[^calon]')
     227    #ssubon = ssub.get_scan('*calon')
     228    #ssuboff = ssub.get_scan('*[^calon]')
     229    sel.set_types( [srctype.poncal,srctype.poffcal] )
     230    ssub.set_selection( sel )
     231    ssubon = ssub.copy()
     232    ssub.set_selection()
     233    sel.reset()
     234    sel.set_types( [srctype.pson,srctype.psoff] )
     235    ssub.set_selection( sel )
     236    ssuboff = ssub.copy()
     237    ssub.set_selection()
     238    sel.reset()
    196239    if ssubon.nrow() != ssuboff.nrow():
    197240        msg = "mismatch in numbers of CAL on/off scans. Cannot calibrate. Check the scan numbers."
    198241        if rcParams['verbose']:
    199             print msg
     242            #print msg
     243            asaplog.push(msg)
     244            print_log('ERROR')
    200245            return
    201246        else:
    202247            raise TypeError(msg)
    203248    cals = dototalpower(ssubon, ssuboff, tcalval)
    204     sig = cals.get_scan('*ps')
    205     ref = cals.get_scan('*psr')
     249    #sig = cals.get_scan('*ps')
     250    #ref = cals.get_scan('*psr')
     251    sel.set_types( srctype.pson )
     252    cals.set_selection( sel )
     253    sig = cals.copy()
     254    cals.set_selection()
     255    sel.reset()
     256    sel.set_types( srctype.psoff )
     257    cals.set_selection( sel )
     258    ref = cals.copy()
     259    cals.set_selection()
     260    sel.reset()
    206261    if sig.nscan() != ref.nscan():
    207262        msg = "mismatch in numbers of on/off scans. Cannot calibrate. Check the scan numbers."
    208263        if rcParams['verbose']:
    209             print msg
     264            #print msg
     265            asaplog.push(msg)
     266            print_log('ERROR')
    210267            return
    211268        else:
     
    217274            msg = "Need to supply a valid tau to use the supplied Tsys"
    218275            if rcParams['verbose']:
    219                 print msg
     276                #print msg
     277                asaplog.push(msg)
     278                print_log('ERROR')
    220279                return
    221280            else:
     
    236295    #ress = dosigref(sig, ref, smooth, tsysval)
    237296    ress = dosigref(sig, ref, smooth, tsysval, tauval)
     297    ###
     298    if verify:
     299        # get data
     300        import numpy
     301        precal={}
     302        postcal=[]
     303        keys=['ps','ps_calon','psr','psr_calon']
     304        types=[srctype.pson,srctype.poncal,srctype.psoff,srctype.poffcal]
     305        ifnos=list(ssub.getifnos())
     306        polnos=list(ssub.getpolnos())
     307        sel=selector()
     308        for i in range(2):
     309            #ss=ssuboff.get_scan('*'+keys[2*i])
     310            ll=[]
     311            for j in range(len(ifnos)):
     312                for k in range(len(polnos)):
     313                    sel.set_ifs(ifnos[j])
     314                    sel.set_polarizations(polnos[k])
     315                    sel.set_types(types[2*i])
     316                    try:
     317                        #ss.set_selection(sel)
     318                        ssuboff.set_selection(sel)
     319                    except:
     320                        continue
     321                    #ll.append(numpy.array(ss._getspectrum(0)))
     322                    ll.append(numpy.array(ssuboff._getspectrum(0)))
     323                    sel.reset()
     324                    ssuboff.set_selection()
     325            precal[keys[2*i]]=ll
     326            #del ss
     327            #ss=ssubon.get_scan('*'+keys[2*i+1])
     328            ll=[]
     329            for j in range(len(ifnos)):
     330                for k in range(len(polnos)):
     331                    sel.set_ifs(ifnos[j])
     332                    sel.set_polarizations(polnos[k])
     333                    sel.set_types(types[2*i+1])
     334                    try:
     335                        #ss.set_selection(sel)
     336                        ssubon.set_selection(sel)
     337                    except:
     338                        continue
     339                    #ll.append(numpy.array(ss._getspectrum(0)))
     340                    ll.append(numpy.array(ssubon._getspectrum(0)))
     341                    sel.reset()
     342                    ssubon.set_selection()
     343            precal[keys[2*i+1]]=ll
     344            #del ss
     345        for j in range(len(ifnos)):
     346            for k in range(len(polnos)):
     347                sel.set_ifs(ifnos[j])
     348                sel.set_polarizations(polnos[k])
     349                try:
     350                    ress.set_selection(sel)
     351                except:
     352                    continue
     353                postcal.append(numpy.array(ress._getspectrum(0)))
     354                sel.reset()
     355                ress.set_selection()
     356        del sel
     357        # plot
     358        print_log()
     359        asaplog.push('Plot only first spectrum for each [if,pol] pairs to verify calibration.')
     360        print_log('WARN')
     361        p=asaplotgui.asaplotgui()
     362        #nr=min(6,len(ifnos)*len(polnos))
     363        nr=len(ifnos)*len(polnos)
     364        titles=[]
     365        btics=[]
     366        if nr<4:
     367            p.set_panels(rows=nr,cols=2,nplots=2*nr,ganged=False)
     368            for i in range(2*nr):
     369                b=False
     370                if i >= 2*nr-2:
     371                    b=True
     372                btics.append(b)
     373        elif nr==4:
     374            p.set_panels(rows=2,cols=4,nplots=8,ganged=False)
     375            for i in range(2*nr):
     376                b=False
     377                if i >= 2*nr-4:
     378                    b=True
     379                btics.append(b)
     380        elif nr<7:
     381            p.set_panels(rows=3,cols=4,nplots=2*nr,ganged=False)
     382            for i in range(2*nr):
     383                if i >= 2*nr-4:
     384                    b=True
     385                btics.append(b)
     386        else:
     387            print_log()
     388            asaplog.push('Only first 6 [if,pol] pairs are plotted.')
     389            print_log('WARN')
     390            nr=6
     391            for i in range(2*nr):
     392                b=False
     393                if i >= 2*nr-4:
     394                    b=True
     395                btics.append(b)
     396            p.set_panels(rows=3,cols=4,nplots=2*nr,ganged=False)
     397        for i in range(nr):
     398            p.subplot(2*i)
     399            p.color=0
     400            title='raw data IF%s POL%s' % (ifnos[int(i/len(polnos))],polnos[i%len(polnos)])
     401            titles.append(title)
     402            #p.set_axes('title',title,fontsize=40)
     403            ymin=1.0e100
     404            ymax=-1.0e100
     405            nchan=s.nchan()
     406            edge=int(nchan*0.01)
     407            for j in range(4):
     408                spmin=min(precal[keys[j]][i][edge:nchan-edge])
     409                spmax=max(precal[keys[j]][i][edge:nchan-edge])
     410                ymin=min(ymin,spmin)
     411                ymax=max(ymax,spmax)
     412            for j in range(4):
     413                if i==0:
     414                    p.set_line(label=keys[j])
     415                else:
     416                    p.legend()
     417                p.plot(precal[keys[j]][i])
     418            p.axes.set_ylim(ymin-0.1*abs(ymin),ymax+0.1*abs(ymax))
     419            if not btics[2*i]:
     420                p.axes.set_xticks([])
     421            p.subplot(2*i+1)
     422            p.color=0
     423            title='cal data IF%s POL%s' % (ifnos[int(i/len(polnos))],polnos[i%len(polnos)])
     424            titles.append(title)
     425            #p.set_axes('title',title)
     426            p.legend()
     427            ymin=postcal[i][edge:nchan-edge].min()
     428            ymax=postcal[i][edge:nchan-edge].max()
     429            p.plot(postcal[i])
     430            p.axes.set_ylim(ymin-0.1*abs(ymin),ymax+0.1*abs(ymax))
     431            if not btics[2*i+1]:
     432                p.axes.set_xticks([])
     433        for i in range(2*nr):
     434            p.subplot(i)
     435            p.set_axes('title',titles[i],fontsize='medium')
     436        x=raw_input('Accept calibration ([y]/n): ' )
     437        if x.upper() == 'N':
     438            p.unmap()
     439            del p
     440            return scabtab
     441        p.unmap()
     442        del p
     443    ###
    238444    ress._add_history("calps", varlist)
     445    print_log()
    239446    return ress
    240447
    241448@print_log_dec
    242 def calnod(scantab, scannos=[], smooth=1, tsysval=0.0, tauval=0.0, tcalval=0.0):
     449def calnod(scantab, scannos=[], smooth=1, tsysval=0.0, tauval=0.0, tcalval=0.0, verify=False):
    243450    """
    244451    Do full (but a pair of scans at time) processing of GBT Nod data
     
    255462    varlist = vars()
    256463    from asap._asap import stmath
     464    from asap._asap import srctype
    257465    stm = stmath()
    258466    stm._setinsitu(False)
    259467
    260468    # check for the appropriate data
    261     s = scantab.get_scan('*_nod*')
    262     if s is None:
     469##     s = scantab.get_scan('*_nod*')
     470##     if s is None:
     471##         msg = "The input data appear to contain no Nod observing mode data."
     472##         if rcParams['verbose']:
     473##             #print msg
     474##             asaplog.push(msg)
     475##             print_log('ERROR')
     476##             return
     477##         else:
     478##             raise TypeError(msg)
     479    s = scantab.copy()
     480    sel = selector()
     481    sel.set_types( srctype.nod )
     482    try:
     483        s.set_selection( sel )
     484    except Exception, e:
    263485        msg = "The input data appear to contain no Nod observing mode data."
    264486        if rcParams['verbose']:
    265             print msg
     487            #print msg
     488            asaplog.push(msg)
     489            print_log('ERROR')
    266490            return
    267491        else:
    268492            raise TypeError(msg)
     493    sel.reset()
     494    del sel
     495    del s
    269496
    270497    # need check correspondance of each beam with sig-ref ...
     
    300527            msg = "Need to supply a valid tau to use the supplied Tsys"
    301528            if rcParams['verbose']:
    302                 print msg
     529                #print msg
     530                asaplog.push(msg)
     531                print_log('ERROR')
    303532                return
    304533            else:
     
    307536            scantab.recalc_azel()
    308537    resspec = scantable(stm._donod(scantab, pairScans, smooth, tsysval,tauval,tcalval))
     538    ###
     539    if verify:
     540        # get data
     541        import numpy
     542        precal={}
     543        postcal=[]
     544        keys=['','_calon']
     545        types=[srctype.nod,srctype.nodcal]
     546        ifnos=list(scantab.getifnos())
     547        polnos=list(scantab.getpolnos())
     548        sel=selector()
     549        ss = scantab.copy()
     550        for i in range(2):
     551            #ss=scantab.get_scan('*'+keys[i])
     552            ll=[]
     553            ll2=[]
     554            for j in range(len(ifnos)):
     555                for k in range(len(polnos)):
     556                    sel.set_ifs(ifnos[j])
     557                    sel.set_polarizations(polnos[k])
     558                    sel.set_scans(pairScans[0])
     559                    sel.set_types(types[i])
     560                    try:
     561                        ss.set_selection(sel)
     562                    except:
     563                        continue
     564                    ll.append(numpy.array(ss._getspectrum(0)))
     565                    sel.reset()
     566                    ss.set_selection()
     567                    sel.set_ifs(ifnos[j])
     568                    sel.set_polarizations(polnos[k])
     569                    sel.set_scans(pairScans[1])
     570                    sel.set_types(types[i])
     571                    try:
     572                        ss.set_selection(sel)
     573                    except:
     574                        ll.pop()
     575                        continue
     576                    ll2.append(numpy.array(ss._getspectrum(0)))
     577                    sel.reset()
     578                    ss.set_selection()
     579            key='%s%s' %(pairScans[0],keys[i])
     580            precal[key]=ll
     581            key='%s%s' %(pairScans[1],keys[i])
     582            precal[key]=ll2
     583            #del ss
     584        keys=precal.keys()
     585        for j in range(len(ifnos)):
     586            for k in range(len(polnos)):
     587                sel.set_ifs(ifnos[j])
     588                sel.set_polarizations(polnos[k])
     589                sel.set_scans(pairScans[0])
     590                try:
     591                    resspec.set_selection(sel)
     592                except:
     593                    continue
     594                postcal.append(numpy.array(resspec._getspectrum(0)))
     595                sel.reset()
     596                resspec.set_selection()
     597        del sel
     598        # plot
     599        print_log()
     600        asaplog.push('Plot only first spectrum for each [if,pol] pairs to verify calibration.')
     601        print_log('WARN')
     602        p=asaplotgui.asaplotgui()
     603        #nr=min(6,len(ifnos)*len(polnos))
     604        nr=len(ifnos)*len(polnos)
     605        titles=[]
     606        btics=[]
     607        if nr<4:
     608            p.set_panels(rows=nr,cols=2,nplots=2*nr,ganged=False)
     609            for i in range(2*nr):
     610                b=False
     611                if i >= 2*nr-2:
     612                    b=True
     613                btics.append(b)
     614        elif nr==4:
     615            p.set_panels(rows=2,cols=4,nplots=8,ganged=False)
     616            for i in range(2*nr):
     617                b=False
     618                if i >= 2*nr-4:
     619                    b=True
     620                btics.append(b)
     621        elif nr<7:
     622            p.set_panels(rows=3,cols=4,nplots=2*nr,ganged=False)
     623            for i in range(2*nr):
     624                if i >= 2*nr-4:
     625                    b=True
     626                btics.append(b)
     627        else:
     628            print_log()
     629            asaplog.push('Only first 6 [if,pol] pairs are plotted.')
     630            print_log('WARN')
     631            nr=6
     632            for i in range(2*nr):
     633                b=False
     634                if i >= 2*nr-4:
     635                    b=True
     636                btics.append(b)
     637            p.set_panels(rows=3,cols=4,nplots=2*nr,ganged=False)
     638        for i in range(nr):
     639            p.subplot(2*i)
     640            p.color=0
     641            title='raw data IF%s POL%s' % (ifnos[int(i/len(polnos))],polnos[i%len(polnos)])
     642            titles.append(title)
     643            #p.set_axes('title',title,fontsize=40)
     644            ymin=1.0e100
     645            ymax=-1.0e100
     646            nchan=scantab.nchan()
     647            edge=int(nchan*0.01)
     648            for j in range(4):
     649                spmin=min(precal[keys[j]][i][edge:nchan-edge])
     650                spmax=max(precal[keys[j]][i][edge:nchan-edge])
     651                ymin=min(ymin,spmin)
     652                ymax=max(ymax,spmax)
     653            for j in range(4):
     654                if i==0:
     655                    p.set_line(label=keys[j])
     656                else:
     657                    p.legend()
     658                p.plot(precal[keys[j]][i])
     659            p.axes.set_ylim(ymin-0.1*abs(ymin),ymax+0.1*abs(ymax))
     660            if not btics[2*i]:
     661                p.axes.set_xticks([])
     662            p.subplot(2*i+1)
     663            p.color=0
     664            title='cal data IF%s POL%s' % (ifnos[int(i/len(polnos))],polnos[i%len(polnos)])
     665            titles.append(title)
     666            #p.set_axes('title',title)
     667            p.legend()
     668            ymin=postcal[i][edge:nchan-edge].min()
     669            ymax=postcal[i][edge:nchan-edge].max()
     670            p.plot(postcal[i])
     671            p.axes.set_ylim(ymin-0.1*abs(ymin),ymax+0.1*abs(ymax))
     672            if not btics[2*i+1]:
     673                p.axes.set_xticks([])
     674        for i in range(2*nr):
     675            p.subplot(i)
     676            p.set_axes('title',titles[i],fontsize='medium')
     677        x=raw_input('Accept calibration ([y]/n): ' )
     678        if x.upper() == 'N':
     679            p.unmap()
     680            del p
     681            return scabtab
     682        p.unmap()
     683        del p
     684    ###
    309685    resspec._add_history("calnod",varlist)
     686    print_log()
    310687    return resspec
    311688
    312689@print_log_dec
    313 def calfs(scantab, scannos=[], smooth=1, tsysval=0.0, tauval=0.0, tcalval=0.0):
     690def calfs(scantab, scannos=[], smooth=1, tsysval=0.0, tauval=0.0, tcalval=0.0, verify=False):
    314691    """
    315692    Calibrate GBT frequency switched data.
     
    333710    varlist = vars()
    334711    from asap._asap import stmath
     712    from asap._asap import srctype
    335713    stm = stmath()
    336714    stm._setinsitu(False)
     
    348726
    349727    resspec = scantable(stm._dofs(s, scannos, smooth, tsysval,tauval,tcalval))
     728    ###
     729    if verify:
     730        # get data
     731        ssub = s.get_scan(scannos)
     732        #ssubon = ssub.get_scan('*calon')
     733        #ssuboff = ssub.get_scan('*[^calon]')
     734        sel = selector()
     735        sel.set_types( [srctype.foncal,srctype.foffcal] )
     736        ssub.set_selection( sel )
     737        ssubon = ssub.copy()
     738        ssub.set_selection()
     739        sel.reset()
     740        sel.set_types( [srctype.fson,srctype.fsoff] )
     741        ssub.set_selection( sel )
     742        ssuboff = ssub.copy()
     743        ssub.set_selection()
     744        sel.reset()
     745        import numpy
     746        precal={}
     747        postcal=[]
     748        keys=['fs','fs_calon','fsr','fsr_calon']
     749        types=[srctype.fson,srctype.foncal,srctype.fsoff,srctype.foffcal]
     750        ifnos=list(ssub.getifnos())
     751        polnos=list(ssub.getpolnos())
     752        for i in range(2):
     753            #ss=ssuboff.get_scan('*'+keys[2*i])
     754            ll=[]
     755            for j in range(len(ifnos)):
     756                for k in range(len(polnos)):
     757                    sel.set_ifs(ifnos[j])
     758                    sel.set_polarizations(polnos[k])
     759                    sel.set_types(types[2*i])
     760                    try:
     761                        #ss.set_selection(sel)
     762                        ssuboff.set_selection(sel)
     763                    except:
     764                        continue
     765                    ll.append(numpy.array(ss._getspectrum(0)))
     766                    sel.reset()
     767                    #ss.set_selection()
     768                    ssuboff.set_selection()
     769            precal[keys[2*i]]=ll
     770            #del ss
     771            #ss=ssubon.get_scan('*'+keys[2*i+1])
     772            ll=[]
     773            for j in range(len(ifnos)):
     774                for k in range(len(polnos)):
     775                    sel.set_ifs(ifnos[j])
     776                    sel.set_polarizations(polnos[k])
     777                    sel.set_types(types[2*i+1])
     778                    try:
     779                        #ss.set_selection(sel)
     780                        ssubon.set_selection(sel)
     781                    except:
     782                        continue
     783                    ll.append(numpy.array(ss._getspectrum(0)))
     784                    sel.reset()
     785                    #ss.set_selection()
     786                    ssubon.set_selection()
     787            precal[keys[2*i+1]]=ll
     788            #del ss
     789        #sig=resspec.get_scan('*_fs')
     790        #ref=resspec.get_scan('*_fsr')
     791        sel.set_types( srctype.fson )
     792        resspec.set_selection( sel )
     793        sig=resspec.copy()
     794        resspec.set_selection()
     795        sel.reset()
     796        sel.set_type( srctype.fsoff )
     797        resspec.set_selection( sel )
     798        ref=resspec.copy()
     799        resspec.set_selection()
     800        sel.reset()
     801        for k in range(len(polnos)):
     802            for j in range(len(ifnos)):
     803                sel.set_ifs(ifnos[j])
     804                sel.set_polarizations(polnos[k])
     805                try:
     806                    sig.set_selection(sel)
     807                    postcal.append(numpy.array(sig._getspectrum(0)))
     808                except:
     809                    ref.set_selection(sel)
     810                    postcal.append(numpy.array(ref._getspectrum(0)))
     811                sel.reset()
     812                resspec.set_selection()
     813        del sel
     814        # plot
     815        print_log()
     816        asaplog.push('Plot only first spectrum for each [if,pol] pairs to verify calibration.')
     817        print_log('WARN')
     818        p=asaplotgui.asaplotgui()
     819        #nr=min(6,len(ifnos)*len(polnos))
     820        nr=len(ifnos)/2*len(polnos)
     821        titles=[]
     822        btics=[]
     823        if nr>3:
     824            print_log()
     825            asaplog.push('Only first 3 [if,pol] pairs are plotted.')
     826            print_log('WARN')
     827            nr=3
     828        p.set_panels(rows=nr,cols=3,nplots=3*nr,ganged=False)
     829        for i in range(3*nr):
     830            b=False
     831            if i >= 3*nr-3:
     832                b=True
     833            btics.append(b)
     834        for i in range(nr):
     835            p.subplot(3*i)
     836            p.color=0
     837            title='raw data IF%s,%s POL%s' % (ifnos[2*int(i/len(polnos))],ifnos[2*int(i/len(polnos))+1],polnos[i%len(polnos)])
     838            titles.append(title)
     839            #p.set_axes('title',title,fontsize=40)
     840            ymin=1.0e100
     841            ymax=-1.0e100
     842            nchan=s.nchan()
     843            edge=int(nchan*0.01)
     844            for j in range(4):
     845                spmin=min(precal[keys[j]][i][edge:nchan-edge])
     846                spmax=max(precal[keys[j]][i][edge:nchan-edge])
     847                ymin=min(ymin,spmin)
     848                ymax=max(ymax,spmax)
     849            for j in range(4):
     850                if i==0:
     851                    p.set_line(label=keys[j])
     852                else:
     853                    p.legend()
     854                p.plot(precal[keys[j]][i])
     855            p.axes.set_ylim(ymin-0.1*abs(ymin),ymax+0.1*abs(ymax))
     856            if not btics[3*i]:
     857                p.axes.set_xticks([])
     858            p.subplot(3*i+1)
     859            p.color=0
     860            title='sig data IF%s POL%s' % (ifnos[2*int(i/len(polnos))],polnos[i%len(polnos)])
     861            titles.append(title)
     862            #p.set_axes('title',title)
     863            p.legend()
     864            ymin=postcal[2*i][edge:nchan-edge].min()
     865            ymax=postcal[2*i][edge:nchan-edge].max()
     866            p.plot(postcal[2*i])
     867            p.axes.set_ylim(ymin-0.1*abs(ymin),ymax+0.1*abs(ymax))
     868            if not btics[3*i+1]:
     869                p.axes.set_xticks([])
     870            p.subplot(3*i+2)
     871            p.color=0
     872            title='ref data IF%s POL%s' % (ifnos[2*int(i/len(polnos))+1],polnos[i%len(polnos)])
     873            titles.append(title)
     874            #p.set_axes('title',title)
     875            p.legend()
     876            ymin=postcal[2*i+1][edge:nchan-edge].min()
     877            ymax=postcal[2*i+1][edge:nchan-edge].max()
     878            p.plot(postcal[2*i+1])
     879            p.axes.set_ylim(ymin-0.1*abs(ymin),ymax+0.1*abs(ymax))
     880            if not btics[3*i+2]:
     881                p.axes.set_xticks([])
     882        for i in range(3*nr):
     883            p.subplot(i)
     884            p.set_axes('title',titles[i],fontsize='medium')
     885        x=raw_input('Accept calibration ([y]/n): ' )
     886        if x.upper() == 'N':
     887            p.unmap()
     888            del p
     889            return scabtab
     890        p.unmap()
     891        del p
     892    ###
    350893    resspec._add_history("calfs",varlist)
     894    print_log()
    351895    return resspec
    352 
    353896
    354897@print_log_dec
     
    380923            msg = "Please give a list of scantables"
    381924            if rcParams['verbose']:
    382                 print msg
     925                #print msg
     926                asaplog.push(msg)
     927                print_log('ERROR')
    383928                return
    384929            else:
     
    386931    s = scantable(stm._merge(lst))
    387932    s._add_history("merge", varlist)
     933    print_log()
    388934    return s
     935
     936def calibrate( scantab, scannos=[], calmode='none', verify=None ):
     937    """
     938    Calibrate data.
     939   
     940    Parameters:
     941        scantab:       scantable
     942        scannos:       list of scan number
     943        calmode:       calibration mode
     944        verify:        verify calibration     
     945    """
     946    antname = scantab.get_antennaname()
     947    if ( calmode == 'nod' ):
     948        asaplog.push( 'Calibrating nod data.' )
     949        print_log()
     950        scal = calnod( scantab, scannos=scannos, verify=verify )
     951    elif ( calmode == 'quotient' ):
     952        asaplog.push( 'Calibrating using quotient.' )
     953        print_log()
     954        scal = scantab.auto_quotient( verify=verify )
     955    elif ( calmode == 'ps' ):
     956        asaplog.push( 'Calibrating %s position-switched data.' % antname )
     957        print_log()
     958        if ( antname.find( 'APEX' ) != -1 ):
     959            scal = apexcal( scantab, scannos, calmode, verify )
     960        elif ( antname.find( 'ALMA' ) != -1 or antname.find( 'OSF' ) != -1 ):
     961            scal = almacal( scantab, scannos, calmode, verify )
     962        else:
     963            scal = calps( scantab, scannos=scannos, verify=verify )
     964    elif ( calmode == 'fs' or calmode == 'fsotf' ):
     965        asaplog.push( 'Calibrating %s frequency-switched data.' % antname )
     966        print_log()
     967        if ( antname.find( 'APEX' ) != -1 ):
     968            scal = apexcal( scantab, scannos, calmode, verify )
     969        elif ( antname.find( 'ALMA' ) != -1 or antname.find( 'OSF' ) != -1 ):
     970            scal = almacal( scantab, scannos, calmode, verify )
     971        else:
     972            scal = calfs( scantab, scannos=scannos, verify=verify )
     973    elif ( calmode == 'otf' ):
     974        asaplog.push( 'Calibrating %s On-The-Fly data.' % antname )
     975        print_log()
     976        scal = almacal( scantab, scannos, calmode, verify )
     977    else:
     978        asaplog.push( 'No calibration.' )
     979        scal = scantab.copy()
     980
     981    return scal
     982
     983def apexcal( scantab, scannos=[], calmode='none', verify=False ):
     984    """
     985    Calibrate APEX data
     986
     987    Parameters:
     988        scantab:       scantable
     989        scannos:       list of scan number
     990        calmode:       calibration mode
     991
     992        verify:        verify calibration     
     993    """
     994    from asap._asap import stmath
     995    stm = stmath()
     996    antname = scantab.get_antennaname()
     997    ssub = scantab.get_scan( scannos )
     998    scal = scantable( stm.cwcal( ssub, calmode, antname ) )
     999    return scal
     1000
     1001def almacal( scantab, scannos=[], calmode='none', verify=False ):
     1002    """
     1003    Calibrate ALMA data
     1004
     1005    Parameters:
     1006        scantab:       scantable
     1007        scannos:       list of scan number
     1008        calmode:       calibration mode
     1009
     1010        verify:        verify calibration     
     1011    """
     1012    from asap._asap import stmath
     1013    stm = stmath()
     1014    ssub = scantab.get_scan( scannos )
     1015    scal = scantable( stm.almacal( ssub, calmode ) )
     1016    return scal
     1017
     1018def splitant(filename, outprefix='',overwrite=False):
     1019    """
     1020    Split Measurement set by antenna name, save data as a scantables,
     1021    and return a list of filename.
     1022    Notice this method can only be available from CASA.
     1023    Prameter
     1024       filename:    the name of Measurement set to be read.
     1025       outprefix:   the prefix of output scantable name.
     1026                    the names of output scantable will be
     1027                    outprefix.antenna1, outprefix.antenna2, ....
     1028                    If not specified, outprefix = filename is assumed.
     1029       overwrite    If the file should be overwritten if it exists.
     1030                    The default False is to return with warning
     1031                    without writing the output. USE WITH CARE.
     1032                   
     1033    """
     1034    # Import the table toolkit from CASA
     1035    try:
     1036       import casac
     1037    except ImportError:
     1038       if rcParams['verbose']:
     1039           #print "failed to load casa"
     1040           print_log()
     1041           asaplog.push("failed to load casa")
     1042           print_log('ERROR')
     1043       else: raise
     1044       return False
     1045    try:
     1046       tbtool = casac.homefinder.find_home_by_name('tableHome')
     1047       tb = tbtool.create()
     1048       tb2 = tbtool.create()
     1049    except:
     1050       if rcParams['verbose']:
     1051           #print "failed to load a table tool:\n", e
     1052           print_log()
     1053           asaplog.push("failed to load table tool")
     1054           print_log('ERROR')
     1055       else: raise
     1056       return False
     1057    # Check the input filename
     1058    if isinstance(filename, str):
     1059        import os.path
     1060        filename = os.path.expandvars(filename)
     1061        filename = os.path.expanduser(filename)
     1062        if not os.path.exists(filename):
     1063            s = "File '%s' not found." % (filename)
     1064            if rcParams['verbose']:
     1065                print_log()
     1066                asaplog.push(s)
     1067                print_log('ERROR')
     1068                return
     1069            raise IOError(s)
     1070        # check if input file is MS
     1071        if not os.path.isdir(filename) \
     1072               or not os.path.exists(filename+'/ANTENNA') \
     1073               or not os.path.exists(filename+'/table.f1'):
     1074            s = "File '%s' is not a Measurement set." % (filename)
     1075            if rcParams['verbose']:
     1076                print_log()
     1077                asaplog.push(s)
     1078                print_log('ERROR')
     1079                return
     1080            raise IOError(s)
     1081    else:
     1082        s = "The filename should be string. "
     1083        if rcParams['verbose']:
     1084            print_log()
     1085            asaplog.push(s)
     1086            print_log('ERROR')
     1087            return
     1088        raise TypeError(s)
     1089    # Check out put file name
     1090    outname=''
     1091    if len(outprefix) > 0: prefix=outprefix+'.'
     1092    else:
     1093        prefix=filename.rstrip('/')
     1094    # Now do the actual splitting.
     1095    outfiles=[]
     1096    tb.open(tablename=filename+'/ANTENNA',nomodify=True)
     1097    nant=tb.nrows()
     1098    antnames=tb.getcol('NAME',0,nant,1)
     1099    antpos=tb.getcol('POSITION',0,nant,1).transpose()
     1100    tb.close()
     1101    tb.open(tablename=filename,nomodify=True)
     1102    ant1=tb.getcol('ANTENNA1',0,-1,1)
     1103    tb.close()
     1104    for antid in set(ant1):
     1105        scan=scantable(filename,average=False,getpt=True,antenna=int(antid))
     1106        outname=prefix+antnames[antid]+'.asap'
     1107        scan.save(outname,format='ASAP',overwrite=overwrite)
     1108        del scan
     1109        outfiles.append(outname)
     1110    del tb, tb2
     1111    return outfiles
     1112
     1113def _array2dOp( scan, value, mode="ADD", tsys=False ):
     1114    """
     1115    This function is workaround on the basic operation of scantable
     1116    with 2 dimensional float list.
     1117
     1118    scan:    scantable operand
     1119    value:   float list operand
     1120    mode:    operation mode (ADD, SUB, MUL, DIV)
     1121    tsys:    if True, operate tsys as well
     1122    """
     1123    nrow = scan.nrow()
     1124    s = None
     1125    if len( value ) == 1:
     1126        from asap._asap import stmath
     1127        stm = stmath()
     1128        s = scantable( stm._arrayop( scan.copy(), value[0], mode, tsys ) )
     1129        del stm
     1130    elif len( value ) != nrow:
     1131        asaplog.push( 'len(value) must be 1 or conform to scan.nrow()' )
     1132        print_log( 'ERROR' )
     1133    else:
     1134        from asap._asap import stmath
     1135        stm = stmath()
     1136        # insitu must be True
     1137        stm._setinsitu( True )
     1138        s = scan.copy()
     1139        sel = selector()
     1140        for irow in range( nrow ):
     1141            sel.set_rows( irow )
     1142            s.set_selection( sel )
     1143            if len( value[irow] ) == 1:
     1144                stm._unaryop( s, value[irow][0], mode, tsys )
     1145            else:
     1146                stm._arrayop( s, value[irow], mode, tsys, 'channel' )
     1147            s.set_selection()
     1148            sel.reset()
     1149        del sel
     1150        del stm
     1151    return s
     1152
     1153           
     1154           
  • trunk/python/asapplotter.py

    r1739 r1819  
    11from asap import rcParams, print_log, print_log_dec
    22from asap import selector, scantable
     3from asap import asaplog
    34import matplotlib.axes
    45from matplotlib.font_manager import FontProperties
     
    2122            self._visible = visible
    2223        self._plotter = self._newplotter(**kwargs)
     24        # additional tool bar
     25        self._plotter.figmgr.casabar=self._newcasabar()
    2326
    2427        self._panelling = None
     
    4346        self._hist = rcParams['plotter.histogram']
    4447        self._fp = FontProperties()
     48        self._panellayout = self.set_panellayout(refresh=False)
    4549
    4650    def _translate(self, instr):
     
    5357
    5458    def _newplotter(self, **kwargs):
    55         if self._visible:
     59        backend=matplotlib.get_backend()
     60        if not self._visible:
     61            from asap.asaplot import asaplot
     62        elif backend == 'TkAgg':
    5663            from asap.asaplotgui import asaplotgui as asaplot
     64        elif backend == 'Qt4Agg':
     65            from asap.asaplotgui_qt4 import asaplotgui as asaplot
     66        elif backend == 'GTkAgg':
     67            from asap.asaplotgui_gtk import asaplotgui as asaplot
    5768        else:
    5869            from asap.asaplot import asaplot
    5970        return asaplot(**kwargs)
     71
     72    def _newcasabar(self):
     73        backend=matplotlib.get_backend()
     74        if self._visible and backend == "TkAgg":
     75            from asap.casatoolbar import CustomToolbarTkAgg
     76            return CustomToolbarTkAgg(self)
     77        else: return None
    6078
    6179    @print_log_dec
     
    7290        """
    7391        if self._plotter.is_dead:
     92            if hasattr(self._plotter.figmgr,'casabar'):
     93                del self._plotter.figmgr.casabar
    7494            self._plotter = self._newplotter()
     95            self._plotter.figmgr.casabar=self._newcasabar()
    7596        self._plotter.hold()
    7697        self._plotter.clear()
    77         from asap import scantable
    7898        if not self._data and not scan:
    7999            msg = "Input is not a scantable"
    80100            if rcParams['verbose']:
    81                 print msg
     101                #print msg
     102                asaplog.push( msg )
     103                print_log( 'ERROR' )
    82104                return
    83105            raise TypeError(msg)
    84         if isinstance(scan, scantable):
    85             if self._data is not None:
    86                 if scan != self._data:
    87                     self._data = scan
    88                     # reset
    89                     self._reset()
    90             else:
    91                 self._data = scan
    92                 self._reset()
    93         # ranges become invalid when unit changes
    94         if self._abcunit and self._abcunit != self._data.get_unit():
    95             self._minmaxx = None
    96             self._minmaxy = None
    97             self._abcunit = self._data.get_unit()
    98             self._datamask = None
     106        if scan: self.set_data(scan,refresh=False)
    99107        self._plot(self._data)
    100108        if self._minmaxy is not None:
    101109            self._plotter.set_limits(ylim=self._minmaxy)
     110        if self._plotter.figmgr.casabar: self._plotter.figmgr.casabar.enable_button()
    102111        self._plotter.release()
    103112        self._plotter.tidy()
    104113        self._plotter.show(hardrefresh=False)
     114        print_log()
    105115        return
    106116
     
    238248                dpos = (pos[0][1], pos[1][1])
    239249                args = dpos + args
    240 
    241250        self._axes_callback("axhspan", *args, **kwargs)
    242251        # hack to preventy mpl from redrawing the patch
     
    265274    # end matplotlib.axes fowarding functions
    266275
    267 
    268     def set_mode(self, stacking=None, panelling=None):
     276    def set_data(self, scan, refresh=True):
     277        """
     278        Set a scantable to plot.
     279        Parameters:
     280            scan:      a scantable
     281            refresh:   True (default) or False. If True, the plot is
     282                       replotted based on the new parameter setting(s).
     283                       Otherwise,the parameter(s) are set without replotting.
     284        Note:
     285           The user specified masks and data selections will be reset
     286           if a new scantable is set. This method should be called before
     287           setting data selections (set_selection) and/or masks (set_mask).
     288        """
     289        from asap import scantable
     290        if isinstance(scan, scantable):
     291            if self._data is not None:
     292                if scan != self._data:
     293                    self._data = scan
     294                    # reset
     295                    self._reset()
     296                    msg = "A new scantable is set to the plotter. The masks and data selections are reset."
     297                    asaplog.push( msg )
     298                    print_log( 'INFO' )
     299            else:
     300                self._data = scan
     301                self._reset()
     302        else:
     303            msg = "Input is not a scantable"
     304            if rcParams['verbose']:
     305                #print msg
     306                asaplog.push( msg )
     307                print_log( 'ERROR' )
     308                return
     309            raise TypeError(msg)
     310
     311        # ranges become invalid when unit changes
     312        if self._abcunit and self._abcunit != self._data.get_unit():
     313            self._minmaxx = None
     314            self._minmaxy = None
     315            self._abcunit = self._data.get_unit()
     316            self._datamask = None
     317        if refresh: self.plot()
     318       
     319
     320    def set_mode(self, stacking=None, panelling=None, refresh=True):
    269321        """
    270322        Set the plots look and feel, i.e. what you want to see on the plot.
     
    274326            panelling:    tell the plotter which variable to plot
    275327                          across multiple panels (default 'scan'
     328            refresh:      True (default) or False. If True, the plot is
     329                          replotted based on the new parameter setting(s).
     330                          Otherwise,the parameter(s) are set without replotting.
    276331        Note:
    277332            Valid modes are:
     
    286341               not self.set_stacking(stacking):
    287342            if rcParams['verbose']:
    288                 print msg
     343                #print msg
     344                asaplog.push( msg )
     345                print_log( 'ERROR' )
    289346                return
    290347            else:
    291348                raise TypeError(msg)
    292         if self._data: self.plot(self._data)
     349        if refresh and self._data: self.plot(self._data)
    293350        return
    294351
     
    304361        return False
    305362
    306     def set_layout(self,rows=None,cols=None):
     363    def set_layout(self,rows=None,cols=None,refresh=True):
    307364        """
    308365        Set the multi-panel layout, i.e. how many rows and columns plots
     
    311368             rows:   The number of rows of plots
    312369             cols:   The number of columns of plots
     370             refresh:  True (default) or False. If True, the plot is
     371                       replotted based on the new parameter setting(s).
     372                       Otherwise,the parameter(s) are set without replotting.
    313373        Note:
    314374             If no argument is given, the potter reverts to its auto-plot
     
    317377        self._rows = rows
    318378        self._cols = cols
    319         if self._data: self.plot(self._data)
     379        if refresh and self._data: self.plot(self._data)
    320380        return
    321381
     
    331391        return False
    332392
    333     def set_range(self,xstart=None,xend=None,ystart=None,yend=None):
     393    def set_range(self,xstart=None,xend=None,ystart=None,yend=None,refresh=True):
    334394        """
    335395        Set the range of interest on the abcissa of the plot
    336396        Parameters:
    337397            [x,y]start,[x,y]end:  The start and end points of the 'zoom' window
     398            refresh:  True (default) or False. If True, the plot is
     399                      replotted based on the new parameter setting(s).
     400                      Otherwise,the parameter(s) are set without replotting.
    338401        Note:
    339402            These become non-sensical when the unit changes.
     
    349412        else:
    350413            self._minmaxy = [ystart,yend]
    351         if self._data: self.plot(self._data)
     414        if refresh and self._data: self.plot(self._data)
    352415        return
    353416
    354     def set_legend(self, mp=None, fontsize = None, mode = 0):
     417    def set_legend(self, mp=None, fontsize = None, mode = 0, refresh=True):
    355418        """
    356419        Specify a mapping for the legend instead of using the default
     
    376439                        9: upper center
    377440                        10: center
     441            refresh:    True (default) or False. If True, the plot is
     442                        replotted based on the new parameter setting(s).
     443                        Otherwise,the parameter(s) are set without replotting.
    378444
    379445        Example:
     
    390456            from matplotlib import rc as rcp
    391457            rcp('legend', fontsize=fontsize)
    392         if self._data:
    393             self.plot(self._data)
     458        if refresh and self._data: self.plot(self._data)
    394459        return
    395460
    396     def set_title(self, title=None, fontsize=None):
     461    def set_title(self, title=None, fontsize=None, refresh=True):
    397462        """
    398463        Set the title of the plot. If multiple panels are plotted,
    399464        multiple titles have to be specified.
     465        Parameters:
     466            refresh:    True (default) or False. If True, the plot is
     467                        replotted based on the new parameter setting(s).
     468                        Otherwise,the parameter(s) are set without replotting.
    400469        Example:
    401470             # two panels are visible on the plotter
     
    406475            from matplotlib import rc as rcp
    407476            rcp('axes', titlesize=fontsize)
    408         if self._data: self.plot(self._data)
     477        if refresh and self._data: self.plot(self._data)
    409478        return
    410479
    411     def set_ordinate(self, ordinate=None, fontsize=None):
     480    def set_ordinate(self, ordinate=None, fontsize=None, refresh=True):
    412481        """
    413482        Set the y-axis label of the plot. If multiple panels are plotted,
     
    416485            ordinate:    a list of ordinate labels. None (default) let
    417486                         data determine the labels
     487            refresh:     True (default) or False. If True, the plot is
     488                         replotted based on the new parameter setting(s).
     489                         Otherwise,the parameter(s) are set without replotting.
    418490        Example:
    419491             # two panels are visible on the plotter
     
    425497            rcp('axes', labelsize=fontsize)
    426498            rcp('ytick', labelsize=fontsize)
    427         if self._data: self.plot(self._data)
     499        if refresh and self._data: self.plot(self._data)
    428500        return
    429501
    430     def set_abcissa(self, abcissa=None, fontsize=None):
     502    def set_abcissa(self, abcissa=None, fontsize=None, refresh=True):
    431503        """
    432504        Set the x-axis label of the plot. If multiple panels are plotted,
     
    435507            abcissa:     a list of abcissa labels. None (default) let
    436508                         data determine the labels
     509            refresh:     True (default) or False. If True, the plot is
     510                         replotted based on the new parameter setting(s).
     511                         Otherwise,the parameter(s) are set without replotting.
    437512        Example:
    438513             # two panels are visible on the plotter
     
    444519            rcp('axes', labelsize=fontsize)
    445520            rcp('xtick', labelsize=fontsize)
    446         if self._data: self.plot(self._data)
     521        if refresh and self._data: self.plot(self._data)
    447522        return
    448523
    449     def set_colors(self, colmap):
     524    def set_colors(self, colmap, refresh=True):
    450525        """
    451526        Set the colours to be used. The plotter will cycle through
     
    453528        Parameters:
    454529            colmap:     a list of colour names
     530            refresh:    True (default) or False. If True, the plot is
     531                        replotted based on the new parameter setting(s).
     532                        Otherwise,the parameter(s) are set without replotting.
    455533        Example:
    456534             plotter.set_colors("red green blue")
     
    462540            colmap = colmap.split()
    463541        self._plotter.palette(0, colormap=colmap)
    464         if self._data: self.plot(self._data)
     542        if refresh and self._data: self.plot(self._data)
    465543
    466544    # alias for english speakers
    467545    set_colours = set_colors
    468546
    469     def set_histogram(self, hist=True, linewidth=None):
     547    def set_histogram(self, hist=True, linewidth=None, refresh=True):
    470548        """
    471549        Enable/Disable histogram-like plotting.
     
    474552                         is taken from the .asaprc setting
    475553                         plotter.histogram
     554            refresh:     True (default) or False. If True, the plot is
     555                         replotted based on the new parameter setting(s).
     556                         Otherwise,the parameter(s) are set without replotting.
    476557        """
    477558        self._hist = hist
     
    479560            from matplotlib import rc as rcp
    480561            rcp('lines', linewidth=linewidth)
    481         if self._data: self.plot(self._data)
    482 
    483     def set_linestyles(self, linestyles=None, linewidth=None):
     562        if refresh and self._data: self.plot(self._data)
     563
     564    def set_linestyles(self, linestyles=None, linewidth=None, refresh=True):
    484565        """
    485566        Set the linestyles to be used. The plotter will cycle through
     
    491572                             'dashdotdot' and 'dashdashdot' are
    492573                             possible
    493 
     574            refresh:         True (default) or False. If True, the plot is
     575                             replotted based on the new parameter setting(s).
     576                             Otherwise,the parameter(s) are set without replotting.
    494577        Example:
    495578             plotter.set_colors("black")
     
    505588            from matplotlib import rc as rcp
    506589            rcp('lines', linewidth=linewidth)
    507         if self._data: self.plot(self._data)
    508 
    509     def set_font(self, **kwargs):
     590        if refresh and self._data: self.plot(self._data)
     591
     592    def set_font(self, refresh=True,**kwargs):
    510593        """
    511594        Set font properties.
     
    516599            size:      the 'general' font size, individual elements can be adjusted
    517600                       seperately
     601            refresh:   True (default) or False. If True, the plot is
     602                       replotted based on the new parameter setting(s).
     603                       Otherwise,the parameter(s) are set without replotting.
    518604        """
    519605        from matplotlib import rc as rcp
     
    523609                fdict[k] = v
    524610        self._fp = FontProperties(**fdict)
    525         if self._data:
    526             self.plot()
     611        if refresh and self._data: self.plot(self._data)
     612
     613    def set_panellayout(self,layout=[],refresh=True):
     614        """
     615        Set the layout of subplots.
     616        Parameters:
     617            layout:   a list of subplots layout in figure coordinate (0-1),
     618                      i.e., fraction of the figure width or height.
     619                      The order of elements should be:
     620                      [left, bottom, right, top, horizontal space btw panels,
     621                      vertical space btw panels].
     622            refresh:  True (default) or False. If True, the plot is
     623                      replotted based on the new parameter setting(s).
     624                      Otherwise,the parameter(s) are set without replotting.
     625        Note
     626        * When layout is not specified, the values are reset to the defaults
     627          of matplotlib.
     628        * If any element is set to be None, the current value is adopted.
     629        """
     630        if layout == []: self._panellayout=self._reset_panellayout()
     631        else:
     632            self._panellayout=[None]*6
     633            self._panellayout[0:len(layout)]=layout
     634        #print "panel layout set to ",self._panellayout
     635        if refresh and self._data: self.plot(self._data)
     636
     637    def _reset_panellayout(self):
     638        ks=map(lambda x: 'figure.subplot.'+x,
     639               ['left','bottom','right','top','hspace','wspace'])
     640        return map(matplotlib.rcParams.get,ks)
    527641
    528642    def plot_lines(self, linecat=None, doppler=0.0, deltachan=10, rotate=90.0,
     
    622736
    623737
    624     def set_mask(self, mask=None, selection=None):
     738    def set_mask(self, mask=None, selection=None, refresh=True):
    625739        """
    626740        Set a plotting mask for a specific polarization.
     
    629743             mask:           a mask from scantable.create_mask
    630744             selection:      the spectra to apply the mask to.
     745             refresh:        True (default) or False. If True, the plot is
     746                             replotted based on the new parameter setting(s).
     747                             Otherwise,the parameter(s) are set without replotting.
    631748        Example:
    632749             select = selector()
     
    637754            msg = "Can only set mask after a first call to plot()"
    638755            if rcParams['verbose']:
    639                 print msg
     756                #print msg
     757                asaplog.push( msg )
     758                print_log( 'ERROR' )
    640759                return
    641760            else:
     
    657776        else:
    658777            self._maskselection = None
    659         self.plot(self._data)
     778        if refresh: self.plot(self._data)
    660779
    661780    def _slice_indeces(self, data):
     
    671790            inc = -1
    672791        # find min index
    673         while start > 0 and data[start] < mn:
    674             start+= inc
     792        #while start > 0 and data[start] < mn:
     793        #    start+= inc
     794        minind=start
     795        for ind in xrange(start,end+inc,inc):
     796            if data[ind] > mn: break
     797            minind=ind
    675798        # find max index
    676         while end > 0 and data[end] > mx:
    677             end-=inc
    678         if end > 0: end +=1
     799        #while end > 0 and data[end] > mx:
     800        #    end-=inc
     801        #if end > 0: end +=1
     802        maxind=end
     803        for ind in xrange(end,start-inc,-inc):
     804            if data[ind] < mx: break
     805            maxind=ind
     806        start=minind
     807        end=maxind
    679808        if start > end:
    680             return end,start
    681         return start,end
     809            return end,start+1
     810        elif start < end:
     811            return start,end+1
     812        else:
     813            return start,end
    682814
    683815    def _reset(self):
     
    708840        maxpanel, maxstack = 16,16
    709841        if n > maxpanel or nstack > maxstack:
    710             from asap import asaplog
    711842            maxn = 0
    712843            if nstack > maxstack: maxn = maxstack
     
    715846                  "Selecting first %d selections..." % (maxn, maxn)
    716847            asaplog.push(msg)
    717             print_log()
     848            print_log('WARN')
    718849            n = min(n,maxpanel)
    719850            nstack = min(nstack,maxstack)
    720851        if n > 1:
    721852            ganged = rcParams['plotter.ganged']
     853            if self._panelling == 'i':
     854                ganged = False
    722855            if self._rows and self._cols:
    723856                n = min(n,self._rows*self._cols)
    724857                self._plotter.set_panels(rows=self._rows,cols=self._cols,
    725                                          nplots=n,ganged=ganged)
     858#                                         nplots=n,ganged=ganged)
     859                                         nplots=n,layout=self._panellayout,ganged=ganged)
    726860            else:
    727                 self._plotter.set_panels(rows=n,cols=0,nplots=n,ganged=ganged)
     861#                self._plotter.set_panels(rows=n,cols=0,nplots=n,ganged=ganged)
     862                self._plotter.set_panels(rows=n,cols=0,nplots=n,layout=self._panellayout,ganged=ganged)
    728863        else:
    729             self._plotter.set_panels()
     864#            self._plotter.set_panels()
     865            self._plotter.set_panels(layout=self._panellayout)
    730866        r=0
    731867        nr = scan.nrow()
     
    799935                    ylim= self._minmaxy or [ma.minimum(y),ma.maximum(y)]
    800936                    allylim += ylim
     937                else:
     938                    xlim = self._minmaxx or []
     939                    allxlim += xlim
     940                    ylim= self._minmaxy or []
     941                    allylim += ylim
    801942                stackcount += 1
    802943                # last in colour stack -> autoscale x
    803                 if stackcount == nstack:
     944                if stackcount == nstack and len(allxlim) > 0:
    804945                    allxlim.sort()
    805                     self._plotter.axes.set_xlim([allxlim[0],allxlim[-1]])
     946                    self._plotter.subplots[panelcount-1]['axes'].set_xlim([allxlim[0],allxlim[-1]])
    806947                    # clear
    807948                    allxlim =[]
     
    813954            if (panelcount == n) and (stackcount == nstack):
    814955                # last panel -> autoscale y if ganged
    815                 if rcParams['plotter.ganged']:
     956                if rcParams['plotter.ganged'] and len(allylim) > 0:
    816957                    allylim.sort()
    817958                    self._plotter.set_limits(ylim=[allylim[0],allylim[-1]])
     
    820961        #reset the selector to the scantable's original
    821962        scan.set_selection(savesel)
    822         if self._fp is not None:
     963       
     964        #temporary switch-off for older matplotlib
     965        #if self._fp is not None:
     966        if self._fp is not None and getattr(self._plotter.figure,'findobj',False):
    823967            for o in self._plotter.figure.findobj(Text):
    824968                o.set_fontproperties(self._fp)
    825969
    826 
    827970    def set_selection(self, selection=None, refresh=True, **kw):
     971        """
     972        Parameters:
     973            selection:  a selector object (default unset the selection)
     974            refresh:    True (default) or False. If True, the plot is
     975                        replotted based on the new parameter setting(s).
     976                        Otherwise,the parameter(s) are set without replotting.
     977        """
    828978        if selection is None:
    829979            # reset
     
    845995        order = [d0[self._panelling],d0[self._stacking]]
    846996        self._selection.set_order(order)
    847         if self._data and refresh: self.plot(self._data)
     997        if refresh and self._data: self.plot(self._data)
    848998
    849999    def _get_selected_n(self, scan):
     
    8681018            poleval = scan._getpollabel(scan.getpol(row),scan.poltype())
    8691019        d = {'b': "Beam "+str(scan.getbeam(row)),
    870              's': scan._getsourcename(row),
     1020             #'s': scan._getsourcename(row),
     1021             's': "Scan "+str(scan.getscan(row))+\
     1022                  " ("+str(scan._getsourcename(row))+")",
    8711023             'i': "IF"+str(scan.getif(row)),
    8721024             'p': poleval,
     
    8741026        return userlabel or d[mode]
    8751027
    876     def plotazel(self):
     1028    def plotazel(self, scan=None, outfile=None):
     1029    #def plotazel(self):
    8771030        """
    8781031        plot azimuth and elevation versus time of a scantable
     
    8831036        from matplotlib.ticker import MultipleLocator
    8841037        from numpy import array, pi
     1038        self._data = scan
     1039        self._outfile = outfile
    8851040        dates = self._data.get_time(asdatetime=True)
    8861041        t = PL.date2num(dates)
     
    8891044        PL.ioff()
    8901045        PL.clf()
     1046        # Adjust subplot layouts
     1047        if len(self._panellayout) !=6: self.set_panellayout(refresh=False)
     1048        lef, bot, rig, top, wsp, hsp = self._panellayout
     1049        PL.gcf().subplots_adjust(left=lef,bottom=bot,right=rig,top=top,
     1050                                 wspace=wsp,hspace=hsp)
     1051       
    8911052        tdel = max(t) - min(t)
    8921053        ax = PL.subplot(2,1,1)
     
    9101071
    9111072        PL.title(dstr)
    912         PL.plot_date(t,el,'b,', tz=tz)
     1073        if tdel == 0.0:
     1074            th = (t - PL.floor(t))*24.0
     1075            PL.plot(th,el,'o',markersize=2, markerfacecolor='b', markeredgecolor='b')
     1076        else:
     1077            PL.plot_date(t,el,'o', markersize=2, markerfacecolor='b', markeredgecolor='b',tz=tz)
     1078            #ax.grid(True)
     1079            ax.xaxis.set_major_formatter(timefmt)
     1080            ax.xaxis.set_major_locator(majloc)
     1081            ax.xaxis.set_minor_locator(minloc)
    9131082        ax.yaxis.grid(True)
    914 
     1083        yloc = MultipleLocator(30)
     1084        ax.set_ylim(0,90)
     1085        ax.yaxis.set_major_locator(yloc)
    9151086        if tdel > 1.0:
    9161087            labels = ax.get_xticklabels()
    9171088        #    PL.setp(labels, fontsize=10, rotation=45)
    9181089            PL.setp(labels, fontsize=10)
     1090
    9191091        # Az plot
    9201092        az = array(self._data.get_azimuth())*180./pi
     
    9231095                if az[irow] < 0: az[irow] += 360.0
    9241096
    925         ax2 = ax.figure.add_subplot(2,1,2, sharex=ax)
    926         ax2.set_xlabel('Time (UT)')
    927         ax2.set_ylabel('Az [deg.]')
    928         ax2.plot_date(t,az,'b,', tz=tz)
     1097        ax2 = PL.subplot(2,1,2)
     1098        #PL.xlabel('Time (UT [hour])')
     1099        PL.ylabel('Az [deg.]')
     1100        if tdel == 0.0:
     1101            PL.plot(th,az,'o',markersize=2, markeredgecolor='b',markerfacecolor='b')
     1102        else:
     1103            PL.plot_date(t,az,'o', markersize=2,markeredgecolor='b',markerfacecolor='b',tz=tz)
     1104            ax2.xaxis.set_major_formatter(timefmt)
     1105            ax2.xaxis.set_major_locator(majloc)
     1106            ax2.xaxis.set_minor_locator(minloc)
     1107        #ax2.grid(True)
     1108        ax2.set_ylim(0,360)
    9291109        ax2.yaxis.grid(True)
    930         # set this last as x axis is shared
    931         ax.xaxis.set_major_formatter(timefmt)
    932         ax.xaxis.set_major_locator(majloc)
    933         ax.xaxis.set_minor_locator(minloc)
     1110        #hfmt = DateFormatter('%H')
     1111        #hloc = HourLocator()
     1112        yloc = MultipleLocator(60)
     1113        ax2.yaxis.set_major_locator(yloc)
     1114        if tdel > 1.0:
     1115            labels = ax2.get_xticklabels()
     1116            PL.setp(labels, fontsize=10)
     1117            PL.xlabel('Time (UT [day])')
     1118        else:
     1119            PL.xlabel('Time (UT [hour])')
     1120
    9341121        PL.ion()
    9351122        PL.draw()
    936 
    937     def plotpointing(self):
     1123        if (self._outfile is not None):
     1124           PL.savefig(self._outfile)
     1125
     1126    def plotpointing(self, scan=None, outfile=None):
     1127    #def plotpointing(self):
    9381128        """
    9391129        plot telescope pointings
    9401130        """
    9411131        from matplotlib import pylab as PL
    942         from numpy import array
     1132        from numpy import array, pi
     1133        self._data = scan
     1134        self._outfile = outfile
    9431135        dir = array(self._data.get_directionval()).transpose()
    9441136        ra = dir[0]*180./pi
    9451137        dec = dir[1]*180./pi
    9461138        PL.cla()
    947         PL.ioff()
     1139        #PL.ioff()
    9481140        PL.clf()
    949         ax = PL.axes([0.1,0.1,0.8,0.8])
    950         ax = PL.axes([0.1,0.1,0.8,0.8])
     1141        # Adjust subplot layouts
     1142        if len(self._panellayout) !=6: self.set_panellayout(refresh=False)
     1143        lef, bot, rig, top, wsp, hsp = self._panellayout
     1144        PL.gcf().subplots_adjust(left=lef,bottom=bot,right=rig,top=top,
     1145                                 wspace=wsp,hspace=hsp)
     1146        ax = PL.gca()
     1147        #ax = PL.axes([0.1,0.1,0.8,0.8])
     1148        #ax = PL.axes([0.1,0.1,0.8,0.8])
    9511149        ax.set_aspect('equal')
    9521150        PL.plot(ra, dec, 'b,')
     
    9561154        [xmin,xmax,ymin,ymax] = PL.axis()
    9571155        PL.axis([xmax,xmin,ymin,ymax])
    958         PL.ion()
     1156        #PL.ion()
    9591157        PL.draw()
     1158        if (self._outfile is not None):
     1159           PL.savefig(self._outfile)
     1160
     1161    # plot total power data
     1162    # plotting in time is not yet implemented..
     1163    def plottp(self, scan=None, outfile=None):
     1164        if self._plotter.is_dead:
     1165            if hasattr(self._plotter.figmgr,'casabar'):
     1166                del self._plotter.figmgr.casabar
     1167            self._plotter = self._newplotter()
     1168            self._plotter.figmgr.casabar=self._newcasabar()
     1169        self._plotter.hold()
     1170        self._plotter.clear()
     1171        from asap import scantable
     1172        if not self._data and not scan:
     1173            msg = "Input is not a scantable"
     1174            if rcParams['verbose']:
     1175                #print msg
     1176                asaplog.push( msg )
     1177                print_log( 'ERROR' )
     1178                return
     1179            raise TypeError(msg)
     1180        if isinstance(scan, scantable):
     1181            if self._data is not None:
     1182                if scan != self._data:
     1183                    self._data = scan
     1184                    # reset
     1185                    self._reset()
     1186            else:
     1187                self._data = scan
     1188                self._reset()
     1189        # ranges become invalid when abcissa changes?
     1190        #if self._abcunit and self._abcunit != self._data.get_unit():
     1191        #    self._minmaxx = None
     1192        #    self._minmaxy = None
     1193        #    self._abcunit = self._data.get_unit()
     1194        #    self._datamask = None
     1195
     1196        # Adjust subplot layouts
     1197        if len(self._panellayout) !=6: self.set_panellayout(refresh=False)
     1198        lef, bot, rig, top, wsp, hsp = self._panellayout
     1199        self._plotter.figure.subplots_adjust(
     1200            left=lef,bottom=bot,right=rig,top=top,wspace=wsp,hspace=hsp)
     1201        if self._plotter.figmgr.casabar: self._plotter.figmgr.casabar.disable_button()
     1202        self._plottp(self._data)
     1203        if self._minmaxy is not None:
     1204            self._plotter.set_limits(ylim=self._minmaxy)
     1205        self._plotter.release()
     1206        self._plotter.tidy()
     1207        self._plotter.show(hardrefresh=False)
     1208        print_log()
     1209        return
     1210
     1211    def _plottp(self,scan):
     1212        """
     1213        private method for plotting total power data
     1214        """
     1215        from numpy import ma, array, arange, logical_not
     1216        r=0
     1217        nr = scan.nrow()
     1218        a0,b0 = -1,-1
     1219        allxlim = []
     1220        allylim = []
     1221        y=[]
     1222        self._plotter.set_panels()
     1223        self._plotter.palette(0)
     1224        #title
     1225        #xlab = self._abcissa and self._abcissa[panelcount] \
     1226        #       or scan._getabcissalabel()
     1227        #ylab = self._ordinate and self._ordinate[panelcount] \
     1228        #       or scan._get_ordinate_label()
     1229        xlab = self._abcissa or 'row number' #or Time
     1230        ylab = self._ordinate or scan._get_ordinate_label()
     1231        self._plotter.set_axes('xlabel',xlab)
     1232        self._plotter.set_axes('ylabel',ylab)
     1233        lbl = self._get_label(scan, r, 's', self._title)
     1234        if isinstance(lbl, list) or isinstance(lbl, tuple):
     1235        #    if 0 <= panelcount < len(lbl):
     1236        #        lbl = lbl[panelcount]
     1237        #    else:
     1238                # get default label
     1239             lbl = self._get_label(scan, r, self._panelling, None)
     1240        self._plotter.set_axes('title',lbl)
     1241        y=array(scan._get_column(scan._getspectrum,-1))
     1242        m = array(scan._get_column(scan._getmask,-1))
     1243        y = ma.masked_array(y,mask=logical_not(array(m,copy=False)))
     1244        x = arange(len(y))
     1245        # try to handle spectral data somewhat...
     1246        l,m = y.shape
     1247        if m > 1:
     1248            y=y.mean(axis=1)
     1249        plotit = self._plotter.plot
     1250        llbl = self._get_label(scan, r, self._stacking, None)
     1251        self._plotter.set_line(label=llbl)
     1252        if len(x) > 0:
     1253            plotit(x,y)
     1254
     1255
     1256    # forwards to matplotlib.Figure.text
     1257    def figtext(self, *args, **kwargs):
     1258        """
     1259        Add text to figure at location x,y (relative 0-1 coords).
     1260        This method forwards *args and **kwargs to a Matplotlib method,
     1261        matplotlib.Figure.text.
     1262        See the method help for detailed information.
     1263        """
     1264        self._plotter.text(*args, **kwargs)
     1265    # end matplotlib.Figure.text forwarding function
     1266
     1267
     1268    # printing header information
     1269    def print_header(self, plot=True, fontsize=9, logger=False, selstr='', extrastr=''):
     1270        """
     1271        print data (scantable) header on the plot and/or logger.
     1272        Parameters:
     1273            plot:      whether or not print header info on the plot.
     1274            fontsize:  header font size (valid only plot=True)
     1275            autoscale: whether or not autoscale the plot (valid only plot=True)
     1276            logger:    whether or not print header info on the logger.
     1277            selstr:    additional selection string (not verified)
     1278            extrastr:  additional string to print (not verified)
     1279        """
     1280        if not plot and not logger: return
     1281        if not self._data: raise RuntimeError("No scantable has been set yet.")
     1282        # Now header will be printed on plot and/or logger.
     1283        # Get header information and format it.
     1284        ssum=self._data.__str__()
     1285        # Print Observation header to the upper-left corner of plot
     1286        if plot:
     1287            headstr=[ssum[ssum.find('Observer:'):ssum.find('Flux Unit:')]]
     1288            headstr.append(ssum[ssum.find('Beams:'):ssum.find('Observer:')]
     1289                         +ssum[ssum.find('Rest Freqs:'):ssum.find('Abcissa:')])
     1290            if extrastr != '': headstr[0]=extrastr+'\n'+headstr[0]
     1291            #headstr[1]='Data File:     '+(filestr or 'unknown')+'\n'+headstr[1]
     1292            ssel='***Selections***\n'+(selstr+self._data.get_selection().__str__() or 'none')
     1293            headstr.append(ssel)
     1294            nstcol=len(headstr)
     1295           
     1296            self._plotter.hold()
     1297            for i in range(nstcol):
     1298                self._plotter.figure.text(0.03+float(i)/nstcol,0.98,
     1299                             headstr[i],
     1300                             horizontalalignment='left',
     1301                             verticalalignment='top',
     1302                             fontsize=fontsize)
     1303            import time
     1304            self._plotter.figure.text(0.99,0.0,
     1305                            time.strftime("%a %d %b %Y  %H:%M:%S %Z"),
     1306                            horizontalalignment='right',
     1307                            verticalalignment='bottom',fontsize=8)
     1308            self._plotter.release()
     1309            del headstr, ssel
     1310        if logger:
     1311            asaplog.push("----------------\n  Plot Summary\n----------------")
     1312            asaplog.push(extrastr)
     1313            asaplog.push(ssum[ssum.find('Beams:'):])
     1314            print_log()
     1315        del ssum
     1316
     1317
  • trunk/python/asapreader.py

    r1695 r1819  
    11from asap._asap import stfiller
    2 from asap import print_log_dec
     2from asap import print_log, print_log_dec
    33
    44class reader(stfiller):
     
    4646        filename = expandvars(filename)
    4747        stfiller.__init__(self, filename, theif, thebeam)
     48        print_log()
    4849
    4950    @print_log_dec
     
    5960        if self.unit is not None:
    6061            tbl.set_fluxunit(self.unit)
     62        print_log()
    6163        return scantable(tbl)
    6264
  • trunk/python/linecatalog.py

    r1534 r1819  
    88from asap._asap import linecatalog as lcbase
    99from asap import rcParams
     10from asap import asaplog
    1011import os
    1112
     
    3031            msg = "File '%s' not found" % fpath
    3132            if rcParams['verbose']:
    32                 print msg
     33                #print msg
     34                asaplog.push( msg )
     35                print_log( 'ERROR' )
    3336                return
    3437            else:
     
    97100                msg = "File %s exists." % name
    98101                if rcParams['verbose']:
    99                     print msg
     102                    #print msg
     103                    asaplog.push( msg )
     104                    print_log( 'ERROR' )
    100105                    return
    101106                else:
  • trunk/python/scantable.py

    r1731 r1819  
    3535        The ASAP container for scans
    3636    """
    37     @print_log_dec
    38     def __init__(self, filename, average=None, unit=None, parallactify=None):
     37
     38    @print_log_dec
     39    def __init__(self, filename, average=None, unit=None, getpt=None, antenna=None, parallactify=None):
    3940        """
    4041        Create a scantable from a saved one or make a reference
     
    5455                         (input rpfits/sdfits/ms) or replaces the value
    5556                         in existing scantables
     57            getpt:       for MeasurementSet input data only:
     58                         If True, all pointing data are filled.
     59                         The deafult is False, which makes time to load
     60                         the MS data faster in some cases.
     61            antenna:     Antenna selection. integer (id) or string (name
     62                         or id).
    5663            parallactify: Indcicate that the data had been parallatified.
    5764                          Default is taken form rc file.
     
    5966        if average is None:
    6067            average = rcParams['scantable.autoaverage']
     68        if getpt is None:
     69            getpt = True
     70        if antenna is None:
     71            antenna = ''
     72        elif type(antenna) == int:
     73            antenna = '%s'%antenna
     74        elif type(antenna) == list:
     75            tmpstr = ''
     76            for i in range( len(antenna) ):
     77                if type(antenna[i]) == int:
     78                    tmpstr = tmpstr + ('%s,'%(antenna[i]))
     79                elif type(antenna[i]) == str:
     80                    tmpstr=tmpstr+antenna[i]+','
     81                else:
     82                    asaplog.push('Bad antenna selection.')
     83                    print_log('ERROR')
     84                    return
     85            antenna = tmpstr.rstrip(',')
    6186        parallactify = parallactify or rcParams['scantable.parallactify']
    6287        varlist = vars()
    6388        from asap._asap import stmath
    64         self._math = stmath()
     89        self._math = stmath( rcParams['insitu'] )
    6590        if isinstance(filename, Scantable):
    6691            Scantable.__init__(self, filename)
     
    7398                    if rcParams['verbose']:
    7499                        asaplog.push(s)
     100                        print_log('ERROR')
    75101                        return
    76102                    raise IOError(s)
     
    80106                    if unit is not None:
    81107                        self.set_fluxunit(unit)
    82                     self.set_freqframe(rcParams['scantable.freqframe'])
     108                    # do not reset to the default freqframe
     109                    #self.set_freqframe(rcParams['scantable.freqframe'])
     110                elif os.path.isdir(filename) \
     111                         and not os.path.exists(filename+'/table.f1'):
     112                    msg = "The given file '%s'is not a valid " \
     113                          "asap table." % (filename)
     114                    if rcParams['verbose']:
     115                        #print msg
     116                        asaplog.push( msg )
     117                        print_log( 'ERROR' )
     118                        return
     119                    else:
     120                        raise IOError(msg)
    83121                else:
    84                     self._fill([filename], unit, average)
     122                    self._fill([filename], unit, average, getpt, antenna)
    85123            elif (isinstance(filename, list) or isinstance(filename, tuple)) \
    86124                  and isinstance(filename[-1], str):
    87                 self._fill(filename, unit, average)
     125                self._fill(filename, unit, average, getpt, antenna)
    88126        self.parallactify(parallactify)
    89127        self._add_history("scantable", varlist)
     128        print_log()
    90129
    91130    @print_log_dec
     
    126165                msg = "File %s exists." % name
    127166                if rcParams['verbose']:
    128                     print msg
     167                    #print msg
     168                    asaplog.push( msg )
     169                    print_log( 'ERROR' )
    129170                    return
    130171                else:
     
    137178            writer = stw(format2)
    138179            writer.write(self, name)
     180        print_log()
    139181        return
    140182
     
    164206        if not _is_valid(scanid):
    165207            if rcParams['verbose']:
    166                 print "Please specify a scanno to drop from the scantable"
     208                #print "Please specify a scanno to drop from the scantable"
     209                asaplog.push( 'Please specify a scanno to drop from the scantable' )
     210                print_log( 'ERROR' )
    167211                return
    168212            else:
     
    176220        except ValueError:
    177221            if rcParams['verbose']:
    178                 print "Couldn't find any match."
     222                #print "Couldn't find any match."
     223                print_log()
     224                asaplog.push( "Couldn't find any match." )
     225                print_log( 'ERROR' )
    179226                return
    180227            else: raise
     
    184231        except RuntimeError:
    185232            if rcParams['verbose']:
    186                 print "Couldn't find any match."
     233                #print "Couldn't find any match."
     234                print_log()
     235                asaplog.push( "Couldn't find any match." )
     236                print_log( 'ERROR' )
    187237            else:
    188238                raise
     
    215265        if scanid is None:
    216266            if rcParams['verbose']:
    217                 print "Please specify a scan no or name to " \
    218                       "retrieve from the scantable"
     267                #print "Please specify a scan no or name to " \
     268                #      "retrieve from the scantable"
     269                asaplog.push( 'Please specify a scan no or name to retrieve from the scantable' )
     270                print_log( 'ERROR' )
    219271                return
    220272            else:
     
    236288                msg = "Illegal scanid type, use 'int' or 'list' if ints."
    237289                if rcParams['verbose']:
    238                     print msg
     290                    #print msg
     291                    asaplog.push( msg )
     292                    print_log( 'ERROR' )
    239293                else:
    240294                    raise TypeError(msg)
    241295        except RuntimeError:
    242             if rcParams['verbose']: print "Couldn't find any match."
     296            if rcParams['verbose']:
     297                #print "Couldn't find any match."
     298                print_log()
     299                asaplog.push( "Couldn't find any match." )
     300                print_log( 'ERROR' )
    243301            else: raise
    244302
     
    266324                msg = "Illegal file name '%s'." % (filename)
    267325                if rcParams['verbose']:
    268                     print msg
     326                    #print msg
     327                    asaplog.push( msg )
     328                    print_log( 'ERROR' )
    269329                else:
    270330                    raise IOError(msg)
     
    367427        self._setselection(selection)
    368428
    369     def stats(self, stat='stddev', mask=None):
     429    def get_row(self, row=0, insitu=None):
     430        """
     431        Select a row in the scantable.
     432        Return a scantable with single row.
     433        Parameters:
     434            row: row no of integration, default is 0.
     435            insitu: if False a new scantable is returned.
     436                    Otherwise, the scaling is done in-situ
     437                    The default is taken from .asaprc (False)
     438        """
     439        if insitu is None: insitu = rcParams['insitu']
     440        if not insitu:
     441            workscan = self.copy()
     442        else:
     443            workscan = self
     444        # Select a row
     445        sel=selector()
     446        sel.set_scans([workscan.getscan(row)])
     447        sel.set_cycles([workscan.getcycle(row)])
     448        sel.set_beams([workscan.getbeam(row)])
     449        sel.set_ifs([workscan.getif(row)])
     450        sel.set_polarisations([workscan.getpol(row)])
     451        sel.set_name(workscan._getsourcename(row))
     452        workscan.set_selection(sel)
     453        if not workscan.nrow() == 1:
     454            msg = "Cloud not identify single row. %d rows selected."%(workscan.nrow())
     455            raise RuntimeError(msg)
     456        del sel
     457        if insitu:
     458            self._assign(workscan)
     459        else:
     460            return workscan
     461
     462    #def stats(self, stat='stddev', mask=None):
     463    def stats(self, stat='stddev', mask=None, form='3.3f'):
    370464        """
    371465        Determine the specified statistic of the current beam/if/pol
     
    373467        channels should be excluded.
    374468        Parameters:
    375             stat:    'min', 'max', 'sumsq', 'sum', 'mean'
    376                      'var', 'stddev', 'avdev', 'rms', 'median'
     469            stat:    'min', 'max', 'min_abc', 'max_abc', 'sumsq', 'sum',
     470                     'mean', 'var', 'stddev', 'avdev', 'rms', 'median'
    377471            mask:    an optional mask specifying where the statistic
    378472                     should be determined.
     473            form:    format string to print statistic values
    379474        Example:
    380475            scan.set_unit('channel')
     
    387482                             "number of channels. Please use setselection() "
    388483                             "to select individual IFs")
    389 
    390         statvals = self._math._stats(self, mask, stat)
    391         def cb(i):
    392             return statvals[i]
    393 
    394         return self._row_callback(cb, stat)
     484        rtnabc = False
     485        if stat.lower().endswith('_abc'): rtnabc = True
     486        getchan = False
     487        if stat.lower().startswith('min') or stat.lower().startswith('max'):
     488            chan = self._math._minmaxchan(self, mask, stat)
     489            getchan = True
     490            statvals = []
     491        if not rtnabc: statvals = self._math._stats(self, mask, stat)
     492
     493        #def cb(i):
     494        #    return statvals[i]
     495
     496        #return self._row_callback(cb, stat)
     497
     498        label=stat
     499        #callback=cb
     500        out = ""
     501        #outvec = []
     502        sep = '-'*50
     503        for i in range(self.nrow()):
     504            refstr = ''
     505            statunit= ''
     506            if getchan:
     507                qx, qy = self.chan2data(rowno=i, chan=chan[i])
     508                if rtnabc:
     509                    statvals.append(qx['value'])
     510                    refstr = ('(value: %'+form) % (qy['value'])+' ['+qy['unit']+'])'
     511                    statunit= '['+qx['unit']+']'
     512                else:
     513                    refstr = ('(@ %'+form) % (qx['value'])+' ['+qx['unit']+'])'
     514
     515            tm = self._gettime(i)
     516            src = self._getsourcename(i)
     517            out += 'Scan[%d] (%s) ' % (self.getscan(i), src)
     518            out += 'Time[%s]:\n' % (tm)
     519            if self.nbeam(-1) > 1:
     520                out +=  ' Beam[%d] ' % (self.getbeam(i))
     521            if self.nif(-1) > 1: out +=  ' IF[%d] ' % (self.getif(i))
     522            if self.npol(-1) > 1: out +=  ' Pol[%d] ' % (self.getpol(i))
     523            #outvec.append(callback(i))
     524            #out += ('= %'+form) % (outvec[i]) +'   '+refstr+'\n'
     525            out += ('= %'+form) % (statvals[i]) +'   '+refstr+'\n'
     526            out +=  sep+"\n"
     527
     528        if rcParams['verbose']:
     529            import os
     530            if os.environ.has_key( 'USER' ):
     531                usr=os.environ['USER']
     532            else:
     533                import commands
     534                usr=commands.getoutput( 'whoami' )
     535            tmpfile='/tmp/tmp_'+usr+'_casapy_asap_scantable_stats'
     536            f=open(tmpfile,'w')
     537            print >> f, sep
     538            print >> f, ' %s %s' % (label, statunit)
     539            print >> f, sep
     540            print >> f, out
     541            f.close()
     542            f=open(tmpfile,'r')
     543            x=f.readlines()
     544            f.close()
     545            blanc=''
     546            asaplog.push(blanc.join(x), False)
     547            #for xx in x:
     548            #    asaplog.push( xx, False )
     549            print_log()
     550        return statvals
     551
     552    def chan2data(self, rowno=0, chan=0):
     553        """
     554        Returns channel/frequency/velocity and spectral value
     555        at an arbitrary row and channel in the scantable.
     556        Parameters:
     557            rowno:   a row number in the scantable. Default is the
     558                     first row, i.e. rowno=0
     559            chan:    a channel in the scantable. Default is the first
     560                     channel, i.e. pos=0
     561        """
     562        if isinstance(rowno, int) and isinstance(chan, int):
     563            qx = {'unit': self.get_unit(),
     564                  'value': self._getabcissa(rowno)[chan]}
     565            qy = {'unit': self.get_fluxunit(),
     566                  'value': self._getspectrum(rowno)[chan]}
     567            return qx, qy
    395568
    396569    def stddev(self, mask=None):
     
    462635            out +=  sep+'\n'
    463636        if rcParams['verbose']:
    464             print sep
    465             print " %s" % (label)
    466             print sep
    467             print out
     637            asaplog.push(sep)
     638            asaplog.push(" %s" % (label))
     639            asaplog.push(sep)
     640            asaplog.push(out)
     641            print_log()
    468642        return outvec
    469643
     
    474648            return [callback(i) for i in range(self.nrow())]
    475649        else:
    476             if 0 <= row < self.nrow():
     650            if  0 <= row < self.nrow():
    477651                return callback(row)
    478652
     
    604778        self._setInstrument(instr)
    605779        self._add_history("set_instument", vars())
     780        print_log()
    606781
    607782    @print_log_dec
     
    614789        self._setfeedtype(feedtype)
    615790        self._add_history("set_feedtype", vars())
     791        print_log()
    616792
    617793    @print_log_dec
     
    627803        self._setcoordinfo(inf)
    628804        self._add_history("set_doppler", vars())
     805        print_log()
    629806
    630807    @print_log_dec
     
    634811        Parameters:
    635812            frame:   an optional frame type, default 'LSRK'. Valid frames are:
    636                      'REST', 'TOPO', 'LSRD', 'LSRK', 'BARY',
     813                     'TOPO', 'LSRD', 'LSRK', 'BARY',
    637814                     'GEO', 'GALACTO', 'LGROUP', 'CMB'
    638815        Examples:
     
    641818        frame = frame or rcParams['scantable.freqframe']
    642819        varlist = vars()
    643         valid = ['REST', 'TOPO', 'LSRD', 'LSRK', 'BARY', \
     820        # "REST" is not implemented in casacore
     821        #valid = ['REST', 'TOPO', 'LSRD', 'LSRK', 'BARY', \
     822        #           'GEO', 'GALACTO', 'LGROUP', 'CMB']
     823        valid = ['TOPO', 'LSRD', 'LSRK', 'BARY', \
    644824                   'GEO', 'GALACTO', 'LGROUP', 'CMB']
    645825
     
    652832            msg  = "Please specify a valid freq type. Valid types are:\n", valid
    653833            if rcParams['verbose']:
    654                 print msg
     834                #print msg
     835                asaplog.push( msg )
     836                print_log( 'ERROR' )
    655837            else:
    656838                raise TypeError(msg)
     839        print_log()
    657840
    658841    def set_dirframe(self, frame=""):
     
    670853        except RuntimeError, msg:
    671854            if rcParams['verbose']:
    672                 print msg
     855                #print msg
     856                print_log()
     857                asaplog.push( str(msg) )
     858                print_log( 'ERROR' )
    673859            else:
    674860                raise
     
    698884        abc = self._getabcissa(rowno)
    699885        lbl = self._getabcissalabel(rowno)
     886        print_log()
    700887        return abc, lbl
    701888
    702     def flag(self, mask=None):
     889    def flag(self, mask=None, unflag=False):
    703890        """
    704891        Flag the selected data using an optional channel mask.
     
    706893            mask:   an optional channel mask, created with create_mask. Default
    707894                    (no mask) is all channels.
     895            unflag:    if True, unflag the data
    708896        """
    709897        varlist = vars()
    710898        mask = mask or []
    711899        try:
    712             self._flag(mask)
     900            self._flag(mask, unflag)
    713901        except RuntimeError, msg:
    714902            if rcParams['verbose']:
    715                 print msg
     903                #print msg
     904                print_log()
     905                asaplog.push( str(msg) )
     906                print_log( 'ERROR' )
    716907                return
    717908            else: raise
    718909        self._add_history("flag", varlist)
    719910
     911    def flag_row(self, rows=[], unflag=False):
     912        """
     913        Flag the selected data in row-based manner.
     914        Parameters:
     915            rows:   list of row numbers to be flagged. Default is no row (must be explicitly specified to execute row-based flagging).
     916            unflag: if True, unflag the data.
     917        """
     918        varlist = vars()
     919        try:
     920            self._flag_row(rows, unflag)
     921        except RuntimeError, msg:
     922            if rcParams['verbose']:
     923                print_log()
     924                asaplog.push( str(msg) )
     925                print_log('ERROR')
     926                return
     927            else: raise
     928        self._add_history("flag_row", varlist)
     929
     930    def clip(self, uthres=None, dthres=None, clipoutside=True, unflag=False):
     931        """
     932        Flag the selected data outside a specified range (in channel-base)
     933        Parameters:
     934            uthres:      upper threshold.
     935            dthres:      lower threshold
     936            clipoutside: True for flagging data outside the range [dthres:uthres].
     937                         False for glagging data inside the range.
     938            unflag     : if True, unflag the data.
     939        """
     940        varlist = vars()
     941        try:
     942            self._clip(uthres, dthres, clipoutside, unflag)
     943        except RuntimeError, msg:
     944            if rcParams['verbose']:
     945                print_log()
     946                asaplog.push(str(msg))
     947                print_log('ERROR')
     948                return
     949            else: raise
     950        self._add_history("clip", varlist)
     951
    720952    @print_log_dec
    721953    def lag_flag(self, start, end, unit="MHz", insitu=None):
     954    #def lag_flag(self, frequency, width=0.0, unit="GHz", insitu=None):
    722955        """
    723956        Flag the data in 'lag' space by providing a frequency to remove.
     
    748981        except RuntimeError, msg:
    749982            if rcParams['verbose']:
    750                 print msg
     983                #print msg
     984                print_log()
     985                asaplog.push( str(msg) )
     986                print_log( 'ERROR' )
    751987                return
    752988            else: raise
    753989        s._add_history("lag_flag", varlist)
     990        print_log()
    754991        if insitu:
    755992            self._assign(s)
     
    8191056            if kwargs.get('invert'):
    8201057                msk = mask_not(msk)
     1058        print_log()
    8211059        return msk
    8221060
    823     def get_restfreqs(self):
     1061    def get_masklist(self, mask=None, row=0):
     1062        """
     1063        Compute and return a list of mask windows, [min, max].
     1064        Parameters:
     1065            mask:       channel mask, created with create_mask.
     1066            row:        calcutate the masklist using the specified row
     1067                        for unit conversions, default is row=0
     1068                        only necessary if frequency varies over rows.
     1069        Returns:
     1070            [min, max], [min2, max2], ...
     1071                Pairs of start/end points (inclusive)specifying
     1072                the masked regions
     1073        """
     1074        if not (isinstance(mask,list) or isinstance(mask, tuple)):
     1075            raise TypeError("The mask should be list or tuple.")
     1076        if len(mask) < 2:
     1077            raise TypeError("The mask elements should be > 1")
     1078        if self.nchan() != len(mask):
     1079            msg = "Number of channels in scantable != number of mask elements"
     1080            raise TypeError(msg)
     1081        data = self._getabcissa(row)
     1082        u = self._getcoordinfo()[0]
     1083        if rcParams['verbose']:
     1084            if u == "": u = "channel"
     1085            msg = "The current mask window unit is %s" % u
     1086            i = self._check_ifs()
     1087            if not i:
     1088                msg += "\nThis mask is only valid for IF=%d" % (self.getif(i))
     1089            asaplog.push(msg)
     1090        masklist=[]
     1091        ist, ien = None, None
     1092        ist, ien=self.get_mask_indices(mask)
     1093        if ist is not None and ien is not None:
     1094            for i in xrange(len(ist)):
     1095                range=[data[ist[i]],data[ien[i]]]
     1096                range.sort()
     1097                masklist.append([range[0],range[1]])
     1098        return masklist
     1099
     1100    def get_mask_indices(self, mask=None):
     1101        """
     1102        Compute and Return lists of mask start indices and mask end indices.
     1103         Parameters:
     1104            mask:       channel mask, created with create_mask.
     1105        Returns:
     1106            List of mask start indices and that of mask end indices,
     1107            i.e., [istart1,istart2,....], [iend1,iend2,....].
     1108        """
     1109        if not (isinstance(mask,list) or isinstance(mask, tuple)):
     1110            raise TypeError("The mask should be list or tuple.")
     1111        if len(mask) < 2:
     1112            raise TypeError("The mask elements should be > 1")
     1113        istart=[]
     1114        iend=[]
     1115        if mask[0]: istart.append(0)
     1116        for i in range(len(mask)-1):
     1117            if not mask[i] and mask[i+1]:
     1118                istart.append(i+1)
     1119            elif mask[i] and not mask[i+1]:
     1120                iend.append(i)
     1121        if mask[len(mask)-1]: iend.append(len(mask)-1)
     1122        if len(istart) != len(iend):
     1123            raise RuntimeError("Numbers of mask start != mask end.")
     1124        for i in range(len(istart)):
     1125            if istart[i] > iend[i]:
     1126                raise RuntimeError("Mask start index > mask end index")
     1127                break
     1128        return istart,iend
     1129
     1130#    def get_restfreqs(self):
     1131#        """
     1132#        Get the restfrequency(s) stored in this scantable.
     1133#        The return value(s) are always of unit 'Hz'
     1134#        Parameters:
     1135#            none
     1136#        Returns:
     1137#            a list of doubles
     1138#        """
     1139#        return list(self._getrestfreqs())
     1140
     1141    def get_restfreqs(self, ids=None):
    8241142        """
    8251143        Get the restfrequency(s) stored in this scantable.
    8261144        The return value(s) are always of unit 'Hz'
    8271145        Parameters:
    828             none
     1146            ids: (optional) a list of MOLECULE_ID for that restfrequency(s) to
     1147                 be retrieved
    8291148        Returns:
    830             a list of doubles
    831         """
    832         return list(self._getrestfreqs())
    833 
     1149            dictionary containing ids and a list of doubles for each id
     1150        """
     1151        if ids is None:
     1152            rfreqs={}
     1153            idlist = self.getmolnos()
     1154            for i in idlist:
     1155                rfreqs[i]=list(self._getrestfreqs(i))
     1156            return rfreqs
     1157        else:
     1158            if type(ids)==list or type(ids)==tuple:
     1159                rfreqs={}
     1160                for i in ids:
     1161                    rfreqs[i]=list(self._getrestfreqs(i))
     1162                return rfreqs
     1163            else:
     1164                return list(self._getrestfreqs(ids))
     1165            #return list(self._getrestfreqs(ids))
    8341166
    8351167    def set_restfreqs(self, freqs=None, unit='Hz'):
    8361168        """
     1169        ********NEED TO BE UPDATED begin************
    8371170        Set or replace the restfrequency specified and
    8381171        If the 'freqs' argument holds a scalar,
     
    8461179        E.g. 'freqs=[1e9, 2e9]'  would mean IF 0 gets restfreq 1e9 and
    8471180        IF 1 gets restfreq 2e9.
     1181        ********NEED TO BE UPDATED end************
    8481182        You can also specify the frequencies via a linecatalog.
    8491183
     
    8531187
    8541188        Example:
    855             # set the given restfrequency for the whole table
     1189            # set the given restfrequency for the all currently selected IFs
    8561190            scan.set_restfreqs(freqs=1.4e9)
    857             # If thee number of IFs in the data is >= 2 IF0 gets the first
    858             # value IF1 the second...
    859             scan.set_restfreqs(freqs=[1.4e9, 1.67e9])
     1191            # set multiple restfrequencies to all the selected data
     1192            scan.set_restfreqs(freqs=[1.4e9, 1.41e9, 1.42e9])
     1193            # If the number of IFs in the data is >= 2 the IF0 gets the first
     1194            # value IF1 the second... NOTE that freqs needs to be
     1195            # specified in list of list (e.g. [[],[],...] ).
     1196            scan.set_restfreqs(freqs=[[1.4e9],[1.67e9]])
    8601197            #set the given restfrequency for the whole table (by name)
    8611198            scan.set_restfreqs(freqs="OH1667")
     
    8771214        # simple  value
    8781215        if isinstance(freqs, int) or isinstance(freqs, float):
    879             self._setrestfreqs(freqs, "",unit)
     1216            # TT mod
     1217            #self._setrestfreqs(freqs, "",unit)
     1218            self._setrestfreqs([freqs], [""],unit)
    8801219        # list of values
    8811220        elif isinstance(freqs, list) or isinstance(freqs, tuple):
    8821221            # list values are scalars
    8831222            if isinstance(freqs[-1], int) or isinstance(freqs[-1], float):
     1223                self._setrestfreqs(freqs, [""], unit)
     1224            # list values are tuples, (value, name)
     1225            elif isinstance(freqs[-1], dict):
     1226                #sel = selector()
     1227                #savesel = self._getselection()
     1228                #iflist = self.getifnos()
     1229                #for i in xrange(len(freqs)):
     1230                #    sel.set_ifs(iflist[i])
     1231                #    self._setselection(sel)
     1232                #    self._setrestfreqs(freqs[i], "",unit)
     1233                #self._setselection(savesel)
     1234                self._setrestfreqs(freqs["value"],
     1235                                   freqs["name"], unit)
     1236            elif isinstance(freqs[-1], list) or isinstance(freqs[-1], tuple):
    8841237                sel = selector()
    8851238                savesel = self._getselection()
    8861239                iflist = self.getifnos()
     1240                if len(freqs)>len(iflist):
     1241                    raise ValueError("number of elements in list of list exeeds the current IF selections")
    8871242                for i in xrange(len(freqs)):
    8881243                    sel.set_ifs(iflist[i])
    8891244                    self._setselection(sel)
    890                     self._setrestfreqs(freqs[i], "",unit)
    891                 self._setselection(savesel)
    892             # list values are tuples, (value, name)
    893             elif isinstance(freqs[-1], dict):
    894                 sel = selector()
    895                 savesel = self._getselection()
    896                 iflist = self.getifnos()
    897                 for i in xrange(len(freqs)):
    898                     sel.set_ifs(iflist[i])
    899                     self._setselection(sel)
    900                     self._setrestfreqs(freqs[i]["value"],
    901                                        freqs[i]["name"], "MHz")
     1245                    self._setrestfreqs(freqs[i], [""], unit)
    9021246                self._setselection(savesel)
    9031247        # freqs are to be taken from a linecatalog
     
    9051249            sel = selector()
    9061250            savesel = self._getselection()
    907             iflist = self.getifnos()
    9081251            for i in xrange(freqs.nrow()):
    9091252                sel.set_ifs(iflist[i])
     
    9631306                msg = "Illegal file name '%s'." % (filename)
    9641307                if rcParams['verbose']:
    965                     print msg
     1308                    #print msg
     1309                    asaplog.push( msg )
     1310                    print_log( 'ERROR' )
    9661311                else:
    9671312                    raise IOError(msg)
     
    10201365        except RuntimeError, msg:
    10211366            if rcParams['verbose']:
    1022                 print msg
     1367                #print msg
     1368                print_log()
     1369                asaplog.push( str(msg) )
     1370                print_log( 'ERROR' )
    10231371                return
    10241372            else: raise
    10251373        s._add_history("average_time", varlist)
     1374        print_log()
    10261375        return s
    10271376
     
    10511400        s = scantable(self._math._convertflux(self, d, eta, jyperk))
    10521401        s._add_history("convert_flux", varlist)
     1402        print_log()
    10531403        if insitu: self._assign(s)
    10541404        else: return s
     
    11031453        s = scantable(self._math._gainel(self, poly, filename, method))
    11041454        s._add_history("gain_el", varlist)
     1455        print_log()
    11051456        if insitu:
    11061457            self._assign(s)
     
    11301481        s = scantable(self._math._freq_align(self, reftime, method))
    11311482        s._add_history("freq_align", varlist)
     1483        print_log()
    11321484        if insitu: self._assign(s)
    11331485        else: return s
     
    11581510        s = scantable(self._math._opacity(self, tau))
    11591511        s._add_history("opacity", varlist)
     1512        print_log()
    11601513        if insitu: self._assign(s)
    11611514        else: return s
     
    11761529        s = scantable(self._math._bin(self, width))
    11771530        s._add_history("bin", varlist)
     1531        print_log()
    11781532        if insitu:
    11791533            self._assign(s)
     
    12001554        s = scantable(self._math._resample(self, method, width))
    12011555        s._add_history("resample", varlist)
     1556        print_log()
    12021557        if insitu: self._assign(s)
    12031558        else: return s
     
    12181573        s = scantable(self._math._averagepol(self, mask, weight.upper()))
    12191574        s._add_history("average_pol", varlist)
     1575        print_log()
    12201576        return s
    12211577
     
    12351591        s = scantable(self._math._averagebeams(self, mask, weight.upper()))
    12361592        s._add_history("average_beam", varlist)
     1593        print_log()
    12371594        return s
    12381595
     
    12631620        except RuntimeError, msg:
    12641621            if rcParams['verbose']:
    1265                 print msg
     1622                #print msg
     1623                print_log()
     1624                asaplog.push( str(msg) )
     1625                print_log( 'ERROR' )
    12661626                return
    12671627            else:
    12681628                raise
    12691629        s._add_history("convert_pol", varlist)
     1630        print_log()
    12701631        return s
    12711632
    12721633    @print_log_dec
    1273     def smooth(self, kernel="hanning", width=5.0, order=2, insitu=None):
     1634    def smooth(self, kernel="hanning", width=5.0, order=2, plot=False, insitu=None):
    12741635        """
    12751636        Smooth the spectrum by the specified kernel (conserving flux).
     
    12861647                        specify the order of the polnomial. Ignored by all other
    12871648                        kernels.
     1649            plot:       plot the original and the smoothed spectra.
     1650                        In this each indivual fit has to be approved, by
     1651                        typing 'y' or 'n'
    12881652            insitu:     if False a new scantable is returned.
    12891653                        Otherwise, the scaling is done in-situ
     
    12951659        self._math._setinsitu(insitu)
    12961660        varlist = vars()
     1661
     1662        if plot: orgscan = self.copy()
     1663
    12971664        s = scantable(self._math._smooth(self, kernel.lower(), width, order))
    12981665        s._add_history("smooth", varlist)
     1666
     1667        if plot:
     1668            if rcParams['plotter.gui']:
     1669                from asap.asaplotgui import asaplotgui as asaplot
     1670            else:
     1671                from asap.asaplot import asaplot
     1672            self._p=asaplot()
     1673            self._p.set_panels()
     1674            ylab=s._get_ordinate_label()
     1675            #self._p.palette(0,["#777777","red"])
     1676            for r in xrange(s.nrow()):
     1677                xsm=s._getabcissa(r)
     1678                ysm=s._getspectrum(r)
     1679                xorg=orgscan._getabcissa(r)
     1680                yorg=orgscan._getspectrum(r)
     1681                self._p.clear()
     1682                self._p.hold()
     1683                self._p.set_axes('ylabel',ylab)
     1684                self._p.set_axes('xlabel',s._getabcissalabel(r))
     1685                self._p.set_axes('title',s._getsourcename(r))
     1686                self._p.set_line(label='Original',color="#777777")
     1687                self._p.plot(xorg,yorg)
     1688                self._p.set_line(label='Smoothed',color="red")
     1689                self._p.plot(xsm,ysm)
     1690                ### Ugly part for legend
     1691                for i in [0,1]:
     1692                    self._p.subplots[0]['lines'].append([self._p.subplots[0]['axes'].lines[i]])
     1693                self._p.release()
     1694                ### Ugly part for legend
     1695                self._p.subplots[0]['lines']=[]
     1696                res = raw_input("Accept smoothing ([y]/n): ")
     1697                if res.upper() == 'N':
     1698                    s._setspectrum(yorg, r)
     1699            self._p.unmap()
     1700            self._p = None
     1701            del orgscan
     1702
     1703        print_log()
    12991704        if insitu: self._assign(s)
    13001705        else: return s
     
    13211726        """
    13221727        if insitu is None: insitu = rcParams['insitu']
     1728        if not insitu:
     1729            workscan = self.copy()
     1730        else:
     1731            workscan = self
    13231732        varlist = vars()
    13241733        if mask is None:
    13251734            mask = [True for i in xrange(self.nchan(-1))]
     1735
    13261736        from asap.asapfitter import fitter
    13271737        try:
    13281738            f = fitter()
    1329             f.set_scan(self, mask)
    1330             #f.set_function(poly=order)
    13311739            if uselin:
    13321740                f.set_function(lpoly=order)
    13331741            else:
    13341742                f.set_function(poly=order)
    1335             s = f.auto_fit(insitu, plot=plot)
    1336             s._add_history("poly_baseline", varlist)
    1337             if insitu: self._assign(s)
    1338             else: return s
     1743
     1744            rows = range(workscan.nrow())
     1745            if len(rows) > 0:
     1746                self.blpars = []
     1747
     1748            for r in rows:
     1749                # take into account flagtra info (CAS-1434)
     1750                flagtra = workscan._getmask(r)
     1751                actualmask = mask[:]
     1752                if len(actualmask) == 0:
     1753                    actualmask = list(flagtra[:])
     1754                else:
     1755                    if len(actualmask) != len(flagtra):
     1756                        raise RuntimeError, "Mask and flagtra have different length"
     1757                    else:
     1758                        for i in range(0, len(actualmask)):
     1759                            actualmask[i] = actualmask[i] and flagtra[i]
     1760                f.set_scan(workscan, actualmask)
     1761                f.x = workscan._getabcissa(r)
     1762                f.y = workscan._getspectrum(r)
     1763                f.data = None
     1764                f.fit()
     1765                if plot:
     1766                    f.plot(residual=True)
     1767                    x = raw_input("Accept fit ( [y]/n ): ")
     1768                    if x.upper() == 'N':
     1769                        self.blpars.append(None)
     1770                        continue
     1771                workscan._setspectrum(f.fitter.getresidual(), r)
     1772                self.blpars.append(f.get_parameters())
     1773
     1774            if plot:
     1775                f._p.unmap()
     1776                f._p = None
     1777            workscan._add_history("poly_baseline", varlist)
     1778            print_log()
     1779            if insitu: self._assign(workscan)
     1780            else: return workscan
    13391781        except RuntimeError:
    13401782            msg = "The fit failed, possibly because it didn't converge."
    13411783            if rcParams['verbose']:
    1342                 print msg
     1784                #print msg
     1785                print_log()
     1786                asaplog.push( str(msg) )
     1787                print_log( 'ERROR' )
    13431788                return
    13441789            else:
    13451790                raise RuntimeError(msg)
     1791
    13461792
    13471793    def auto_poly_baseline(self, mask=[], edge=(0, 0), order=0,
     
    14271873
    14281874        rows = range(workscan.nrow())
     1875        # Save parameters of baseline fits & masklists as a class attribute.
     1876        # NOTICE: It does not reflect changes in scantable!
     1877        if len(rows) > 0:
     1878            self.blpars=[]
     1879            self.masklists=[]
    14291880        asaplog.push("Processing:")
    14301881        for r in rows:
     
    14411892                    curedge = edge[workscan.getif(r)]
    14421893
     1894            # take into account flagtra info (CAS-1434)
     1895            flagtra = workscan._getmask(r)
     1896            actualmask = mask[:]
     1897            if len(actualmask) == 0:
     1898                actualmask = list(flagtra[:])
     1899            else:
     1900                if len(actualmask) != len(flagtra):
     1901                    raise RuntimeError, "Mask and flagtra have different length"
     1902                else:
     1903                    for i in range(0, len(actualmask)):
     1904                        actualmask[i] = actualmask[i] and flagtra[i]
     1905
    14431906            # setup line finder
    1444             fl.find_lines(r, mask, curedge)
    1445             f.set_data(workscan._getabcissa(r),  workscan._getspectrum(r),
    1446                         mask_and(workscan._getmask(r), fl.get_mask()))
     1907            fl.find_lines(r, actualmask, curedge)
     1908            outmask=fl.get_mask()
     1909            f.set_scan(workscan, fl.get_mask())
     1910            f.x = workscan._getabcissa(r)
     1911            f.y = workscan._getspectrum(r)
     1912            f.data = None
    14471913            f.fit()
    1448             x = f.get_parameters()
     1914
     1915            # Show mask list
     1916            masklist=workscan.get_masklist(fl.get_mask(),row=r)
     1917            msg = "mask range: "+str(masklist)
     1918            asaplog.push(msg, False)
     1919
    14491920            if plot:
    14501921                f.plot(residual=True)
    14511922                x = raw_input("Accept fit ( [y]/n ): ")
    14521923                if x.upper() == 'N':
     1924                    self.blpars.append(None)
     1925                    self.masklists.append(None)
    14531926                    continue
     1927
    14541928            workscan._setspectrum(f.fitter.getresidual(), r)
     1929            self.blpars.append(f.get_parameters())
     1930            self.masklists.append(masklist)
    14551931        if plot:
    14561932            f._p.unmap()
     
    14761952        self._math._rotate_linpolphase(self, angle)
    14771953        self._add_history("rotate_linpolphase", varlist)
     1954        print_log()
    14781955        return
    14791956
     
    14921969        self._math._rotate_xyphase(self, angle)
    14931970        self._add_history("rotate_xyphase", varlist)
     1971        print_log()
    14941972        return
    14951973
     
    15031981        self._math._swap_linears(self)
    15041982        self._add_history("swap_linears", varlist)
     1983        print_log()
    15051984        return
    15061985
     
    15131992        self._math._invert_phase(self)
    15141993        self._add_history("invert_phase", varlist)
     1994        print_log()
    15151995        return
    15161996
     
    15302010        s = scantable(self._math._unaryop(self, offset, "ADD", False))
    15312011        s._add_history("add", varlist)
     2012        print_log()
    15322013        if insitu:
    15332014            self._assign(s)
     
    15402021        Return a scan where all spectra are scaled by the give 'factor'
    15412022        Parameters:
    1542             factor:      the scaling factor
     2023            factor:      the scaling factor (float or 1D float list)
    15432024            insitu:      if False a new scantable is returned.
    15442025                         Otherwise, the scaling is done in-situ
     
    15502031        self._math._setinsitu(insitu)
    15512032        varlist = vars()
    1552         s = scantable(self._math._unaryop(self, factor, "MUL", tsys))
     2033        s = None
     2034        import numpy
     2035        if isinstance(factor, list) or isinstance(factor, numpy.ndarray):
     2036            if isinstance(factor[0], list) or isinstance(factor[0], numpy.ndarray):
     2037                from asapmath import _array2dOp
     2038                s = _array2dOp( self.copy(), factor, "MUL", tsys )
     2039            else:
     2040                s = scantable( self._math._arrayop( self.copy(), factor, "MUL", tsys ) )
     2041        else:
     2042            s = scantable(self._math._unaryop(self.copy(), factor, "MUL", tsys))
    15532043        s._add_history("scale", varlist)
     2044        print_log()
    15542045        if insitu:
    15552046            self._assign(s)
     
    15942085
    15952086    @print_log_dec
    1596     def auto_quotient(self, preserve=True, mode='paired'):
     2087    def auto_quotient(self, preserve=True, mode='paired', verify=False):
    15972088        """
    15982089        This function allows to build quotients automatically.
    1599         It assumes the observation to have the same numer of
     2090        It assumes the observation to have the same number of
    16002091        "ons" and "offs"
    16012092        Parameters:
     
    16342125            s = scantable(self._math._auto_quotient(self, mode, preserve))
    16352126        s._add_history("auto_quotient", varlist)
     2127        print_log()
    16362128        return s
    16372129
     
    16562148        q = quotient(on, off, preserve)
    16572149        q._add_history("mx_quotient", varlist)
     2150        print_log()
    16582151        return q
    16592152
     
    16742167        s = scantable(self._math._freqswitch(self))
    16752168        s._add_history("freq_switch", varlist)
     2169        print_log()
    16762170        if insitu: self._assign(s)
    16772171        else: return s
     
    16882182        self._recalcazel()
    16892183        self._add_history("recalc_azel", varlist)
     2184        print_log()
    16902185        return
    16912186
     
    17652260        fit = asapfit(self._getfit(row))
    17662261        if rcParams['verbose']:
    1767             print fit
     2262            #print fit
     2263            asaplog.push( '%s' %(fit) )
     2264            print_log()
    17682265            return
    17692266        else:
     
    18622359        return (sum(nchans)/len(nchans) == nchans[0])
    18632360
    1864     def _fill(self, names, unit, average):
     2361    def _fill(self, names, unit, average, getpt, antenna):
    18652362        import os
    18662363        from asap._asap import stfiller
     
    18742371                if rcParams['verbose']:
    18752372                    asaplog.push(msg)
    1876                     print asaplog.pop().strip()
     2373                    #print asaplog.pop().strip()
     2374                    print_log( 'ERROR' )
    18772375                    return
    18782376                raise IOError(msg)
     
    18892387            asaplog.push(msg, False)
    18902388            print_log()
    1891             r._open(name, -1, -1)
     2389            r._open(name, antenna, -1, -1, getpt)
    18922390            r._read()
    18932391            if average:
     
    19012399        if unit is not None:
    19022400            self.set_fluxunit(unit)
    1903         self.set_freqframe(rcParams['scantable.freqframe'])
     2401        #self.set_freqframe(rcParams['scantable.freqframe'])
    19042402
    19052403    def __getitem__(self, key):
  • trunk/python/selector.py

    r1596 r1819  
    160160        """
    161161        self._setorder(order)
     162
     163    def set_rows(self, rows=[]):
     164        """
     165        Set a sequence of row numbers (0-based). Power users Only!
     166        NOTICE row numbers can be changed easily by sorting,
     167        prior selection, etc.
     168        Parameters:
     169            rows:    a list of integers. Default [] is to unset the selection.
     170        """
     171        vec = _to_list(rows, int)
     172        if isinstance(vec,list):
     173            self._setrows(vec)
     174        else:
     175            raise TypeError('Unknown row number type. Use lists of integers.')
     176
     177    def set_types(self, types=[]):
     178        """
     179        Set a sequence of source types.
     180        Parameters:
     181            types:    a list of integers. Default [] is to unset the selection.
     182        """
     183        vec = _to_list(types, int)
     184        if isinstance(vec,list):
     185            self._settypes(vec)
     186        else:
     187            raise TypeError('Unknown row number type. Use lists of integers.')
    162188
    163189    def get_scans(self):
     
    175201    def get_order(self):
    176202        return list(self._getorder())
     203    def get_types(self):
     204        return list(self._gettypes())
    177205    def get_query(self):
    178206        prefix = "SELECT FROM $1 WHERE "
  • trunk/src

  • trunk/src/MathUtils.cpp

    r1570 r1819  
    3838#include <casa/BasicSL/String.h>
    3939#include <scimath/Mathematics/MedianSlider.h>
     40#include <casa/Exceptions/Error.h>
    4041
    4142#include <scimath/Fitting/LinearFit.h>
     
    5354   String str(which);
    5455   str.upcase();
    55    if (str.contains(String("MIN"))) {
     56   if (str.matches(String("MIN"))) {
    5657      return min(data);
    57    } else if (str.contains(String("MAX"))) {
     58   } else if (str.matches(String("MAX"))) {
    5859      return max(data);
    59    } else if (str.contains(String("SUMSQ"))) {
     60   } else if (str.matches(String("SUMSQ"))) {
    6061      return sumsquares(data);
    61    } else if (str.contains(String("SUM"))) {
     62   } else if (str.matches(String("SUM"))) {
    6263      return sum(data);
    63    } else if (str.contains(String("MEAN"))) {
     64   } else if (str.matches(String("MEAN"))) {
    6465      return mean(data);
    65    } else if (str.contains(String("VAR"))) {
     66   } else if (str.matches(String("VAR"))) {
    6667      return variance(data);
    67    } else if (str.contains(String("STDDEV"))) {
     68      } else if (str.matches(String("STDDEV"))) {
    6869      return stddev(data);
    69    } else if (str.contains(String("AVDEV"))) {
     70   } else if (str.matches(String("AVDEV"))) {
    7071      return avdev(data);
    71    } else if (str.contains(String("RMS"))) {
     72   } else if (str.matches(String("RMS"))) {
    7273      uInt n = data.nelementsValid();
    7374      return sqrt(sumsquares(data)/n);
    74    } else if (str.contains(String("MED"))) {
     75   } else if (str.matches(String("MEDIAN"))) {
    7576      return median(data);
    76    }
     77   } else {
     78      String msg = str + " is not a valid type of statistics";
     79      throw(AipsError(msg));
     80   }
    7781   return 0.0;
    7882}
    7983
     84IPosition mathutil::minMaxPos(const String& which,
     85                           const MaskedArray<Float>& data)
     86{
     87   Float minVal, maxVal;
     88   IPosition minPos(data.ndim(), 0), maxPos(data.ndim(), 0);
     89   minMax(minVal, maxVal, minPos, maxPos, data);
     90   String str(which);
     91   str.upcase();
     92   if (str.contains(String("MIN"))) {
     93     return minPos;
     94   } else if (str.contains(String("MAX"))) {
     95     return maxPos;
     96   } else {
     97      String msg = str + " is not a valid type of statistics";
     98      throw(AipsError(msg));
     99   }
     100   //return 0.0;
     101}
    80102
    81103void mathutil::replaceMaskByZero(Vector<Float>& data, const Vector<Bool>& mask)
  • trunk/src/MathUtils.h

    r1570 r1819  
    3737#include <casa/Arrays/Vector.h>
    3838#include <casa/BasicSL/String.h>
     39#include <casa/Arrays/IPosition.h>
    3940
    4041namespace mathutil {
     
    7980                   float hwidth, int order);
    8081
    81 
    8282// Generate specified statistic
    8383float statistics(const casa::String& which,
     84                 const casa::MaskedArray<casa::Float>& data);
     85
     86// Return a position of min or max value
     87 casa::IPosition minMaxPos(const casa::String& which,
    8488                 const casa::MaskedArray<casa::Float>& data);
    8589
  • trunk/src/RowAccumulator.cpp

    r1569 r1819  
    152152  userMask_ = m;
    153153}
     154
     155// Added by TT  check the state of RowAccumulator
     156casa::Bool RowAccumulator::state() const
     157{
     158  return initialized_;
     159}
     160
  • trunk/src/RowAccumulator.h

    r1569 r1819  
    8585    */
    8686  void reset();
     87  /**
     88    * check the initialization state
     89    */
     90  casa::Bool state() const;
    8791
    8892private:
  • trunk/src/SConscript

  • trunk/src/STAsciiWriter.cpp

    r1552 r1819  
     1
    12//#---------------------------------------------------------------------------
    23//# STAsciiWriter.cc: ASAP class to write out single dish spectra as FITS images
     
    8889
    8990   String rootName(fileName);
    90    
     91
    9192  Block<String> cols(4);
    9293  cols[0] = String("SCANNO");
     
    132133    String wcs = stable.frequencies().print(rec.asuInt("FREQ_ID"), True);
    133134    addLine(of, "WCS", wcs);
    134     addLine(of, "Rest Freq.",
    135             stable.molecules().getRestFrequency(rec.asuInt("MOLECULE_ID") ));
     135    std::vector<double> restfreqs= stable.molecules().getRestFrequency(rec.asuInt("MOLECULE_ID"));
     136    int nf = restfreqs.size();
     137    //addLine(of, "Rest Freq.",
     138    //        stable.molecules().getRestFrequency(rec.asuInt("MOLECULE_ID") ));
     139    addLine(of, "Rest Freq.", restfreqs[0]);
     140    for ( unsigned int i=1; i<nf; ++i) {
     141      addLine(of, " ", restfreqs[i]);
     142    }
     143    ostringstream osflagrow;
     144    for ( unsigned int i=0; i<t.nrow(); ++i) {
     145      osflagrow << "Pol" << i << ":" << ((row.get(i).asuInt("FLAGROW") > 0) ? "True" : "False") << " ";
     146    }
     147    addLine(of, "Row_Flagged", String(osflagrow));
    136148    of << setfill('#') << setw(70) << "" << setfill(' ') << endl;
    137149
  • trunk/src/STFiller.cpp

    r1725 r1819  
    2525#include <tables/Tables/TableRow.h>
    2626
     27#include <measures/Measures/MDirection.h>
     28#include <measures/Measures/MeasConvert.h>
     29
    2730#include <atnf/PKSIO/PKSrecord.h>
    2831#include <atnf/PKSIO/PKSreader.h>
     
    3033 #include <casa/System/ProgressMeter.h>
    3134#endif
     35#include <casa/System/ProgressMeter.h>
     36#include <atnf/PKSIO/NROReader.h>
     37#include <casa/Logging/LogIO.h>
     38
     39#include <time.h>
     40
    3241
    3342#include "STDefs.h"
     
    4554  header_(0),
    4655  table_(0),
    47   refRx_(".*(e|w|_R)$")
     56  refRx_(".*(e|w|_R)$"),
     57  nreader_(0)
    4858{
    4959}
     
    5363  header_(0),
    5464  table_(stbl),
    55   refRx_(".*(e|w|_R)$")
     65  refRx_(".*(e|w|_R)$"),
     66  nreader_(0)
    5667{
    5768}
     
    6172  header_(0),
    6273  table_(0),
    63   refRx_(".*(e|w|_R)$")
    64 {
    65   open(filename, whichIF, whichBeam);
     74  refRx_(".*(e|w|_R)$"),
     75  nreader_(0)
     76{
     77  open(filename, "", whichIF, whichBeam);
    6678}
    6779
     
    7183}
    7284
    73 void STFiller::open( const std::string& filename, int whichIF, int whichBeam )
     85void STFiller::open( const std::string& filename, const std::string& antenna, int whichIF, int whichBeam, casa::Bool getPt )
    7486{
    7587  if (table_.null())  {
     
    93105  Vector<Bool> beams, ifs;
    94106  Vector<uInt> nchans,npols;
    95   if ( (reader_ = getPKSreader(inName, 0, 0, format, beams, ifs,
     107
     108  //
     109  // if isNRO_ is true, try NROReader
     110  //
     111  // 2008/11/11 Takeshi Nakazato
     112  isNRO_ = fileCheck() ;
     113  if ( isNRO_ ) {
     114    if ( (nreader_ = getNROReader( inName, format )) == 0 ) {
     115      throw(AipsError("Creation of NROReader failed")) ;
     116    }
     117    else {
     118      openNRO( whichIF, whichBeam ) ;
     119      return ;
     120    }
     121  }
     122  //
     123
     124  if ( (reader_ = getPKSreader(inName, antenna, 0, 0, format, beams, ifs,
    96125                              nchans, npols, haveXPol_,haveBase, haveSpectra
    97126                              )) == 0 )  {
     
    118147  header_->npol = max(npols);
    119148  header_->nbeam = nBeam_;
    120  
     149
    121150  Int status = reader_->getHeader(header_->observer, header_->project,
    122151                                  header_->antennaname, header_->antennaposition,
     
    197226  Vector<Int> start(nIF_, 1);
    198227  Vector<Int> end(nIF_, 0);
    199   reader_->select(beams, ifs, start, end, ref, True, haveXPol_[0]);
     228  reader_->select(beams, ifs, start, end, ref, True, haveXPol_[0], False, getPt);
    200229  table_->setHeader(*header_);
    201230  //For MS, add the location of POINTING of the input MS so one get
    202231  //pointing data from there, if necessary.
    203   //Also find nrow in MS 
     232  //Also find nrow in MS
    204233  nInDataRow = 0;
    205234  if (format == "MS2") {
    206     Path datapath(inName); 
     235    Path datapath(inName);
    207236    String ptTabPath = datapath.absoluteName();
    208237    Table inMS(ptTabPath);
     
    216245    }
    217246  }
     247  String freqFrame = header_->freqref;
     248  //translate frequency reference frame back to
     249  //MS style (as PKSMS2reader converts the original frame
     250  //in FITS standard style)
     251  if (freqFrame == "TOPOCENT") {
     252    freqFrame = "TOPO";
     253  } else if (freqFrame == "GEOCENER") {
     254    freqFrame = "GEO";
     255  } else if (freqFrame == "BARYCENT") {
     256    freqFrame = "BARY";
     257  } else if (freqFrame == "GALACTOC") {
     258    freqFrame = "GALACTO";
     259  } else if (freqFrame == "LOCALGRP") {
     260    freqFrame = "LGROUP";
     261  } else if (freqFrame == "CMBDIPOL") {
     262    freqFrame = "CMB";
     263  } else if (freqFrame == "SOURCE") {
     264    freqFrame = "REST";
     265  }
     266  // set both "FRAME" and "BASEFRAME"
     267  table_->frequencies().setFrame(freqFrame, false);
     268  table_->frequencies().setFrame(freqFrame,true);
    218269  //table_->focus().setParallactify(true);
    219270}
     
    222273{
    223274  delete reader_;reader_=0;
     275  delete nreader_;nreader_=0;
    224276  delete header_;header_=0;
    225277  table_ = 0;
     
    229281{
    230282  int status = 0;
     283
     284  //
     285  // for NRO data
     286  //
     287  // 2008/11/12 Takeshi Nakazato
     288  if ( isNRO_ ) {
     289    status = readNRO() ;
     290    return status ;
     291  }
     292  //
     293
     294/**
     295  Int    beamNo, IFno, refBeam, scanNo, cycleNo;
     296  Float  azimuth, elevation, focusAxi, focusRot, focusTan,
     297    humidity, parAngle, pressure, temperature, windAz, windSpeed;
     298  Double bandwidth, freqInc, interval, mjd, refFreq, srcVel;
     299  String          fieldName, srcName, tcalTime, obsType;
     300  Vector<Float>   calFctr, sigma, tcal, tsys;
     301  Matrix<Float>   baseLin, baseSub;
     302  Vector<Double>  direction(2), scanRate(2), srcDir(2), srcPM(2), restFreq(1);
     303  Matrix<Float>   spectra;
     304  Matrix<uChar>   flagtra;
     305  Complex         xCalFctr;
     306  Vector<Complex> xPol;
     307**/
    231308
    232309  Double min = 0.0;
     
    236313#endif
    237314  PKSrecord pksrec;
     315  pksrec.srcType=-1;
    238316  int n = 0;
     317  bool isGBTFITS = false ;
     318  if ((header_->antennaname.find( "GBT" ) != String::npos) && File(filename_).isRegular()) {
     319    FILE *fp = fopen( filename_.c_str(), "r" ) ;
     320    fseek( fp, 640, SEEK_SET ) ;
     321    char buf[81] ;
     322    fread( buf, 80, 1, fp ) ;
     323    buf[80] = '\0' ;
     324    if ( strstr( buf, "NRAO_GBT" ) != NULL ) {
     325      isGBTFITS = true ;
     326    }
     327    fclose( fp ) ;
     328  }
    239329  while ( status == 0 ) {
    240330    status = reader_->read(pksrec);
     
    288378    //*srcnCol = pksrec.srcName;//.before(rx2);
    289379    *srctCol = match;
     380    if ( pksrec.srcType != -1 ) {
     381      *srctCol = pksrec.srcType ;
     382    }
    290383    RecordFieldPtr<uInt> beamCol(rec, "BEAMNO");
    291384    *beamCol = pksrec.beamNo-beamOffset_-1;
     
    296389    RecordFieldPtr<uInt> ifCol(rec, "IFNO");
    297390    *ifCol = pksrec.IFno-ifOffset_- 1;
    298     uInt id;
    299     /// @todo this has to change when nchan isn't global anymore
    300     id = table_->frequencies().addEntry(Double(header_->nchan/2),
    301                                         pksrec.refFreq, pksrec.freqInc);
     391    uInt id = table_->frequencies().addEntry(Double(pksrec.spectra.nrow()/2),
     392                                             pksrec.refFreq, pksrec.freqInc);
    302393    RecordFieldPtr<uInt> mfreqidCol(rec, "FREQ_ID");
    303394    *mfreqidCol = id;
     395    //*ifCol = id;
    304396
    305397    id = table_->molecules().addEntry(pksrec.restFreq);
     
    317409
    318410    RecordFieldPtr<uInt> mfocusidCol(rec, "FOCUS_ID");
    319     id = table_->focus().addEntry(pksrec.parAngle, pksrec.focusAxi, 
     411    id = table_->focus().addEntry(pksrec.parAngle, pksrec.focusAxi,
    320412                                  pksrec.focusTan, pksrec.focusRot);
    321413    *mfocusidCol = id;
     
    335427    // into 2-4 rows in the scantable
    336428    Vector<Float> tsysvec(1);
    337     // Why is pksrec.spectra.ncolumn() == 3 for haveXPol_ == True
     429    // Why is spectra.ncolumn() == 3 for haveXPol_ == True
    338430    uInt npol = (pksrec.spectra.ncolumn()==1 ? 1: 2);
    339431    for ( uInt i=0; i< npol; ++i ) {
    340432      tsysvec = pksrec.tsys(i);
    341433      *tsysCol = tsysvec;
    342       *polnoCol = i;
     434      if (isGBTFITS)
     435        *polnoCol = pksrec.polNo ;
     436      else
     437        *polnoCol = i;
    343438
    344439      *specCol = pksrec.spectra.column(i);
     
    347442      row.put(table_->table().nrow()-1, rec);
    348443    }
     444
     445    RecordFieldPtr< uInt > flagrowCol(rec, "FLAGROW");
     446    *flagrowCol = pksrec.flagrow;
     447
    349448    if ( haveXPol_[0] ) {
    350449      // no tsys given for xpol, so emulate it
     
    381480}
    382481
     482/**
     483 * For NRO data
     484 *
     485 * 2008/11/11 Takeshi Nakazato
     486 **/
     487void STFiller::openNRO( int whichIF, int whichBeam )
     488{
     489  // open file
     490  // DEBUG
     491  time_t t0 ;
     492  time( &t0 ) ;
     493  tm *ttm = localtime( &t0 ) ;
     494  LogIO os( LogOrigin( "STFiller", "openNRO()", WHERE ) ) ;
     495//   cout << "STFiller::openNRO()  Start time = " << t0
     496//        << " ("
     497//        << ttm->tm_year + 1900 << "/" << ttm->tm_mon + 1 << "/" << ttm->tm_mday
     498//        << " "
     499//        << ttm->tm_hour << ":" << ttm->tm_min << ":" << ttm->tm_sec
     500//        << ")" << endl ;
     501  os << "Start time = " << t0
     502     << " ("
     503     << ttm->tm_year + 1900 << "/" << ttm->tm_mon + 1 << "/" << ttm->tm_mday
     504     << " "
     505     << ttm->tm_hour << ":" << ttm->tm_min << ":" << ttm->tm_sec
     506     << ")" << LogIO::POST ;
     507
     508  // fill STHeader
     509  header_ = new STHeader() ;
     510
     511  if ( nreader_->getHeaderInfo( header_->nchan,
     512                                header_->npol,
     513                                nIF_,
     514                                nBeam_,
     515                                header_->observer,
     516                                header_->project,
     517                                header_->obstype,
     518                                header_->antennaname,
     519                                header_->antennaposition,
     520                                header_->equinox,
     521                                header_->freqref,
     522                                header_->reffreq,
     523                                header_->bandwidth,
     524                                header_->utc,
     525                                header_->fluxunit,
     526                                header_->epoch,
     527                                header_->poltype ) ) {
     528//     cout << "STFiller::openNRO()  Failed to get header information." << endl ;
     529//     return ;
     530    throw( AipsError("Failed to get header information.") ) ;
     531  }
     532
     533  // set FRAME and BASEFRAME keyword of FREQUENCIES table
     534  if ( header_->freqref != "TOPO" ) {
     535    table_->frequencies().setFrame( header_->freqref, false ) ;
     536    table_->frequencies().setFrame( header_->freqref, true ) ;
     537  }
     538
     539  ifOffset_ = 0;
     540  vector<Bool> ifs = nreader_->getIFs() ;
     541  if ( whichIF >= 0 ) {
     542    if ( whichIF >= 0 && whichIF < nIF_ ) {
     543      for ( int i = 0 ; i < nIF_ ; i++ )
     544        ifs[i] = False ;
     545      ifs[whichIF] = True ;
     546      header_->nif = 1;
     547      nIF_ = 1;
     548      ifOffset_ = whichIF;
     549    } else {
     550      delete reader_;
     551      reader_ = 0;
     552      delete header_;
     553      header_ = 0;
     554      throw(AipsError("Illegal IF selection"));
     555    }
     556  }
     557
     558  beamOffset_ = 0;
     559  vector<Bool> beams = nreader_->getBeams() ;
     560  if (whichBeam>=0) {
     561    if (whichBeam>=0 && whichBeam<nBeam_) {
     562      for ( int i = 0 ; i < nBeam_ ; i++ )
     563        beams[i] = False ;
     564      beams[whichBeam] = True;
     565      header_->nbeam = 1;
     566      nBeam_ = 1;
     567      beamOffset_ = whichBeam;
     568    } else {
     569      delete reader_;
     570      reader_ = 0;
     571      delete header_;
     572      header_ = 0;
     573      throw(AipsError("Illegal Beam selection"));
     574    }
     575  }
     576
     577  header_->nbeam = nBeam_ ;
     578  header_->nif = nIF_ ;
     579
     580  // set header
     581  table_->setHeader( *header_ ) ;
     582
     583  // DEBUG
     584  time_t t1 ;
     585  time( &t1 ) ;
     586  ttm = localtime( &t1 ) ;
     587//   cout << "STFiller::openNRO()  End time = " << t1
     588//        << " ("
     589//        << ttm->tm_year + 1900 << "/" << ttm->tm_mon + 1 << "/" << ttm->tm_mday
     590//        << " "
     591//        << ttm->tm_hour << ":" << ttm->tm_min << ":" << ttm->tm_sec
     592//        << ")" << endl ;
     593//   cout << "STFiller::openNRO()  Elapsed time = " << t1 - t0 << " sec" << endl ;
     594  os << "End time = " << t1
     595     << " ("
     596     << ttm->tm_year + 1900 << "/" << ttm->tm_mon + 1 << "/" << ttm->tm_mday
     597     << " "
     598     << ttm->tm_hour << ":" << ttm->tm_min << ":" << ttm->tm_sec
     599     << ")" << endl ;
     600  os << "Elapsed time = " << t1 - t0 << " sec" << endl ;
     601  os.post() ;
     602  //
     603
     604  return ;
     605}
     606
     607int STFiller::readNRO()
     608{
     609  // DEBUG
     610  time_t t0 ;
     611  time( &t0 ) ;
     612  tm *ttm = localtime( &t0 ) ;
     613  LogIO os( LogOrigin( "STFiller", "readNRO()", WHERE ) ) ;
     614//   cout << "STFiller::readNRO()  Start time = " << t0
     615//        << " ("
     616//        << ttm->tm_year + 1900 << "/" << ttm->tm_mon + 1 << "/" << ttm->tm_mday
     617//        << " "
     618//        << ttm->tm_hour << ":" << ttm->tm_min << ":" << ttm->tm_sec
     619//        << ")" << endl ;
     620  os << "Start time = " << t0
     621     << " ("
     622     << ttm->tm_year + 1900 << "/" << ttm->tm_mon + 1 << "/" << ttm->tm_mday
     623     << " "
     624     << ttm->tm_hour << ":" << ttm->tm_min << ":" << ttm->tm_sec
     625     << ")" << LogIO::POST ;
     626  //
     627
     628  // fill row
     629  uInt id ;
     630  uInt imax = nreader_->getRowNum() ;
     631  vector< vector<double > > freqs ;
     632  uInt i = 0 ;
     633  int count = 0 ;
     634  uInt scanno ;
     635  uInt cycleno ;
     636  uInt beamno ;
     637  uInt polno ;
     638  vector<double> fqs ;
     639  Vector<Double> restfreq ;
     640  uInt refbeamno ;
     641  Double scantime ;
     642  Double interval ;
     643  String srcname ;
     644  String fieldname ;
     645  Array<Float> spectra ;
     646  Array<uChar> flagtra ;
     647  Array<Float> tsys ;
     648  Array<Double> direction ;
     649  Float azimuth ;
     650  Float elevation ;
     651  Float parangle ;
     652  Float opacity ;
     653  uInt tcalid ;
     654  Int fitid ;
     655  uInt focusid ;
     656  Float temperature ;
     657  Float pressure ;
     658  Float humidity ;
     659  Float windvel ;
     660  Float winddir ;
     661  Double srcvel ;
     662  Array<Double> propermotion ;
     663  Vector<Double> srcdir ;
     664  Array<Double> scanrate ;
     665  for ( i = 0 ; i < imax ; i++ ) {
     666    string scanType = nreader_->getScanType( i ) ;
     667    Int srcType = -1 ;
     668    if ( scanType.compare( 0, 2, "ON") == 0 ) {
     669      // os << "ON srcType: " << i << LogIO::POST ;
     670      srcType = 0 ;
     671    }
     672    else if ( scanType.compare( 0, 3, "OFF" ) == 0 ) {
     673      //os << "OFF srcType: " << i << LogIO::POST ;
     674      srcType = 1 ;
     675    }
     676    else if ( scanType.compare( 0, 4, "ZERO" ) == 0 ) {
     677      //os << "ZERO srcType: " << i << LogIO::POST ;
     678      srcType = 2 ;
     679    }
     680    else {
     681      //os << "Undefined srcType: " << i << LogIO::POST ;
     682      srcType = 3 ;
     683    }
     684
     685    // if srcType is 2 (ZERO scan), ignore scan
     686    if ( srcType != 2 && srcType != -1 && srcType != 3 ) {
     687      TableRow row( table_->table() ) ;
     688      TableRecord& rec = row.record();
     689
     690      if ( nreader_->getScanInfo( i,
     691                                  scanno,
     692                                  cycleno,
     693                                  beamno,
     694                                  polno,
     695                                  fqs,
     696                                  restfreq,
     697                                  refbeamno,
     698                                  scantime,
     699                                  interval,
     700                                  srcname,
     701                                  fieldname,
     702                                  spectra,
     703                                  flagtra,
     704                                  tsys,
     705                                  direction,
     706                                  azimuth,
     707                                  elevation,
     708                                  parangle,
     709                                  opacity,
     710                                  tcalid,
     711                                  fitid,
     712                                  focusid,
     713                                  temperature,
     714                                  pressure,
     715                                  humidity,
     716                                  windvel,
     717                                  winddir,
     718                                  srcvel,
     719                                  propermotion,
     720                                  srcdir,
     721                                  scanrate ) ) {
     722//         cerr << "STFiller::readNRO()  Failed to get scan information." << endl ;
     723//         return 1 ;
     724        throw( AipsError("Failed to get scan information.") ) ;
     725      }
     726
     727      RecordFieldPtr<uInt> scannoCol( rec, "SCANNO" ) ;
     728      *scannoCol = scanno ;
     729      RecordFieldPtr<uInt> cyclenoCol(rec, "CYCLENO") ;
     730      *cyclenoCol = cycleno ;
     731      RecordFieldPtr<uInt> beamCol(rec, "BEAMNO") ;
     732      *beamCol = beamno ;
     733      RecordFieldPtr<uInt> ifCol(rec, "IFNO") ;
     734      RecordFieldPtr< uInt > polnoCol(rec, "POLNO") ;
     735      *polnoCol = polno ;
     736      RecordFieldPtr<uInt> mfreqidCol(rec, "FREQ_ID") ;
     737      if ( freqs.size() == 0 ) {
     738        id = table_->frequencies().addEntry( Double( fqs[0] ),
     739                                             Double( fqs[1] ),
     740                                             Double( fqs[2] ) ) ;
     741        *mfreqidCol = id ;
     742        *ifCol = id ;
     743        freqs.push_back( fqs ) ;
     744      }
     745      else {
     746        int iadd = -1 ;
     747        for ( uInt iif = 0 ; iif < freqs.size() ; iif++ ) {
     748          //os << "freqs[" << iif << "][1] = " << freqs[iif][1] << LogIO::POST ;
     749          double fdiff = abs( freqs[iif][1] - fqs[1] ) / freqs[iif][1] ;
     750          //os << "fdiff = " << fdiff << LogIO::POST ;
     751          if ( fdiff < 1.0e-8 ) {
     752            iadd = iif ;
     753            break ;
     754          }
     755        }
     756        if ( iadd == -1 ) {
     757          id = table_->frequencies().addEntry( Double( fqs[0] ),
     758                                               Double( fqs[1] ),
     759                                               Double( fqs[2] ) ) ;
     760          *mfreqidCol = id ;
     761          *ifCol = id ;
     762          freqs.push_back( fqs ) ;
     763        }
     764        else {
     765          *mfreqidCol = iadd ;
     766          *ifCol = iadd ;
     767        }
     768      }
     769      RecordFieldPtr<uInt> molidCol(rec, "MOLECULE_ID") ;
     770      id = table_->molecules().addEntry( restfreq ) ;
     771      *molidCol = id ;
     772      RecordFieldPtr<Int> rbCol(rec, "REFBEAMNO") ;
     773      *rbCol = refbeamno ;
     774      RecordFieldPtr<Double> mjdCol( rec, "TIME" ) ;
     775      *mjdCol = scantime ;
     776      RecordFieldPtr<Double> intervalCol( rec, "INTERVAL" ) ;
     777      *intervalCol = interval ;
     778      RecordFieldPtr<String> srcnCol(rec, "SRCNAME") ;
     779      *srcnCol = srcname ;
     780      RecordFieldPtr<Int> srctCol(rec, "SRCTYPE") ;
     781      *srctCol = srcType ;
     782      RecordFieldPtr<String> fieldnCol(rec, "FIELDNAME");
     783      *fieldnCol = fieldname ;
     784      RecordFieldPtr< Array<Float> > specCol(rec, "SPECTRA") ;
     785      *specCol = spectra ;
     786      RecordFieldPtr< Array<uChar> > flagCol(rec, "FLAGTRA") ;
     787      *flagCol = flagtra ;
     788      RecordFieldPtr< Array<Float> > tsysCol(rec, "TSYS") ;
     789      *tsysCol = tsys ;
     790      RecordFieldPtr< Array<Double> > dirCol(rec, "DIRECTION") ;
     791      *dirCol = direction ;
     792      RecordFieldPtr<Float> azCol(rec, "AZIMUTH") ;
     793      *azCol = azimuth ;
     794      RecordFieldPtr<Float> elCol(rec, "ELEVATION") ;
     795      *elCol = elevation ;
     796      RecordFieldPtr<Float> parCol(rec, "PARANGLE") ;
     797      *parCol = parangle ;
     798      RecordFieldPtr<Float> tauCol(rec, "OPACITY") ;
     799      *tauCol = opacity ;
     800      RecordFieldPtr<uInt> mcalidCol(rec, "TCAL_ID") ;
     801      *mcalidCol = tcalid ;
     802      RecordFieldPtr<Int> fitCol(rec, "FIT_ID") ;
     803      *fitCol = fitid ;
     804      RecordFieldPtr<uInt> mfocusidCol(rec, "FOCUS_ID") ;
     805      *mfocusidCol = focusid ;
     806      RecordFieldPtr<uInt> mweatheridCol(rec, "WEATHER_ID") ;
     807      id = table_->weather().addEntry( temperature,
     808                                       pressure,
     809                                       humidity,
     810                                       windvel,
     811                                       winddir ) ;
     812      *mweatheridCol = id ;
     813      RecordFieldPtr<Double> svelCol(rec, "SRCVELOCITY") ;
     814      *svelCol = srcvel ;
     815      RecordFieldPtr<Array<Double> > spmCol(rec, "SRCPROPERMOTION") ;
     816      *spmCol = propermotion ;
     817      RecordFieldPtr<Array<Double> > sdirCol(rec, "SRCDIRECTION") ;
     818      *sdirCol = srcdir ;
     819      RecordFieldPtr<Array<Double> > srateCol(rec, "SCANRATE");
     820      *srateCol = scanrate ;
     821
     822      table_->table().addRow() ;
     823      row.put(table_->table().nrow()-1, rec) ;
     824    }
     825    else {
     826      count++ ;
     827    }
     828    // DEBUG
     829    //int rownum = nreader_->getRowNum() ;
     830    //os << "Finished row " << i << "/" << rownum << LogIO::POST ;
     831    //
     832  }
     833
     834  // DEBUG
     835  time_t t1 ;
     836  time( &t1 ) ;
     837  ttm = localtime( &t1 ) ;
     838//   cout << "STFiller::readNRO()  Processed " << i << " rows" << endl ;
     839//   cout << "STFiller::readNRO()  Added " << i - count << " rows (ignored "
     840//        << count << " \"ZERO\" scans)" << endl ;
     841//   cout << "STFiller::readNRO()  End time = " << t1
     842//        << " ("
     843//        << ttm->tm_year + 1900 << "/" << ttm->tm_mon + 1 << "/" << ttm->tm_mday
     844//        << " "
     845//        << ttm->tm_hour << ":" << ttm->tm_min << ":" << ttm->tm_sec
     846//        << ")" << endl ;
     847//   cout << "STFiller::readNRO()  Elapsed time = " << t1 - t0 << " sec" << endl ;
     848  os << "Processed " << i << " rows" << endl ;
     849  os << "Added " << i - count << " rows (ignored "
     850     << count << " \"ZERO\" scans)" << endl ;
     851  os.post() ;
     852  os << "End time = " << t1
     853     << " ("
     854     << ttm->tm_year + 1900 << "/" << ttm->tm_mon + 1 << "/" << ttm->tm_mday
     855     << " "
     856     << ttm->tm_hour << ":" << ttm->tm_min << ":" << ttm->tm_sec
     857     << ")" << endl ;
     858  os << "Elapsed time = " << t1 - t0 << " sec" << endl ;
     859  os.post() ;
     860  //
     861
     862  return 0 ;
     863}
     864
     865Bool STFiller::fileCheck()
     866{
     867  bool bval = false ;
     868
     869  // if filename_ is directory, return false
     870  File inFile( filename_ ) ;
     871  if ( inFile.isDirectory() )
     872    return bval ;
     873
     874  // if beginning of header data is "RW", return true
     875  // otherwise, return false ;
     876  FILE *fp = fopen( filename_.c_str(), "r" ) ;
     877  char buf[9] ;
     878  char buf2[80] ;
     879  fread( buf, 4, 1, fp ) ;
     880  buf[4] = '\0' ;
     881  fseek( fp, 640, SEEK_SET ) ;
     882  fread( buf2, 80, 1, fp ) ;
     883  if ( ( strncmp( buf, "RW", 2 ) == 0 ) || ( strstr( buf2, "NRO45M" ) != NULL ) ) {
     884    bval = true ;
     885  }
     886  fclose( fp ) ;
     887  return bval ;
     888}
     889
    383890}//namespace asap
  • trunk/src/STFiller.h

    r1504 r1819  
    2727
    2828class PKSreader;
     29class NROReader;
    2930
    3031namespace asap {
     
    6162    */
    6263  explicit STFiller( const std::string& filename, int whichIF=-1,
    63                   int whichBeam=-1 );
     64                     int whichBeam=-1 );
    6465
    6566  /**
     
    7576   * @exception AipsError Creation of PKSreader failed
    7677   */
    77   void open( const std::string& filename, int whichIF=-1, int whichBeam=-1 );
     78  void open( const std::string& filename, const std::string& antenna, int whichIF=-1, int whichBeam=-1, casa::Bool getPt=casa::False );
    7879
    7980  /**
     
    9394  casa::CountedPtr<Scantable> getTable() const { return table_;}
    9495
     96  /**
     97   * For NRO data
     98   *
     99   * 2008/11/11 Takeshi Nakazato
     100   *
     101   * openNRO  : NRO version of open(), which performs to open file and
     102   *            read header data.
     103   * 
     104   * readNRO  : NRO version of read(), which performs to read scan
     105   *            records.
     106   *
     107   * fileCheck: Identify a type (NRO data or not) of filename_.
     108   **/
     109  void openNRO( int whichIF=-1, int whichBeam=-1 ) ;
     110  int readNRO() ;
     111  casa::Bool fileCheck() ;
     112
    95113  void setReferenceExpr(const std::string& rx) { refRx_ = rx; }
    96114
     
    105123  casa::Vector<casa::Bool> haveXPol_;
    106124  casa::String refRx_;
     125  NROReader *nreader_ ;
     126  casa::Bool isNRO_ ;
    107127};
    108128
  • trunk/src/STFitter.cpp

    r1391 r1819  
    3232#include <casa/Arrays/ArrayMath.h>
    3333#include <casa/Arrays/ArrayLogical.h>
     34#include <casa/Logging/LogIO.h>
    3435#include <scimath/Fitting.h>
    3536#include <scimath/Fitting/LinearFit.h>
     
    3738#include <scimath/Functionals/CompoundFunction.h>
    3839#include <scimath/Functionals/Gaussian1D.h>
     40#include "Lorentzian1D.h"
    3941#include <scimath/Functionals/Polynomial.h>
    4042#include <scimath/Mathematics/AutoDiff.h>
     
    146148    funcs_.resize(1);
    147149    funcs_[0] = new Polynomial<Float>(ncomp);
     150  } else if (expr == "lorentz") {
     151    if (ncomp < 1) throw (AipsError("Need at least one lorentzian to fit."));
     152    funcs_.resize(ncomp);
     153    for (Int k=0; k<ncomp; ++k) {
     154      funcs_[k] = new Lorentzian1D<Float>();
     155    }
    148156  } else {
    149     cerr << " compiled functions not yet implemented" << endl;
     157    //cerr << " compiled functions not yet implemented" << endl;
     158    LogIO os( LogOrigin( "Fitter", "setExpression()", WHERE ) ) ;
     159    os << LogIO::WARN << " compiled functions not yet implemented" << LogIO::POST;
    150160    //funcs_.resize(1);
    151161    //funcs_[0] = new CompiledFunction<Float>();
     
    227237            (funcs_[0]->parameters())[i] =  tmppar[i];
    228238        }
     239    } else if (dynamic_cast<Lorentzian1D<Float>* >(funcs_[0]) != 0) {
     240        uInt count = 0;
     241        for (uInt j=0; j < funcs_.nelements(); ++j) {
     242            for (uInt i=0; i < funcs_[j]->nparameters(); ++i) {
     243                (funcs_[j]->parameters())[i] = tmppar[count];
     244                parameters_[count] = tmppar[count];
     245                ++count;
     246            }
     247        }
    229248    }
    230249    // reset
     
    260279            funcs_[0]->mask(i) =  !fixed[i];
    261280        }
     281    } else if (dynamic_cast<Lorentzian1D<Float>* >(funcs_[0]) != 0) {
     282      uInt count = 0;
     283        for (uInt j=0; j < funcs_.nelements(); ++j) {
     284            for (uInt i=0; i < funcs_[j]->nparameters(); ++i) {
     285                funcs_[j]->mask(i) = !fixed[count];
     286                fixedpar_[count] = fixed[count];
     287                ++count;
     288            }
     289        }
    262290    }
    263291    return true;
  • trunk/src/STFrequencies.cpp

    r1694 r1819  
    128128}
    129129
     130void STFrequencies::setEntry( Double refpix, Double refval, Double inc, uInt id )
     131{
     132  Table t = table_(table_.col("ID") == Int(id) );
     133  if (t.nrow() == 0 ) {
     134    throw(AipsError("STFrequencies::getEntry - freqID out of range"));
     135  }
     136  for ( uInt i = 0 ; i < table_.nrow() ; i++ ) {
     137    uInt fid ;
     138    idCol_.get( i, fid ) ;
     139    if ( fid == id ) {
     140      refpixCol_.put( i, refpix ) ;
     141      refvalCol_.put( i, refval ) ;
     142      incrCol_.put( i, inc ) ;
     143    }
     144  }
     145}
     146
    130147SpectralCoordinate STFrequencies::getSpectralCoordinate( uInt id ) const
    131148{
     
    145162}
    146163
     164/**
    147165SpectralCoordinate
    148166  STFrequencies::getSpectralCoordinate( const MDirection& md,
     
    150168                                        const MEpoch& me,
    151169                                        Double restfreq, uInt id ) const
     170**/
     171SpectralCoordinate
     172  STFrequencies::getSpectralCoordinate( const MDirection& md,
     173                                              const MPosition& mp,
     174                                              const MEpoch& me,
     175                                              Vector<Double> restfreq, uInt id ) const
    152176{
    153177  SpectralCoordinate spc = getSpectralCoordinate(id);
    154   spc.setRestFrequency(restfreq, True);
     178  //spc.setRestFrequency(restfreq, True);
     179  // for now just use the first rest frequency
     180  if (restfreq.nelements()==0 ) {
     181    restfreq.resize(1);
     182    restfreq[0] = 0;
     183  }
     184  spc.setRestFrequency(restfreq[0], True);
    155185  if ( !spc.setReferenceConversion(getFrame(), me, mp, md) ) {
    156186    throw(AipsError("Couldn't convert frequency frame."));
  • trunk/src/STFrequencies.h

    r1375 r1819  
    5959                 casa::Double& inc, casa::uInt id );
    6060
     61  /***
     62   * Set the frequency values for a specific id via references
     63   * @param refpix the reference pixel
     64   * @param refval the reference value
     65   * @param inc    the increment
     66   * @param id     the identifier
     67   *
     68   * 17/09/2008 Takeshi Nakazato
     69   ***/
     70  void setEntry( casa::Double refpix, casa::Double refval,
     71                 casa::Double inc, casa::uInt id ) ;
     72
    6173
    6274  bool conformant(const STFrequencies& other) const;
     
    6981  casa::SpectralCoordinate getSpectralCoordinate( casa::uInt freqID ) const;
    7082
     83  /**
    7184  casa::SpectralCoordinate getSpectralCoordinate( const casa::MDirection& md,
    7285                                                  const casa::MPosition& mp,
     
    7588                                                  casa::uInt freqID
    7689                                                  ) const;
     90  **/
     91  casa::SpectralCoordinate getSpectralCoordinate( const casa::MDirection& md,
     92                                                  const casa::MPosition& mp,
     93                                                  const casa::MEpoch& me,
     94                                                  casa::Vector<casa::Double> restfreq,
     95                                                  casa::uInt freqID
     96                                                  ) const;
    7797
    7898  /**
  • trunk/src/STHeader.cpp

    r1439 r1819  
    3737#include <casa/Arrays/IPosition.h>
    3838#include <casa/Quanta/MVTime.h>
     39#include <casa/Logging/LogIO.h>
    3940
    40 
     41#include <sstream>
    4142
    4243#include "STDefs.h"
     
    7980  MVTime mvt(this->utc);
    8081  mvt.setFormat(MVTime::YMD);
    81   cout << "Observer: " << this->observer << endl
    82        << "Project: " << this->project << endl
    83        << "Obstype: " << this->obstype << endl
    84        << "Antenna: " << this->antennaname << endl
    85        << "Ant. Position: " << this->antennaposition << endl
    86        << "Equinox: " << this->equinox << endl
    87        << "Freq. ref.: " << this->freqref << endl
    88        << "Ref. frequency: " << this->reffreq << endl
    89        << "Bandwidth: "  << this->bandwidth << endl
    90        << "Time (utc): "
    91        << mvt
    92        << endl;
     82//   cout << "Observer: " << this->observer << endl
     83//        << "Project: " << this->project << endl
     84//        << "Obstype: " << this->obstype << endl
     85//        << "Antenna: " << this->antennaname << endl
     86//        << "Ant. Position: " << this->antennaposition << endl
     87//        << "Equinox: " << this->equinox << endl
     88//        << "Freq. ref.: " << this->freqref << endl
     89//        << "Ref. frequency: " << this->reffreq << endl
     90//        << "Bandwidth: "  << this->bandwidth << endl
     91//        << "Time (utc): "
     92//        << mvt
     93//        << endl;
     94  LogIO os( LogOrigin( "STHeader", "print()", WHERE ) ) ;
     95  os << "Observer: " << this->observer << endl
     96     << "Project: " << this->project << endl
     97     << "Obstype: " << this->obstype << endl
     98     << "Antenna: " << this->antennaname << endl
     99     << "Ant. Position: " << this->antennaposition << endl
     100     << "Equinox: " << this->equinox << endl
     101     << "Freq. ref.: " << this->freqref << endl
     102     << "Ref. frequency: " << this->reffreq << endl
     103     << "Bandwidth: "  << this->bandwidth << endl
     104     << "Time (utc): "
     105     << mvt
     106     << LogIO::POST ;
    93107  //setprecision(10) << this->utc << endl;
    94108}
     
    129143{
    130144   if (n_>0) {
    131       cerr << "Source    ID" << endl;
    132       for (uInt i=0; i<n_; i++) {
    133          cout << setw(11) << source_(i) << ID_(i) << endl;
    134       }
     145//       cerr << "Source    ID" << endl;
     146//       for (uInt i=0; i<n_; i++) {
     147//          cout << setw(11) << source_(i) << ID_(i) << endl;
     148     LogIO os( LogOrigin( "SDDataDesc", "summary()", WHERE ) ) ;
     149     ostringstream oss ;
     150     oss << "Source    ID" << endl;
     151     for (uInt i=0; i<n_; i++) {
     152       oss << setw(11) << source_(i) << ID_(i) << endl;
     153     }
     154     os << oss.str() << LogIO::POST ;
    135155   }
    136156}
  • trunk/src/STMath.cpp

    r1689 r1819  
    4444#include <scimath/Functionals/Polynomial.h>
    4545
     46#include <atnf/PKSIO/SrcType.h>
     47
     48#include <casa/Logging/LogIO.h>
     49#include <sstream>
     50
    4651#include "MathUtils.h"
    4752#include "RowAccumulator.h"
     
    5358
    5459using namespace asap;
     60
     61// tolerance for direction comparison (rad)
     62#define TOL_OTF    1.0e-15
     63#define TOL_POINT  2.9088821e-4  // 1 arcmin
    5564
    5665STMath::STMath(bool insitu) :
     
    7079                 const std::string& avmode)
    7180{
     81  LogIO os( LogOrigin( "STMath", "average()", WHERE ) ) ;
    7282  if ( avmode == "SCAN" && in.size() != 1 )
    7383    throw(AipsError("Can't perform 'SCAN' averaging on multiple tables.\n"
    7484                    "Use merge first."));
    7585  WeightType wtype = stringToWeight(weight);
     86
     87  // check if OTF observation
     88  String obstype = in[0]->getHeader().obstype ;
     89  Double tol = 0.0 ;
     90  if ( (obstype.find( "OTF" ) != String::npos) || (obstype.find( "OBSERVE_TARGET" ) != String::npos) ) {
     91    tol = TOL_OTF ;
     92  }
     93  else {
     94    tol = TOL_POINT ;
     95  }
    7696
    7797  // output
     
    113133  }
    114134  if ( avmode == "SCAN"  && in.size() == 1) {
    115     cols.resize(4);
    116     cols[3] = String("SCANNO");
     135    //cols.resize(4);
     136    //cols[3] = String("SCANNO");
     137    cols.resize(5);
     138    cols[3] = String("SRCNAME");
     139    cols[4] = String("SCANNO");
    117140  }
    118141  uInt outrowCount = 0;
    119142  TableIterator iter(baset, cols);
     143//   int count = 0 ;
    120144  while (!iter.pastEnd()) {
    121145    Table subt = iter.table();
    122     // copy the first row of this selection into the new table
    123     tout.addRow();
    124     TableCopy::copyRows(tout, subt, outrowCount, 0, 1);
    125     // re-index to 0
    126     if ( avmode != "SCAN" && avmode != "SOURCE" ) {
    127       scanColOut.put(outrowCount, uInt(0));
    128     }
    129     ++outrowCount;
     146//     // copy the first row of this selection into the new table
     147//     tout.addRow();
     148//     TableCopy::copyRows(tout, subt, outrowCount, 0, 1);
     149//     // re-index to 0
     150//     if ( avmode != "SCAN" && avmode != "SOURCE" ) {
     151//       scanColOut.put(outrowCount, uInt(0));
     152//     }
     153//     ++outrowCount;
     154    MDirection::ScalarColumn dircol ;
     155    dircol.attach( subt, "DIRECTION" ) ;
     156    Int length = subt.nrow() ;
     157    vector< Vector<Double> > dirs ;
     158    vector<int> indexes ;
     159    for ( Int i = 0 ; i < length ; i++ ) {
     160      Vector<Double> t = dircol(i).getAngle(Unit(String("rad"))).getValue() ;
     161      //os << << count++ << ": " ;
     162      //os << "[" << t[0] << "," << t[1] << "]" << LogIO::POST ;
     163      bool adddir = true ;
     164      for ( uInt j = 0 ; j < dirs.size() ; j++ ) {
     165        //if ( allTrue( t == dirs[j] ) ) {
     166        Double dx = t[0] - dirs[j][0] ;
     167        Double dy = t[1] - dirs[j][1] ;
     168        Double dd = sqrt( dx * dx + dy * dy ) ;
     169        //if ( allNearAbs( t, dirs[j], tol ) ) {
     170        if ( dd <= tol ) {
     171          adddir = false ;
     172          break ;
     173        }
     174      }
     175      if ( adddir ) {
     176        dirs.push_back( t ) ;
     177        indexes.push_back( i ) ;
     178      }
     179    }
     180    uInt rowNum = dirs.size() ;
     181    tout.addRow( rowNum ) ;
     182    for ( uInt i = 0 ; i < rowNum ; i++ ) {
     183      TableCopy::copyRows( tout, subt, outrowCount+i, indexes[i], 1 ) ;
     184      // re-index to 0
     185      if ( avmode != "SCAN" && avmode != "SOURCE" ) {
     186        scanColOut.put(outrowCount+i, uInt(0));
     187      }       
     188    }
     189    outrowCount += rowNum ;
    130190    ++iter;
    131191  }
    132 
    133192  RowAccumulator acc(wtype);
    134193  Vector<Bool> cmask(mask);
     
    155214        subt = basesubt( basesubt.col("SRCNAME") == rec.asString("SRCNAME") );
    156215      } else if (avmode == "SCAN") {
    157         subt = basesubt( basesubt.col("SCANNO") == Int(rec.asuInt("SCANNO")) );
     216        //subt = basesubt( basesubt.col("SCANNO") == Int(rec.asuInt("SCANNO")) );
     217        subt = basesubt( basesubt.col("SCANNO") == Int(rec.asuInt("SCANNO"))
     218                         && basesubt.col("SRCNAME") == rec.asString("SRCNAME") );
    158219      } else {
    159220        subt = basesubt;
    160221      }
     222
     223      vector<uInt> removeRows ;
     224      uInt nrsubt = subt.nrow() ;
     225      for ( uInt irow = 0 ; irow < nrsubt ; irow++ ) {
     226        //if ( !allTrue((subt.col("DIRECTION").getArrayDouble(TableExprId(irow)))==rec.asArrayDouble("DIRECTION")) ) {
     227        Vector<Double> x0 = (subt.col("DIRECTION").getArrayDouble(TableExprId(irow))) ;
     228        Vector<Double> x1 = rec.asArrayDouble("DIRECTION") ;
     229        double dx = x0[0] - x1[0] ;
     230        double dy = x0[0] - x1[0] ;
     231        Double dd = sqrt( dx * dx + dy * dy ) ;
     232        //if ( !allNearAbs((subt.col("DIRECTION").getArrayDouble(TableExprId(irow))), rec.asArrayDouble("DIRECTION"), tol ) ) {
     233        if ( dd > tol ) {
     234          removeRows.push_back( irow ) ;
     235        }
     236      }
     237      if ( removeRows.size() != 0 ) {
     238        subt.removeRow( removeRows ) ;
     239      }
     240     
     241      if ( nrsubt == removeRows.size() )
     242        throw(AipsError("Averaging data is empty.")) ;
     243
    161244      specCol.attach(subt,"SPECTRA");
    162245      flagCol.attach(subt,"FLAGTRA");
     
    192275    }
    193276    //write out
    194     Vector<uChar> flg(msk.shape());
    195     convertArray(flg, !msk);
    196     flagColOut.put(i, flg);
    197     specColOut.put(i, acc.getSpectrum());
    198     tsysColOut.put(i, acc.getTsys());
    199     intColOut.put(i, acc.getInterval());
    200     mjdColOut.put(i, acc.getTime());
    201     // we should only have one cycle now -> reset it to be 0
    202     // frequency switched data has different CYCLENO for different IFNO
    203     // which requires resetting this value
    204     cycColOut.put(i, uInt(0));
     277    if (acc.state()) {
     278      Vector<uChar> flg(msk.shape());
     279      convertArray(flg, !msk);
     280      flagColOut.put(i, flg);
     281      specColOut.put(i, acc.getSpectrum());
     282      tsysColOut.put(i, acc.getTsys());
     283      intColOut.put(i, acc.getInterval());
     284      mjdColOut.put(i, acc.getTime());
     285      // we should only have one cycle now -> reset it to be 0
     286      // frequency switched data has different CYCLENO for different IFNO
     287      // which requires resetting this value
     288      cycColOut.put(i, uInt(0));
     289    } else {
     290      ostringstream oss;
     291      oss << "For output row="<<i<<", all input rows of data are flagged. no averaging" << endl;
     292      pushLog(String(oss));
     293    }
    205294    acc.reset();
    206295  }
    207296  if (rowstodelete.nelements() > 0) {
     297    //cout << rowstodelete << endl;
     298    os << rowstodelete << LogIO::POST ;
    208299    tout.removeRow(rowstodelete);
    209300    if (tout.nrow() == 0) {
     
    219310                          const std::string& avmode )
    220311{
     312  // check if OTF observation
     313  String obstype = in->getHeader().obstype ;
     314  Double tol = 0.0 ;
     315  if ( obstype.find( "OTF" ) != String::npos ) {
     316    tol = TOL_OTF ;
     317  }
     318  else {
     319    tol = TOL_POINT ;
     320  }
     321
    221322  // clone as this is non insitu
    222323  bool insitu = insitu_;
     
    250351    flagCol.attach(subt,"FLAGTRA");
    251352    tsysCol.attach(subt,"TSYS");
    252     tout.addRow();
    253     TableCopy::copyRows(tout, subt, outrowCount, 0, 1);
    254     if ( avmode != "SCAN") {
    255       scanColOut.put(outrowCount, uInt(0));
    256     }
    257     Vector<Float> tmp;
    258     specCol.get(0, tmp);
    259     uInt nchan = tmp.nelements();
    260     // have to do channel by channel here as MaskedArrMath
    261     // doesn't have partialMedians
    262     Vector<uChar> flags = flagCol.getColumn(Slicer(Slice(0)));
    263     Vector<Float> outspec(nchan);
    264     Vector<uChar> outflag(nchan,0);
    265     Vector<Float> outtsys(1);/// @fixme when tsys is channel based
    266     for (uInt i=0; i<nchan; ++i) {
    267       Vector<Float> specs = specCol.getColumn(Slicer(Slice(i)));
    268       MaskedArray<Float> ma = maskedArray(specs,flags);
    269       outspec[i] = median(ma);
    270       if ( allEQ(ma.getMask(), False) )
    271         outflag[i] = userflag;// flag data
    272     }
    273     outtsys[0] = median(tsysCol.getColumn());
    274     specColOut.put(outrowCount, outspec);
    275     flagColOut.put(outrowCount, outflag);
    276     tsysColOut.put(outrowCount, outtsys);
    277     Double intsum = sum(intCol.getColumn());
    278     intColOut.put(outrowCount, intsum);
    279     ++outrowCount;
     353//     tout.addRow();
     354//     TableCopy::copyRows(tout, subt, outrowCount, 0, 1);
     355//     if ( avmode != "SCAN") {
     356//       scanColOut.put(outrowCount, uInt(0));
     357//     }
     358//     Vector<Float> tmp;
     359//     specCol.get(0, tmp);
     360//     uInt nchan = tmp.nelements();
     361//     // have to do channel by channel here as MaskedArrMath
     362//     // doesn't have partialMedians
     363//     Vector<uChar> flags = flagCol.getColumn(Slicer(Slice(0)));
     364//     Vector<Float> outspec(nchan);
     365//     Vector<uChar> outflag(nchan,0);
     366//     Vector<Float> outtsys(1);/// @fixme when tsys is channel based
     367//     for (uInt i=0; i<nchan; ++i) {
     368//       Vector<Float> specs = specCol.getColumn(Slicer(Slice(i)));
     369//       MaskedArray<Float> ma = maskedArray(specs,flags);
     370//       outspec[i] = median(ma);
     371//       if ( allEQ(ma.getMask(), False) )
     372//         outflag[i] = userflag;// flag data
     373//     }
     374//     outtsys[0] = median(tsysCol.getColumn());
     375//     specColOut.put(outrowCount, outspec);
     376//     flagColOut.put(outrowCount, outflag);
     377//     tsysColOut.put(outrowCount, outtsys);
     378//     Double intsum = sum(intCol.getColumn());
     379//     intColOut.put(outrowCount, intsum);
     380//     ++outrowCount;
     381//     ++iter;
     382    MDirection::ScalarColumn dircol ;
     383    dircol.attach( subt, "DIRECTION" ) ;
     384    Int length = subt.nrow() ;
     385    vector< Vector<Double> > dirs ;
     386    vector<int> indexes ;
     387    for ( Int i = 0 ; i < length ; i++ ) {
     388      Vector<Double> t = dircol(i).getAngle(Unit(String("rad"))).getValue() ;
     389      bool adddir = true ;
     390      for ( uInt j = 0 ; j < dirs.size() ; j++ ) {
     391        //if ( allTrue( t == dirs[j] ) ) {
     392        Double dx = t[0] - dirs[j][0] ;
     393        Double dy = t[1] - dirs[j][1] ;
     394        Double dd = sqrt( dx * dx + dy * dy ) ;
     395        //if ( allNearAbs( t, dirs[j], tol ) ) {
     396        if ( dd <= tol ) {
     397          adddir = false ;
     398          break ;
     399        }
     400      }
     401      if ( adddir ) {
     402        dirs.push_back( t ) ;
     403        indexes.push_back( i ) ;
     404      }
     405    }
     406    uInt rowNum = dirs.size() ;
     407    tout.addRow( rowNum );
     408    for ( uInt i = 0 ; i < rowNum ; i++ ) {
     409      TableCopy::copyRows(tout, subt, outrowCount+i, indexes[i], 1) ;
     410      if ( avmode != "SCAN") {
     411        //scanColOut.put(outrowCount+i, uInt(0));
     412      }
     413    }
     414    MDirection::ScalarColumn dircolOut ;
     415    dircolOut.attach( tout, "DIRECTION" ) ;
     416    for ( uInt irow = 0 ; irow < rowNum ; irow++ ) {
     417      Vector<Double> t = dircolOut(outrowCount+irow).getAngle(Unit(String("rad"))).getValue() ;
     418      Vector<Float> tmp;
     419      specCol.get(0, tmp);
     420      uInt nchan = tmp.nelements();
     421      // have to do channel by channel here as MaskedArrMath
     422      // doesn't have partialMedians
     423      Vector<uChar> flags = flagCol.getColumn(Slicer(Slice(0)));
     424      // mask spectra for different DIRECTION
     425      for ( uInt jrow = 0 ; jrow < subt.nrow() ; jrow++ ) {
     426        Vector<Double> direction = dircol(jrow).getAngle(Unit(String("rad"))).getValue() ;
     427        //if ( t[0] != direction[0] || t[1] != direction[1] ) {
     428        Double dx = t[0] - direction[0] ;
     429        Double dy = t[1] - direction[1] ;
     430        Double dd = sqrt( dx * dx + dy * dy ) ;
     431        //if ( !allNearAbs( t, direction, tol ) ) {
     432        if ( dd > tol ) {
     433          flags[jrow] = userflag ;
     434        }
     435      }
     436      Vector<Float> outspec(nchan);
     437      Vector<uChar> outflag(nchan,0);
     438      Vector<Float> outtsys(1);/// @fixme when tsys is channel based
     439      for (uInt i=0; i<nchan; ++i) {
     440        Vector<Float> specs = specCol.getColumn(Slicer(Slice(i)));
     441        MaskedArray<Float> ma = maskedArray(specs,flags);
     442        outspec[i] = median(ma);
     443        if ( allEQ(ma.getMask(), False) )
     444          outflag[i] = userflag;// flag data
     445      }
     446      outtsys[0] = median(tsysCol.getColumn());
     447      specColOut.put(outrowCount+irow, outspec);
     448      flagColOut.put(outrowCount+irow, outflag);
     449      tsysColOut.put(outrowCount+irow, outtsys);
     450      Vector<Double> integ = intCol.getColumn() ;
     451      MaskedArray<Double> mi = maskedArray( integ, flags ) ;
     452      Double intsum = sum(mi);
     453      intColOut.put(outrowCount+irow, intsum);
     454    }
     455    outrowCount += rowNum ;
    280456    ++iter;
    281457  }
     
    323499      if ( tsys ) {
    324500        ts += val;
     501        tsysCol.put(i, ts);
     502      }
     503    }
     504  }
     505  return out;
     506}
     507
     508CountedPtr< Scantable > STMath::arrayOperate( const CountedPtr< Scantable >& in,
     509                                              const std::vector<float> val,
     510                                              const std::string& mode,
     511                                              const std::string& opmode,
     512                                              bool tsys )
     513{
     514  CountedPtr< Scantable > out ;
     515  if ( opmode == "channel" ) {
     516    out = arrayOperateChannel( in, val, mode, tsys ) ;
     517  }
     518  else if ( opmode == "row" ) {
     519    out = arrayOperateRow( in, val, mode, tsys ) ;
     520  }
     521  else {
     522    throw( AipsError( "Unknown array operation mode." ) ) ;
     523  }
     524  return out ;
     525}
     526
     527CountedPtr< Scantable > STMath::arrayOperateChannel( const CountedPtr< Scantable >& in,
     528                                                     const std::vector<float> val,
     529                                                     const std::string& mode,
     530                                                     bool tsys )
     531{
     532  if ( val.size() == 1 ){
     533    return unaryOperate( in, val[0], mode, tsys ) ;
     534  }
     535
     536  // conformity of SPECTRA and TSYS
     537  if ( tsys ) {
     538    TableIterator titer(in->table(), "IFNO");
     539    while ( !titer.pastEnd() ) {
     540      ArrayColumn<Float> specCol( in->table(), "SPECTRA" ) ;
     541      ArrayColumn<Float> tsysCol( in->table(), "TSYS" ) ;
     542      Array<Float> spec = specCol.getColumn() ;
     543      Array<Float> ts = tsysCol.getColumn() ;
     544      if ( !spec.conform( ts ) ) {
     545        throw( AipsError( "SPECTRA and TSYS must conform in shape if you want to apply operation on Tsys." ) ) ;
     546      }
     547      titer.next() ;
     548    }
     549  }
     550
     551  // check if all spectra in the scantable have the same number of channel
     552  vector<uInt> nchans;
     553  vector<uInt> ifnos = in->getIFNos() ;
     554  for ( uInt i = 0 ; i < ifnos.size() ; i++ ) {
     555    nchans.push_back( in->nchan( ifnos[i] ) ) ;
     556  }
     557  Vector<uInt> mchans( nchans ) ;
     558  if ( anyNE( mchans, mchans[0] ) ) {
     559    throw( AipsError("All spectra in the input scantable must have the same number of channel for vector operation." ) ) ;
     560  }
     561
     562  // check if vector size is equal to nchan
     563  Vector<Float> fact( val ) ;
     564  if ( fact.nelements() != mchans[0] ) {
     565    throw( AipsError("Vector size must be 1 or be same as number of channel.") ) ;
     566  }
     567
     568  // check divided by zero
     569  if ( ( mode == "DIV" ) && anyEQ( fact, (float)0.0 ) ) {
     570    throw( AipsError("Divided by zero is not recommended." ) ) ;
     571  }
     572
     573  CountedPtr< Scantable > out = getScantable(in, false);
     574  Table& tab = out->table();
     575  ArrayColumn<Float> specCol(tab,"SPECTRA");
     576  ArrayColumn<Float> tsysCol(tab,"TSYS");
     577  for (uInt i=0; i<tab.nrow(); ++i) {
     578    Vector<Float> spec;
     579    Vector<Float> ts;
     580    specCol.get(i, spec);
     581    tsysCol.get(i, ts);
     582    if (mode == "MUL" || mode == "DIV") {
     583      if (mode == "DIV") fact = (float)1.0 / fact;
     584      spec *= fact;
     585      specCol.put(i, spec);
     586      if ( tsys ) {
     587        ts *= fact;
     588        tsysCol.put(i, ts);
     589      }
     590    } else if ( mode == "ADD"  || mode == "SUB") {
     591      if (mode == "SUB") fact *= (float)-1.0 ;
     592      spec += fact;
     593      specCol.put(i, spec);
     594      if ( tsys ) {
     595        ts += fact;
     596        tsysCol.put(i, ts);
     597      }
     598    }
     599  }
     600  return out;
     601}
     602
     603CountedPtr< Scantable > STMath::arrayOperateRow( const CountedPtr< Scantable >& in,
     604                                                 const std::vector<float> val,
     605                                                 const std::string& mode,
     606                                                 bool tsys )
     607{
     608  if ( val.size() == 1 ) {
     609    return unaryOperate( in, val[0], mode, tsys ) ;
     610  }
     611
     612  // conformity of SPECTRA and TSYS
     613  if ( tsys ) {
     614    TableIterator titer(in->table(), "IFNO");
     615    while ( !titer.pastEnd() ) {
     616      ArrayColumn<Float> specCol( in->table(), "SPECTRA" ) ;
     617      ArrayColumn<Float> tsysCol( in->table(), "TSYS" ) ;
     618      Array<Float> spec = specCol.getColumn() ;
     619      Array<Float> ts = tsysCol.getColumn() ;
     620      if ( !spec.conform( ts ) ) {
     621        throw( AipsError( "SPECTRA and TSYS must conform in shape if you want to apply operation on Tsys." ) ) ;
     622      }
     623      titer.next() ;
     624    }
     625  }
     626
     627  // check if vector size is equal to nrow
     628  Vector<Float> fact( val ) ;
     629  if ( fact.nelements() != in->nrow() ) {
     630    throw( AipsError("Vector size must be 1 or be same as number of row.") ) ;
     631  }
     632
     633  // check divided by zero
     634  if ( ( mode == "DIV" ) && anyEQ( fact, (float)0.0 ) ) {
     635    throw( AipsError("Divided by zero is not recommended." ) ) ;
     636  }
     637
     638  CountedPtr< Scantable > out = getScantable(in, false);
     639  Table& tab = out->table();
     640  ArrayColumn<Float> specCol(tab,"SPECTRA");
     641  ArrayColumn<Float> tsysCol(tab,"TSYS");
     642  if (mode == "DIV") fact = (float)1.0 / fact;
     643  if (mode == "SUB") fact *= (float)-1.0 ;
     644  for (uInt i=0; i<tab.nrow(); ++i) {
     645    Vector<Float> spec;
     646    Vector<Float> ts;
     647    specCol.get(i, spec);
     648    tsysCol.get(i, ts);
     649    if (mode == "MUL" || mode == "DIV") {
     650      spec *= fact[i];
     651      specCol.put(i, spec);
     652      if ( tsys ) {
     653        ts *= fact[i];
     654        tsysCol.put(i, ts);
     655      }
     656    } else if ( mode == "ADD"  || mode == "SUB") {
     657      spec += fact[i];
     658      specCol.put(i, spec);
     659      if ( tsys ) {
     660        ts += fact[i];
     661        tsysCol.put(i, ts);
     662      }
     663    }
     664  }
     665  return out;
     666}
     667
     668CountedPtr< Scantable > STMath::array2dOperate( const CountedPtr< Scantable >& in,
     669                                                const std::vector< std::vector<float> > val,
     670                                                const std::string& mode,
     671                                                bool tsys )
     672{
     673  // conformity of SPECTRA and TSYS
     674  if ( tsys ) {
     675    TableIterator titer(in->table(), "IFNO");
     676    while ( !titer.pastEnd() ) {
     677      ArrayColumn<Float> specCol( in->table(), "SPECTRA" ) ;
     678      ArrayColumn<Float> tsysCol( in->table(), "TSYS" ) ;
     679      Array<Float> spec = specCol.getColumn() ;
     680      Array<Float> ts = tsysCol.getColumn() ;
     681      if ( !spec.conform( ts ) ) {
     682        throw( AipsError( "SPECTRA and TSYS must conform in shape if you want to apply operation on Tsys." ) ) ;
     683      }
     684      titer.next() ;
     685    }
     686  }
     687
     688  // some checks
     689  vector<uInt> nchans;
     690  for ( uInt i = 0 ; i < in->nrow() ; i++ ) {
     691    nchans.push_back( (in->getSpectrum( i )).size() ) ;
     692  }
     693  //Vector<uInt> mchans( nchans ) ;
     694  vector< Vector<Float> > facts ;
     695  for ( uInt i = 0 ; i < nchans.size() ; i++ ) {
     696    Vector<Float> tmp( val[i] ) ;
     697    // check divided by zero
     698    if ( ( mode == "DIV" ) && anyEQ( tmp, (float)0.0 ) ) {
     699      throw( AipsError("Divided by zero is not recommended." ) ) ;
     700    }
     701    // conformity check
     702    if ( tmp.nelements() != nchans[i] ) {
     703      stringstream ss ;
     704      ss << "Row " << i << ": Vector size must be same as number of channel." ;
     705      throw( AipsError( ss.str() ) ) ;
     706    }
     707    facts.push_back( tmp ) ;
     708  }
     709
     710
     711  CountedPtr< Scantable > out = getScantable(in, false);
     712  Table& tab = out->table();
     713  ArrayColumn<Float> specCol(tab,"SPECTRA");
     714  ArrayColumn<Float> tsysCol(tab,"TSYS");
     715  for (uInt i=0; i<tab.nrow(); ++i) {
     716    Vector<Float> fact = facts[i] ;
     717    Vector<Float> spec;
     718    Vector<Float> ts;
     719    specCol.get(i, spec);
     720    tsysCol.get(i, ts);
     721    if (mode == "MUL" || mode == "DIV") {
     722      if (mode == "DIV") fact = (float)1.0 / fact;
     723      spec *= fact;
     724      specCol.put(i, spec);
     725      if ( tsys ) {
     726        ts *= fact;
     727        tsysCol.put(i, ts);
     728      }
     729    } else if ( mode == "ADD"  || mode == "SUB") {
     730      if (mode == "SUB") fact *= (float)-1.0 ;
     731      spec += fact;
     732      specCol.put(i, spec);
     733      if ( tsys ) {
     734        ts += fact;
    325735        tsysCol.put(i, ts);
    326736      }
     
    386796}
    387797
     798MaskedArray<Double> STMath::maskedArray( const Vector<Double>& s,
     799                                         const Vector<uChar>& f)
     800{
     801  Vector<Bool> mask;
     802  mask.resize(f.shape());
     803  convertArray(mask, f);
     804  return MaskedArray<Double>(s,!mask);
     805}
     806
    388807Vector<uChar> STMath::flagsFromMA(const MaskedArray<Float>& ma)
    389808{
     
    402821  // make this operation non insitu
    403822  const Table& tin = in->table();
    404   Table ons = tin(tin.col("SRCTYPE") == Int(0));
    405   Table offs = tin(tin.col("SRCTYPE") == Int(1));
     823  Table ons = tin(tin.col("SRCTYPE") == Int(SrcType::PSON));
     824  Table offs = tin(tin.col("SRCTYPE") == Int(SrcType::PSOFF));
    406825  if ( offs.nrow() == 0 )
    407826    throw(AipsError("No 'off' scans present."));
     
    6411060         //Debug
    6421061         //if(noff!=ndiff) cerr<<"noff and ndiff is not equal"<<endl;
     1062         //LogIO os( LogOrigin( "STMath", "dototalpower()", WHERE ) ) ;
     1063         //if(noff!=ndiff) os<<"noff and ndiff is not equal"<<LogIO::POST;
    6431064         meanoff = sum(spoff)/noff;
    6441065         meandiff = sum(spdiff)/ndiff;
     
    7601181      //Debug
    7611182      //cerr<<"Tsys used="<<tsysrefscalar<<endl;
     1183      //LogIO os( LogOrigin( "STMath", "dosigref", WHERE ) ) ;
     1184      //os<<"Tsys used="<<tsysrefscalar<<LogIO::POST;
    7621185      // fill the result, replay signal tsys by reference tsys
    7631186      outintCol.put(i, resint);
     
    7821205  setInsitu(false);
    7831206  STSelector sel;
    784   std::vector<int> scan1, scan2, beams;
     1207  std::vector<int> scan1, scan2, beams, types;
    7851208  std::vector< vector<int> > scanpair;
    786   std::vector<string> calstate;
     1209  //std::vector<string> calstate;
     1210  std::vector<int> calstate;
    7871211  String msg;
    7881212
     
    8311255  scanpair.push_back(scan1);
    8321256  scanpair.push_back(scan2);
    833   calstate.push_back("*calon");
    834   calstate.push_back("*[^calon]");
     1257  //calstate.push_back("*calon");
     1258  //calstate.push_back("*[^calon]");
     1259  calstate.push_back(SrcType::NODCAL);
     1260  calstate.push_back(SrcType::NOD);
    8351261  CountedPtr< Scantable > ws = getScantable(s, false);
    8361262  uInt l=0;
     
    8411267          sel.reset();
    8421268          sel.setScans(scanpair[i]);
    843           sel.setName(calstate[k]);
     1269          //sel.setName(calstate[k]);
     1270          types.clear();
     1271          types.push_back(calstate[k]);
     1272          sel.setTypes(types);
    8441273          beams.clear();
    8451274          beams.push_back(j);
     
    9261355      //Array<Float> avtsys =  Float(0.5) * (tsys1 + tsys2);
    9271356      // cerr<< "Tsys1="<<tsys1<<" Tsys2="<<tsys2<<endl;
     1357      // LogIO os( LogOrigin( "STMath", "donod", WHERE ) ) ;
     1358      // os<< "Tsys1="<<tsys1<<" Tsys2="<<tsys2<<LogIO::POST;
    9281359      tsys1[0] = sqrt(tsyssq1 + tsyssq2);
    9291360      Array<Float> avtsys =  tsys1;
     
    9521383  CountedPtr< Scantable > ws = getScantable(s, false);
    9531384  CountedPtr< Scantable > sig, sigwcal, ref, refwcal;
    954   CountedPtr< Scantable > calsig, calref, out;
     1385  CountedPtr< Scantable > calsig, calref, out, out1, out2;
     1386  Bool nofold=False;
     1387  vector<int> types ;
    9551388
    9561389  //split the data
    957   sel.setName("*_fs");
     1390  //sel.setName("*_fs");
     1391  types.push_back( SrcType::FSON ) ;
     1392  sel.setTypes( types ) ;
    9581393  ws->setSelection(sel);
    9591394  sig = getScantable(ws,false);
    9601395  sel.reset();
    961   sel.setName("*_fs_calon");
     1396  types.clear() ;
     1397  //sel.setName("*_fs_calon");
     1398  types.push_back( SrcType::FONCAL ) ;
     1399  sel.setTypes( types ) ;
    9621400  ws->setSelection(sel);
    9631401  sigwcal = getScantable(ws,false);
    9641402  sel.reset();
    965   sel.setName("*_fsr");
     1403  types.clear() ;
     1404  //sel.setName("*_fsr");
     1405  types.push_back( SrcType::FSOFF ) ;
     1406  sel.setTypes( types ) ;
    9661407  ws->setSelection(sel);
    9671408  ref = getScantable(ws,false);
    9681409  sel.reset();
    969   sel.setName("*_fsr_calon");
     1410  types.clear() ;
     1411  //sel.setName("*_fsr_calon");
     1412  types.push_back( SrcType::FOFFCAL ) ;
     1413  sel.setTypes( types ) ;
    9701414  ws->setSelection(sel);
    9711415  refwcal = getScantable(ws,false);
     1416  sel.reset() ;
     1417  types.clear() ;
    9721418
    9731419  calsig = dototalpower(sigwcal, sig, tcal=tcal);
    9741420  calref = dototalpower(refwcal, ref, tcal=tcal);
    9751421
    976   out=dosigref(calsig,calref,smoothref,tsysv,tau);
    977 
     1422  out1=dosigref(calsig,calref,smoothref,tsysv,tau);
     1423  out2=dosigref(calref,calsig,smoothref,tsysv,tau);
     1424
     1425  Table& tabout1=out1->table();
     1426  Table& tabout2=out2->table();
     1427  ROScalarColumn<uInt> freqidCol1(tabout1, "FREQ_ID");
     1428  ScalarColumn<uInt> freqidCol2(tabout2, "FREQ_ID");
     1429  ROArrayColumn<Float> specCol(tabout2, "SPECTRA");
     1430  Vector<Float> spec; specCol.get(0, spec);
     1431  uInt nchan = spec.nelements();
     1432  uInt freqid1; freqidCol1.get(0,freqid1);
     1433  uInt freqid2; freqidCol2.get(0,freqid2);
     1434  Double rp1, rp2, rv1, rv2, inc1, inc2;
     1435  out1->frequencies().getEntry(rp1, rv1, inc1, freqid1);
     1436  out2->frequencies().getEntry(rp2, rv2, inc2, freqid2);
     1437  //cerr << out1->frequencies().table().nrow() << " " << out2->frequencies().table().nrow() << endl ;
     1438  //LogIO os( LogOrigin( "STMath", "dofs()", WHERE ) ) ;
     1439  //os << out1->frequencies().table().nrow() << " " << out2->frequencies().table().nrow() << LogIO::POST ;
     1440  if (rp1==rp2) {
     1441    Double foffset = rv1 - rv2;
     1442    uInt choffset = static_cast<uInt>(foffset/abs(inc2));
     1443    if (choffset >= nchan) {
     1444      //cerr<<"out-band frequency switching, no folding"<<endl;
     1445      LogIO os( LogOrigin( "STMath", "dofs()", WHERE ) ) ;
     1446      os<<"out-band frequency switching, no folding"<<LogIO::POST;
     1447      nofold = True;
     1448    }
     1449  }
     1450
     1451  if (nofold) {
     1452    std::vector< CountedPtr< Scantable > > tabs;
     1453    tabs.push_back(out1);
     1454    tabs.push_back(out2);
     1455    out = merge(tabs);
     1456  }
     1457  else {
     1458    //out = out1;
     1459    Double choffset = ( rv1 - rv2 ) / inc2 ;
     1460    out = dofold( out1, out2, choffset ) ;
     1461  }
     1462   
    9781463  return out;
     1464}
     1465
     1466CountedPtr<Scantable> STMath::dofold( const CountedPtr<Scantable> &sig,
     1467                                      const CountedPtr<Scantable> &ref,
     1468                                      Double choffset,
     1469                                      Double choffset2 )
     1470{
     1471  LogIO os( LogOrigin( "STMath", "dofold", WHERE ) ) ;
     1472  os << "choffset=" << choffset << " choffset2=" << choffset2 << LogIO::POST ;
     1473
     1474  // output scantable
     1475  CountedPtr<Scantable> out = getScantable( sig, false ) ;
     1476
     1477  // separate choffset to integer part and decimal part
     1478  Int ioffset = (Int)choffset ;
     1479  Double doffset = choffset - ioffset ;
     1480  Int ioffset2 = (Int)choffset2 ;
     1481  Double doffset2 = choffset2 - ioffset2 ;
     1482  os << "ioffset=" << ioffset << " doffset=" << doffset << LogIO::POST ;
     1483  os << "ioffset2=" << ioffset2 << " doffset2=" << doffset2 << LogIO::POST ; 
     1484
     1485  // get column
     1486  ROArrayColumn<Float> specCol1( sig->table(), "SPECTRA" ) ;
     1487  ROArrayColumn<Float> specCol2( ref->table(), "SPECTRA" ) ;
     1488  ROArrayColumn<Float> tsysCol1( sig->table(), "TSYS" ) ;
     1489  ROArrayColumn<Float> tsysCol2( ref->table(), "TSYS" ) ;
     1490  ROArrayColumn<uChar> flagCol1( sig->table(), "FLAGTRA" ) ;
     1491  ROArrayColumn<uChar> flagCol2( ref->table(), "FLAGTRA" ) ;
     1492  ROScalarColumn<Double> mjdCol1( sig->table(), "TIME" ) ;
     1493  ROScalarColumn<Double> mjdCol2( ref->table(), "TIME" ) ;
     1494  ROScalarColumn<Double> intervalCol1( sig->table(), "INTERVAL" ) ;
     1495  ROScalarColumn<Double> intervalCol2( ref->table(), "INTERVAL" ) ;
     1496
     1497  // check
     1498  if ( ioffset == 0 ) {
     1499    LogIO os( LogOrigin( "STMath", "dofold()", WHERE ) ) ;
     1500    os << "channel offset is zero, no folding" << LogIO::POST ;
     1501    return out ;
     1502  }
     1503  int nchan = ref->nchan() ;
     1504  if ( abs(ioffset) >= nchan ) {
     1505    LogIO os( LogOrigin( "STMath", "dofold()", WHERE ) ) ;
     1506    os << "out-band frequency switching, no folding" << LogIO::POST ;
     1507    return out ;
     1508  }
     1509
     1510  // attach column for output scantable
     1511  ArrayColumn<Float> specColOut( out->table(), "SPECTRA" ) ;
     1512  ArrayColumn<uChar> flagColOut( out->table(), "FLAGTRA" ) ;
     1513  ArrayColumn<Float> tsysColOut( out->table(), "TSYS" ) ;
     1514  ScalarColumn<Double> mjdColOut( out->table(), "TIME" ) ;
     1515  ScalarColumn<Double> intervalColOut( out->table(), "INTERVAL" ) ;
     1516  ScalarColumn<uInt> fidColOut( out->table(), "FREQ_ID" ) ;
     1517
     1518  // for each row
     1519  // assume that the data order are same between sig and ref
     1520  RowAccumulator acc( asap::W_TINTSYS ) ;
     1521  for ( int i = 0 ; i < sig->nrow() ; i++ ) {
     1522    // get values
     1523    Vector<Float> spsig ;
     1524    specCol1.get( i, spsig ) ;
     1525    Vector<Float> spref ;
     1526    specCol2.get( i, spref ) ;
     1527    Vector<Float> tsyssig ;
     1528    tsysCol1.get( i, tsyssig ) ;
     1529    Vector<Float> tsysref ;
     1530    tsysCol2.get( i, tsysref ) ;
     1531    Vector<uChar> flagsig ;
     1532    flagCol1.get( i, flagsig ) ;
     1533    Vector<uChar> flagref ;
     1534    flagCol2.get( i, flagref ) ;
     1535    Double timesig ;
     1536    mjdCol1.get( i, timesig ) ;
     1537    Double timeref ;
     1538    mjdCol2.get( i, timeref ) ;
     1539    Double intsig ;
     1540    intervalCol1.get( i, intsig ) ;
     1541    Double intref ;
     1542    intervalCol2.get( i, intref ) ;
     1543
     1544    // shift reference spectra
     1545    int refchan = spref.nelements() ;
     1546    Vector<Float> sspref( spref.nelements() ) ;
     1547    Vector<Float> stsysref( tsysref.nelements() ) ;
     1548    Vector<uChar> sflagref( flagref.nelements() ) ;
     1549    if ( ioffset > 0 ) {
     1550      // SPECTRA and FLAGTRA
     1551      for ( int j = 0 ; j < refchan-ioffset ; j++ ) {
     1552        sspref[j] = spref[j+ioffset] ;
     1553        sflagref[j] = flagref[j+ioffset] ;
     1554      }
     1555      for ( int j = refchan-ioffset ; j < refchan ; j++ ) {
     1556        sspref[j] = spref[j-refchan+ioffset] ;
     1557        sflagref[j] = flagref[j-refchan+ioffset] ;
     1558      }
     1559      spref = sspref.copy() ;
     1560      flagref = sflagref.copy() ;
     1561      for ( int j = 0 ; j < refchan - 1 ; j++ ) {
     1562        sspref[j] = doffset * spref[j+1] + ( 1.0 - doffset ) * spref[j] ;
     1563        sflagref[j] = flagref[j+1] + flagref[j] ;
     1564      }
     1565      sspref[refchan-1] = doffset * spref[0] + ( 1.0 - doffset ) * spref[refchan-1] ;
     1566      sflagref[refchan-1] = flagref[0] + flagref[refchan-1] ;
     1567
     1568      // TSYS
     1569      if ( spref.nelements() == tsysref.nelements() ) {
     1570        for ( int j = 0 ; j < refchan-ioffset ; j++ ) {
     1571          stsysref[j] = tsysref[j+ioffset] ;
     1572        }
     1573        for ( int j = refchan-ioffset ; j < refchan ; j++ ) {
     1574          stsysref[j] = tsysref[j-refchan+ioffset] ;
     1575        }
     1576        tsysref = stsysref.copy() ;
     1577        for ( int j = 0 ; j < refchan - 1 ; j++ ) {
     1578          stsysref[j] = doffset * tsysref[j+1] + ( 1.0 - doffset ) * tsysref[j] ;
     1579        }
     1580        stsysref[refchan-1] = doffset * tsysref[0] + ( 1.0 - doffset ) * tsysref[refchan-1] ;
     1581      }
     1582    }
     1583    else {
     1584      // SPECTRA and FLAGTRA
     1585      for ( int j = 0 ; j < abs(ioffset) ; j++ ) {
     1586        sspref[j] = spref[refchan+ioffset+j] ;
     1587        sflagref[j] = flagref[refchan+ioffset+j] ;
     1588      }
     1589      for ( int j = abs(ioffset) ; j < refchan ; j++ ) {
     1590        sspref[j] = spref[j+ioffset] ;
     1591        sflagref[j] = flagref[j+ioffset] ;
     1592      }
     1593      spref = sspref.copy() ;
     1594      flagref = sflagref.copy() ;
     1595      sspref[0] = doffset * spref[refchan-1] + ( 1.0 - doffset ) * spref[0] ;
     1596      sflagref[0] = flagref[0] + flagref[refchan-1] ;
     1597      for ( int j = 1 ; j < refchan ; j++ ) {
     1598        sspref[j] = doffset * spref[j-1] + ( 1.0 - doffset ) * spref[j] ;
     1599        sflagref[j] = flagref[j-1] + flagref[j] ;
     1600      }
     1601      // TSYS
     1602      if ( spref.nelements() == tsysref.nelements() ) {
     1603        for ( int j = 0 ; j < abs(ioffset) ; j++ ) {
     1604          stsysref[j] = tsysref[refchan+ioffset+j] ;
     1605        }
     1606        for ( int j = abs(ioffset) ; j < refchan ; j++ ) {
     1607          stsysref[j] = tsysref[j+ioffset] ;
     1608        }
     1609        tsysref = stsysref.copy() ;
     1610        stsysref[0] = doffset * tsysref[refchan-1] + ( 1.0 - doffset ) * tsysref[0] ;
     1611        for ( int j = 1 ; j < refchan ; j++ ) {
     1612          stsysref[j] = doffset * tsysref[j-1] + ( 1.0 - doffset ) * tsysref[j] ;
     1613        }
     1614      }
     1615    }
     1616
     1617    // shift signal spectra if necessary (only for APEX?)
     1618    if ( choffset2 != 0.0 ) {
     1619      int sigchan = spsig.nelements() ;
     1620      Vector<Float> sspsig( spsig.nelements() ) ;
     1621      Vector<Float> stsyssig( tsyssig.nelements() ) ;
     1622      Vector<uChar> sflagsig( flagsig.nelements() ) ;
     1623      if ( ioffset2 > 0 ) {
     1624        // SPECTRA and FLAGTRA
     1625        for ( int j = 0 ; j < sigchan-ioffset2 ; j++ ) {
     1626          sspsig[j] = spsig[j+ioffset2] ;
     1627          sflagsig[j] = flagsig[j+ioffset2] ;
     1628        }
     1629        for ( int j = sigchan-ioffset2 ; j < sigchan ; j++ ) {
     1630          sspsig[j] = spsig[j-sigchan+ioffset2] ;
     1631          sflagsig[j] = flagsig[j-sigchan+ioffset2] ;
     1632        }
     1633        spsig = sspsig.copy() ;
     1634        flagsig = sflagsig.copy() ;
     1635        for ( int j = 0 ; j < sigchan - 1 ; j++ ) {
     1636          sspsig[j] = doffset2 * spsig[j+1] + ( 1.0 - doffset2 ) * spsig[j] ;
     1637          sflagsig[j] = flagsig[j+1] || flagsig[j] ;
     1638        }
     1639        sspsig[sigchan-1] = doffset2 * spsig[0] + ( 1.0 - doffset2 ) * spsig[sigchan-1] ;
     1640        sflagsig[sigchan-1] = flagsig[0] || flagsig[sigchan-1] ;
     1641        // TSTS
     1642        if ( spsig.nelements() == tsyssig.nelements() ) {
     1643          for ( int j = 0 ; j < sigchan-ioffset2 ; j++ ) {
     1644            stsyssig[j] = tsyssig[j+ioffset2] ;
     1645          }
     1646          for ( int j = sigchan-ioffset2 ; j < sigchan ; j++ ) {
     1647            stsyssig[j] = tsyssig[j-sigchan+ioffset2] ;
     1648          }
     1649          tsyssig = stsyssig.copy() ;
     1650          for ( int j = 0 ; j < sigchan - 1 ; j++ ) {
     1651            stsyssig[j] = doffset2 * tsyssig[j+1] + ( 1.0 - doffset2 ) * tsyssig[j] ;
     1652          }
     1653          stsyssig[sigchan-1] = doffset2 * tsyssig[0] + ( 1.0 - doffset2 ) * tsyssig[sigchan-1] ;
     1654        }
     1655      }
     1656      else {
     1657        // SPECTRA and FLAGTRA
     1658        for ( int j = 0 ; j < abs(ioffset2) ; j++ ) {
     1659          sspsig[j] = spsig[sigchan+ioffset2+j] ;
     1660          sflagsig[j] = flagsig[sigchan+ioffset2+j] ;
     1661        }
     1662        for ( int j = abs(ioffset2) ; j < sigchan ; j++ ) {
     1663          sspsig[j] = spsig[j+ioffset2] ;
     1664          sflagsig[j] = flagsig[j+ioffset2] ;
     1665        }
     1666        spsig = sspsig.copy() ;
     1667        flagsig = sflagsig.copy() ;
     1668        sspsig[0] = doffset2 * spsig[sigchan-1] + ( 1.0 - doffset2 ) * spsig[0] ;
     1669        sflagsig[0] = flagsig[0] + flagsig[sigchan-1] ;
     1670        for ( int j = 1 ; j < sigchan ; j++ ) {
     1671          sspsig[j] = doffset2 * spsig[j-1] + ( 1.0 - doffset2 ) * spsig[j] ;
     1672          sflagsig[j] = flagsig[j-1] + flagsig[j] ;
     1673        }
     1674        // TSYS
     1675        if ( spsig.nelements() == tsyssig.nelements() ) {
     1676          for ( int j = 0 ; j < abs(ioffset2) ; j++ ) {
     1677            stsyssig[j] = tsyssig[sigchan+ioffset2+j] ;
     1678          }
     1679          for ( int j = abs(ioffset2) ; j < sigchan ; j++ ) {
     1680            stsyssig[j] = tsyssig[j+ioffset2] ;
     1681          }
     1682          tsyssig = stsyssig.copy() ;
     1683          stsyssig[0] = doffset2 * tsyssig[sigchan-1] + ( 1.0 - doffset2 ) * tsyssig[0] ;
     1684          for ( int j = 1 ; j < sigchan ; j++ ) {
     1685            stsyssig[j] = doffset2 * tsyssig[j-1] + ( 1.0 - doffset2 ) * tsyssig[j] ;
     1686          }
     1687        }
     1688      }
     1689    }
     1690
     1691    // folding
     1692    acc.add( spsig, !flagsig, tsyssig, intsig, timesig ) ;
     1693    acc.add( sspref, !sflagref, stsysref, intref, timeref ) ;
     1694   
     1695    // put result
     1696    specColOut.put( i, acc.getSpectrum() ) ;
     1697    const Vector<Bool> &msk = acc.getMask() ;
     1698    Vector<uChar> flg( msk.shape() ) ;
     1699    convertArray( flg, !msk ) ;
     1700    flagColOut.put( i, flg ) ;
     1701    tsysColOut.put( i, acc.getTsys() ) ;
     1702    intervalColOut.put( i, acc.getInterval() ) ;
     1703    mjdColOut.put( i, acc.getTime() ) ;
     1704    // change FREQ_ID to unshifted IF setting (only for APEX?)
     1705    if ( choffset2 != 0.0 ) {
     1706      uInt freqid = fidColOut( 0 ) ; // assume single-IF data
     1707      double refpix, refval, increment ;
     1708      out->frequencies().getEntry( refpix, refval, increment, freqid ) ;
     1709      refval -= choffset * increment ;
     1710      uInt newfreqid = out->frequencies().addEntry( refpix, refval, increment ) ;
     1711      Vector<uInt> freqids = fidColOut.getColumn() ;
     1712      for ( uInt j = 0 ; j < freqids.nelements() ; j++ ) {
     1713        if ( freqids[j] == freqid )
     1714          freqids[j] = newfreqid ;
     1715      }
     1716      fidColOut.putColumn( freqids ) ;
     1717    }
     1718
     1719    acc.reset() ;
     1720  }
     1721
     1722  return out ;
    9791723}
    9801724
     
    10511795    }
    10521796    out.push_back(outstat);
     1797  }
     1798  return out;
     1799}
     1800
     1801std::vector< int > STMath::minMaxChan( const CountedPtr< Scantable > & in,
     1802                                        const std::vector< bool > & mask,
     1803                                        const std::string& which )
     1804{
     1805
     1806  Vector<Bool> m(mask);
     1807  const Table& tab = in->table();
     1808  ROArrayColumn<Float> specCol(tab, "SPECTRA");
     1809  ROArrayColumn<uChar> flagCol(tab, "FLAGTRA");
     1810  std::vector<int> out;
     1811  for (uInt i=0; i < tab.nrow(); ++i ) {
     1812    Vector<Float> spec; specCol.get(i, spec);
     1813    Vector<uChar> flag; flagCol.get(i, flag);
     1814    MaskedArray<Float> ma  = maskedArray(spec, flag);
     1815    if (ma.ndim() != 1) {
     1816      throw (ArrayError(
     1817          "std::vector<int> STMath::minMaxChan("
     1818          "ContedPtr<Scantable> &in, std::vector<bool> &mask, "
     1819          " std::string &which)"
     1820          " - MaskedArray is not 1D"));
     1821    }
     1822    IPosition outpos(1,0);
     1823    if ( spec.nelements() == m.nelements() ) {
     1824      outpos = mathutil::minMaxPos(which, ma(m));
     1825    } else {
     1826      outpos = mathutil::minMaxPos(which, ma);
     1827    }
     1828    out.push_back(outpos[0]);
    10531829  }
    10541830  return out;
     
    15712347    if ( ! (*it)->conformant(*out) ) {
    15722348      // non conformant.
    1573       pushLog(String("Warning: Can't merge scantables as header info differs."));
     2349      //pushLog(String("Warning: Can't merge scantables as header info differs."));
     2350      LogIO os( LogOrigin( "STMath", "merge()", WHERE ) ) ;
     2351      os << LogIO::SEVERE << "Can't merge scantables as header informations (any one of AntennaName, Equinox, and FluxUnit) differ." << LogIO::EXCEPTION ;
    15742352    }
    15752353    out->appendToHistoryTable((*it)->history());
     
    15932371          id = out->frequencies().addEntry(rp, rv, inc);
    15942372          freqidcol.put(k,id);
    1595           String name,fname;Double rf;
     2373          //String name,fname;Double rf;
     2374          Vector<String> name,fname;Vector<Double> rf;
    15962375          (*it)->molecules().getEntry(rf, name, fname, rec.asuInt("MOLECULE_ID"));
    15972376          id = out->molecules().addEntry(rf, name, fname);
     
    19972776      int fstart = -1;
    19982777      int fend = -1;
    1999       for (int k=0; k < flag.nelements(); ++k ) {
     2778      for (unsigned int k=0; k < flag.nelements(); ++k ) {
    20002779        if (flag[k] > 0) {
    20012780          fstart = k;
     
    20512830  return out;
    20522831}
     2832
     2833// Averaging spectra with different channel/resolution
     2834CountedPtr<Scantable>
     2835STMath::new_average( const std::vector<CountedPtr<Scantable> >& in,
     2836                     const bool& compel,
     2837                     const std::vector<bool>& mask,
     2838                     const std::string& weight,
     2839                     const std::string& avmode )
     2840  throw ( casa::AipsError )
     2841{
     2842  LogIO os( LogOrigin( "STMath", "new_average()", WHERE ) ) ;
     2843  if ( avmode == "SCAN" && in.size() != 1 )
     2844    throw(AipsError("Can't perform 'SCAN' averaging on multiple tables.\n"
     2845                    "Use merge first."));
     2846 
     2847  // check if OTF observation
     2848  String obstype = in[0]->getHeader().obstype ;
     2849  Double tol = 0.0 ;
     2850  if ( obstype.find( "OTF" ) != String::npos ) {
     2851    tol = TOL_OTF ;
     2852  }
     2853  else {
     2854    tol = TOL_POINT ;
     2855  }
     2856
     2857  CountedPtr<Scantable> out ;     // processed result
     2858  if ( compel ) {
     2859    std::vector< CountedPtr<Scantable> > newin ; // input for average process
     2860    uInt insize = in.size() ;    // number of input scantables
     2861
     2862    // TEST: do normal average in each table before IF grouping
     2863    os << "Do preliminary averaging" << LogIO::POST ;
     2864    vector< CountedPtr<Scantable> > tmpin( insize ) ;
     2865    for ( uInt itable = 0 ; itable < insize ; itable++ ) {
     2866      vector< CountedPtr<Scantable> > v( 1, in[itable] ) ;
     2867      tmpin[itable] = average( v, mask, weight, avmode ) ;
     2868    }
     2869
     2870    // warning
     2871    os << "Average spectra with different spectral resolution" << LogIO::POST ;
     2872
     2873    // temporarily set coordinfo
     2874    vector<string> oldinfo( insize ) ;
     2875    for ( uInt itable = 0 ; itable < insize ; itable++ ) {
     2876      vector<string> coordinfo = in[itable]->getCoordInfo() ;
     2877      oldinfo[itable] = coordinfo[0] ;
     2878      coordinfo[0] = "Hz" ;
     2879      tmpin[itable]->setCoordInfo( coordinfo ) ;
     2880    }
     2881
     2882    // columns
     2883    ScalarColumn<uInt> freqIDCol ;
     2884    ScalarColumn<uInt> ifnoCol ;
     2885    ScalarColumn<uInt> scannoCol ;
     2886
     2887
     2888    // check IF frequency coverage
     2889    // freqid: list of FREQ_ID, which is used, in each table 
     2890    // iffreq: list of minimum and maximum frequency for each FREQ_ID in
     2891    //         each table
     2892    // freqid[insize][numIF]
     2893    // freqid: [[id00, id01, ...],
     2894    //          [id10, id11, ...],
     2895    //          ...
     2896    //          [idn0, idn1, ...]]
     2897    // iffreq[insize][numIF*2]
     2898    // iffreq: [[min_id00, max_id00, min_id01, max_id01, ...],
     2899    //          [min_id10, max_id10, min_id11, max_id11, ...],
     2900    //          ...
     2901    //          [min_idn0, max_idn0, min_idn1, max_idn1, ...]]
     2902    //os << "Check IF settings in each table" << LogIO::POST ;
     2903    vector< vector<uInt> > freqid( insize );
     2904    vector< vector<double> > iffreq( insize ) ;
     2905    for ( uInt itable = 0 ; itable < insize ; itable++ ) {
     2906      uInt rows = tmpin[itable]->nrow() ;
     2907      uInt freqnrows = tmpin[itable]->frequencies().table().nrow() ;
     2908      for ( uInt irow = 0 ; irow < rows ; irow++ ) {
     2909        if ( freqid[itable].size() == freqnrows ) {
     2910          break ;
     2911        }
     2912        else {
     2913          freqIDCol.attach( tmpin[itable]->table(), "FREQ_ID" ) ;
     2914          ifnoCol.attach( tmpin[itable]->table(), "IFNO" ) ;
     2915          uInt id = freqIDCol( irow ) ;
     2916          if ( freqid[itable].size() == 0 || count( freqid[itable].begin(), freqid[itable].end(), id ) == 0 ) {
     2917            //os << "itable = " << itable << ": IF " << id << " is included in the list" << LogIO::POST ;
     2918            vector<double> abcissa = tmpin[itable]->getAbcissa( irow ) ;
     2919            freqid[itable].push_back( id ) ;
     2920            iffreq[itable].push_back( abcissa[0] - 0.5 * ( abcissa[1] - abcissa[0] ) ) ;
     2921            iffreq[itable].push_back( abcissa[abcissa.size()-1] + 0.5 * ( abcissa[1] - abcissa[0] ) ) ;
     2922          }
     2923        }
     2924      }
     2925    }
     2926
     2927    // debug
     2928    //os << "IF settings summary:" << endl ;
     2929    //for ( uInt i = 0 ; i < freqid.size() ; i++ ) {
     2930    //os << "   Table" << i << endl ;
     2931    //for ( uInt j = 0 ; j < freqid[i].size() ; j++ ) {
     2932    //os << "      id = " << freqid[i][j] << " (min,max) = (" << iffreq[i][2*j] << "," << iffreq[i][2*j+1] << ")" << endl ;
     2933    //}
     2934    //}
     2935    //os << endl ;
     2936    //os.post() ;
     2937
     2938    // IF grouping based on their frequency coverage
     2939    // ifgrp: list of table index and FREQ_ID for all members in each IF group
     2940    // ifgfreq: list of minimum and maximum frequency in each IF group
     2941    // ifgrp[numgrp][nummember*2]
     2942    // ifgrp: [[table00, freqrow00, table01, freqrow01, ...],
     2943    //         [table10, freqrow10, table11, freqrow11, ...],
     2944    //         ...
     2945    //         [tablen0, freqrown0, tablen1, freqrown1, ...]]
     2946    // ifgfreq[numgrp*2]
     2947    // ifgfreq: [min0_grp0, max0_grp0, min1_grp1, max1_grp1, ...]
     2948    //os << "IF grouping based on their frequency coverage" << LogIO::POST ;
     2949    vector< vector<uInt> > ifgrp ;
     2950    vector<double> ifgfreq ;
     2951
     2952    // parameter for IF grouping
     2953    // groupmode = OR    retrieve all region
     2954    //             AND   only retrieve overlaped region
     2955    //string groupmode = "AND" ;
     2956    string groupmode = "OR" ;
     2957    uInt sizecr = 0 ;
     2958    if ( groupmode == "AND" )
     2959      sizecr = 2 ;
     2960    else if ( groupmode == "OR" )
     2961      sizecr = 0 ;
     2962
     2963    vector<double> sortedfreq ;
     2964    for ( uInt i = 0 ; i < iffreq.size() ; i++ ) {
     2965      for ( uInt j = 0 ; j < iffreq[i].size() ; j++ ) {
     2966        if ( count( sortedfreq.begin(), sortedfreq.end(), iffreq[i][j] ) == 0 )
     2967          sortedfreq.push_back( iffreq[i][j] ) ;
     2968      }
     2969    }
     2970    sort( sortedfreq.begin(), sortedfreq.end() ) ;
     2971    for ( vector<double>::iterator i = sortedfreq.begin() ; i != sortedfreq.end()-1 ; i++ ) {
     2972      ifgfreq.push_back( *i ) ;
     2973      ifgfreq.push_back( *(i+1) ) ;
     2974    }
     2975    ifgrp.resize( ifgfreq.size()/2 ) ;
     2976    for ( uInt itable = 0 ; itable < insize ; itable++ ) {
     2977      for ( uInt iif = 0 ; iif < freqid[itable].size() ; iif++ ) {
     2978        double range0 = iffreq[itable][2*iif] ;
     2979        double range1 = iffreq[itable][2*iif+1] ;
     2980        for ( uInt j = 0 ; j < ifgrp.size() ; j++ ) {
     2981          double fmin = max( range0, ifgfreq[2*j] ) ;
     2982          double fmax = min( range1, ifgfreq[2*j+1] ) ;
     2983          if ( fmin < fmax ) {
     2984            ifgrp[j].push_back( itable ) ;
     2985            ifgrp[j].push_back( freqid[itable][iif] ) ;
     2986          }
     2987        }
     2988      }
     2989    }
     2990    vector< vector<uInt> >::iterator fiter = ifgrp.begin() ;
     2991    vector<double>::iterator giter = ifgfreq.begin() ;
     2992    while( fiter != ifgrp.end() ) {
     2993      if ( fiter->size() <= sizecr ) {
     2994        fiter = ifgrp.erase( fiter ) ;
     2995        giter = ifgfreq.erase( giter ) ;
     2996        giter = ifgfreq.erase( giter ) ;
     2997      }
     2998      else {
     2999        fiter++ ;
     3000        advance( giter, 2 ) ;
     3001      }
     3002    }
     3003
     3004    // Grouping continuous IF groups (without frequency gap)
     3005    // freqgrp: list of IF group indexes in each frequency group
     3006    // freqrange: list of minimum and maximum frequency in each frequency group
     3007    // freqgrp[numgrp][nummember]
     3008    // freqgrp: [[ifgrp00, ifgrp01, ifgrp02, ...],
     3009    //           [ifgrp10, ifgrp11, ifgrp12, ...],
     3010    //           ...
     3011    //           [ifgrpn0, ifgrpn1, ifgrpn2, ...]]
     3012    // freqrange[numgrp*2]
     3013    // freqrange: [min_grp0, max_grp0, min_grp1, max_grp1, ...]
     3014    vector< vector<uInt> > freqgrp ;
     3015    double freqrange = 0.0 ;
     3016    uInt grpnum = 0 ;
     3017    for ( uInt i = 0 ; i < ifgrp.size() ; i++ ) {
     3018      // Assumed that ifgfreq was sorted
     3019      if ( grpnum != 0 && freqrange == ifgfreq[2*i] ) {
     3020        freqgrp[grpnum-1].push_back( i ) ;
     3021      }
     3022      else {
     3023        vector<uInt> grp0( 1, i ) ;
     3024        freqgrp.push_back( grp0 ) ;
     3025        grpnum++ ;
     3026      }
     3027      freqrange = ifgfreq[2*i+1] ;
     3028    }
     3029       
     3030
     3031    // print IF groups
     3032    ostringstream oss ;
     3033    oss << "IF Group summary: " << endl ;
     3034    oss << "   GROUP_ID [FREQ_MIN, FREQ_MAX]: (TABLE_ID, FREQ_ID)" << endl ;
     3035    for ( uInt i = 0 ; i < ifgrp.size() ; i++ ) {
     3036      oss << "   GROUP " << setw( 2 ) << i << " [" << ifgfreq[2*i] << "," << ifgfreq[2*i+1] << "]: " ;
     3037      for ( uInt j = 0 ; j < ifgrp[i].size()/2 ; j++ ) {
     3038        oss << "(" << ifgrp[i][2*j] << "," << ifgrp[i][2*j+1] << ") " ;
     3039      }
     3040      oss << endl ;
     3041    }
     3042    oss << endl ;
     3043    os << oss.str() << LogIO::POST ;
     3044   
     3045    // print frequency group
     3046    oss.str("") ;
     3047    oss << "Frequency Group summary: " << endl ;
     3048    oss << "   GROUP_ID [FREQ_MIN, FREQ_MAX]: IF_GROUP_ID" << endl ;
     3049    for ( uInt i = 0 ; i < freqgrp.size() ; i++ ) {
     3050      oss << "   GROUP " << setw( 2 ) << i << " [" << ifgfreq[2*freqgrp[i][0]] << "," << ifgfreq[2*freqgrp[i][freqgrp[i].size()-1]+1] << "]: " ;
     3051      for ( uInt j = 0 ; j < freqgrp[i].size() ; j++ ) {
     3052        oss << freqgrp[i][j] << " " ;
     3053      }
     3054      oss << endl ;
     3055    }
     3056    oss << endl ;
     3057    os << oss.str() << LogIO::POST ;
     3058
     3059    // membership check
     3060    // groups: list of IF group indexes whose frequency range overlaps with
     3061    //         that of each table and IF
     3062    // groups[numtable][numIF][nummembership]
     3063    // groups: [[[grp, grp,...], [grp, grp,...],...],
     3064    //          [[grp, grp,...], [grp, grp,...],...],
     3065    //          ...
     3066    //          [[grp, grp,...], [grp, grp,...],...]]
     3067    vector< vector< vector<uInt> > > groups( insize ) ;
     3068    for ( uInt i = 0 ; i < insize ; i++ ) {
     3069      groups[i].resize( freqid[i].size() ) ;
     3070    }
     3071    for ( uInt igrp = 0 ; igrp < ifgrp.size() ; igrp++ ) {
     3072      for ( uInt imem = 0 ; imem < ifgrp[igrp].size()/2 ; imem++ ) {
     3073        uInt tableid = ifgrp[igrp][2*imem] ;
     3074        vector<uInt>::iterator iter = find( freqid[tableid].begin(), freqid[tableid].end(), ifgrp[igrp][2*imem+1] ) ;
     3075        if ( iter != freqid[tableid].end() ) {
     3076          uInt rowid = distance( freqid[tableid].begin(), iter ) ;
     3077          groups[tableid][rowid].push_back( igrp ) ;
     3078        }
     3079      }
     3080    }
     3081
     3082    // print membership
     3083    //oss.str("") ;
     3084    //for ( uInt i = 0 ; i < insize ; i++ ) {
     3085    //oss << "Table " << i << endl ;
     3086    //for ( uInt j = 0 ; j < groups[i].size() ; j++ ) {
     3087    //oss << "   FREQ_ID " <<  setw( 2 ) << freqid[i][j] << ": " ;
     3088    //for ( uInt k = 0 ; k < groups[i][j].size() ; k++ ) {
     3089    //oss << setw( 2 ) << groups[i][j][k] << " " ;
     3090    //}
     3091    //oss << endl ;
     3092    //}
     3093    //}
     3094    //os << oss.str() << LogIO::POST ;
     3095
     3096    // set back coordinfo
     3097    for ( uInt itable = 0 ; itable < insize ; itable++ ) {
     3098      vector<string> coordinfo = tmpin[itable]->getCoordInfo() ;
     3099      coordinfo[0] = oldinfo[itable] ;
     3100      tmpin[itable]->setCoordInfo( coordinfo ) ;
     3101    }
     3102
     3103    // Create additional table if needed
     3104    bool oldInsitu = insitu_ ;
     3105    setInsitu( false ) ;
     3106    vector< vector<uInt> > addrow( insize ) ;
     3107    vector<uInt> addtable( insize, 0 ) ;
     3108    vector<uInt> newtableids( insize ) ;
     3109    vector<uInt> newifids( insize, 0 ) ;
     3110    for ( uInt itable = 0 ; itable < insize ; itable++ ) {
     3111      //os << "Table " << itable << ": " ;
     3112      for ( uInt ifrow = 0 ; ifrow < groups[itable].size() ; ifrow++ ) {
     3113        addrow[itable].push_back( groups[itable][ifrow].size()-1 ) ;
     3114        //os << addrow[itable][ifrow] << " " ;
     3115      }
     3116      addtable[itable] = *max_element( addrow[itable].begin(), addrow[itable].end() ) ;
     3117      //os << "(" << addtable[itable] << ")" << LogIO::POST ;
     3118    }
     3119    newin.resize( insize ) ;
     3120    copy( tmpin.begin(), tmpin.end(), newin.begin() ) ;
     3121    for ( uInt i = 0 ; i < insize ; i++ ) {
     3122      newtableids[i] = i ;
     3123    }
     3124    for ( uInt itable = 0 ; itable < insize ; itable++ ) {
     3125      for ( uInt iadd = 0 ; iadd < addtable[itable] ; iadd++ ) {
     3126        CountedPtr<Scantable> add = getScantable( newin[itable], false ) ;
     3127        vector<int> freqidlist ;
     3128        for ( uInt i = 0 ; i < groups[itable].size() ; i++ ) {
     3129          if ( groups[itable][i].size() > iadd + 1 ) {
     3130            freqidlist.push_back( freqid[itable][i] ) ;
     3131          }
     3132        }
     3133        stringstream taqlstream ;
     3134        taqlstream << "SELECT FROM $1 WHERE FREQ_ID IN [" ;
     3135        for ( uInt i = 0 ; i < freqidlist.size() ; i++ ) {
     3136          taqlstream << i ;
     3137          if ( i < freqidlist.size() - 1 )
     3138            taqlstream << "," ;
     3139          else
     3140            taqlstream << "]" ;
     3141        }
     3142        string taql = taqlstream.str() ;
     3143        //os << "taql = " << taql << LogIO::POST ;
     3144        STSelector selector = STSelector() ;
     3145        selector.setTaQL( taql ) ;
     3146        add->setSelection( selector ) ;
     3147        newin.push_back( add ) ;
     3148        newtableids.push_back( itable ) ;
     3149        newifids.push_back( iadd + 1 ) ;
     3150      }
     3151    }
     3152
     3153    // udpate ifgrp
     3154    for ( uInt itable = 0 ; itable < insize ; itable++ ) {
     3155      for ( uInt iadd = 0 ; iadd < addtable[itable] ; iadd++ ) {
     3156        for ( uInt ifrow = 0 ; ifrow < groups[itable].size() ; ifrow++ ) {
     3157          if ( groups[itable][ifrow].size() > iadd + 1 ) {
     3158            uInt igrp = groups[itable][ifrow][iadd+1] ;
     3159            for ( uInt imem = 0 ; imem < ifgrp[igrp].size()/2 ; imem++ ) {
     3160              if ( ifgrp[igrp][2*imem] == newtableids[iadd+insize] && ifgrp[igrp][2*imem+1] == freqid[newtableids[iadd+insize]][ifrow] ) {
     3161                ifgrp[igrp][2*imem] = insize + iadd ;
     3162              }
     3163            }
     3164          }
     3165        }
     3166      }
     3167    }
     3168
     3169    // print IF groups again for debug
     3170    //oss.str( "" ) ;
     3171    //oss << "IF Group summary: " << endl ;
     3172    //oss << "   GROUP_ID [FREQ_MIN, FREQ_MAX]: (TABLE_ID, FREQ_ID)" << endl ;
     3173    //for ( uInt i = 0 ; i < ifgrp.size() ; i++ ) {
     3174    //oss << "   GROUP " << setw( 2 ) << i << " [" << ifgfreq[2*i] << "," << ifgfreq[2*i+1] << "]: " ;
     3175    //for ( uInt j = 0 ; j < ifgrp[i].size()/2 ; j++ ) {
     3176    //oss << "(" << ifgrp[i][2*j] << "," << ifgrp[i][2*j+1] << ") " ;
     3177    //}
     3178    //oss << endl ;
     3179    //}
     3180    //oss << endl ;
     3181    //os << oss.str() << LogIO::POST ;
     3182
     3183    // reset SCANNO and IFNO/FREQ_ID: IF is reset by the result of sortation
     3184    os << "All scan number is set to 0" << LogIO::POST ;
     3185    //os << "All IF number is set to IF group index" << LogIO::POST ;
     3186    insize = newin.size() ;
     3187    for ( uInt itable = 0 ; itable < insize ; itable++ ) {
     3188      uInt rows = newin[itable]->nrow() ;
     3189      Table &tmpt = newin[itable]->table() ;
     3190      freqIDCol.attach( tmpt, "FREQ_ID" ) ;
     3191      scannoCol.attach( tmpt, "SCANNO" ) ;
     3192      ifnoCol.attach( tmpt, "IFNO" ) ;
     3193      for ( uInt irow=0 ; irow < rows ; irow++ ) {
     3194        scannoCol.put( irow, 0 ) ;
     3195        uInt freqID = freqIDCol( irow ) ;
     3196        vector<uInt>::iterator iter = find( freqid[newtableids[itable]].begin(), freqid[newtableids[itable]].end(), freqID ) ;
     3197        if ( iter != freqid[newtableids[itable]].end() ) {
     3198          uInt index = distance( freqid[newtableids[itable]].begin(), iter ) ;
     3199          ifnoCol.put( irow, groups[newtableids[itable]][index][newifids[itable]] ) ;
     3200        }
     3201        else {
     3202          throw(AipsError("IF grouping was wrong in additional tables.")) ;
     3203        }
     3204      }
     3205    }
     3206    oldinfo.resize( insize ) ;
     3207    setInsitu( oldInsitu ) ;
     3208
     3209    // temporarily set coordinfo
     3210    for ( uInt itable = 0 ; itable < insize ; itable++ ) {
     3211      vector<string> coordinfo = newin[itable]->getCoordInfo() ;
     3212      oldinfo[itable] = coordinfo[0] ;
     3213      coordinfo[0] = "Hz" ;
     3214      newin[itable]->setCoordInfo( coordinfo ) ;
     3215    }
     3216
     3217    // save column values in the vector
     3218    vector< vector<uInt> > freqTableIdVec( insize ) ;
     3219    vector< vector<uInt> > freqIdVec( insize ) ;
     3220    vector< vector<uInt> > ifNoVec( insize ) ;
     3221    for ( uInt itable = 0 ; itable < insize ; itable++ ) {
     3222      ScalarColumn<uInt> freqIDs ;
     3223      freqIDs.attach( newin[itable]->frequencies().table(), "ID" ) ;
     3224      ifnoCol.attach( newin[itable]->table(), "IFNO" ) ;
     3225      freqIDCol.attach( newin[itable]->table(), "FREQ_ID" ) ;
     3226      for ( uInt irow = 0 ; irow < newin[itable]->frequencies().table().nrow() ; irow++ ) {
     3227        freqTableIdVec[itable].push_back( freqIDs( irow ) ) ;
     3228      }
     3229      for ( uInt irow = 0 ; irow < newin[itable]->table().nrow() ; irow++ ) {
     3230        freqIdVec[itable].push_back( freqIDCol( irow ) ) ;
     3231        ifNoVec[itable].push_back( ifnoCol( irow ) ) ;
     3232      }
     3233    }
     3234
     3235    // reset spectra and flagtra: pick up common part of frequency coverage
     3236    //os << "Pick common frequency range and align resolution" << LogIO::POST ;
     3237    for ( uInt itable = 0 ; itable < insize ; itable++ ) {
     3238      uInt rows = newin[itable]->nrow() ;
     3239      int nminchan = -1 ;
     3240      int nmaxchan = -1 ;
     3241      vector<uInt> freqIdUpdate ;
     3242      for ( uInt irow = 0 ; irow < rows ; irow++ ) {
     3243        uInt ifno = ifNoVec[itable][irow] ;  // IFNO is reset by group index
     3244        double minfreq = ifgfreq[2*ifno] ;
     3245        double maxfreq = ifgfreq[2*ifno+1] ;
     3246        //os << "frequency range: [" << minfreq << "," << maxfreq << "]" << LogIO::POST ;
     3247        vector<double> abcissa = newin[itable]->getAbcissa( irow ) ;
     3248        int nchan = abcissa.size() ;
     3249        double resol = abcissa[1] - abcissa[0] ;
     3250        //os << "abcissa range  : [" << abcissa[0] << "," << abcissa[nchan-1] << "]" << LogIO::POST ;
     3251        if ( minfreq <= abcissa[0] )
     3252          nminchan = 0 ;
     3253        else {
     3254          //double cfreq = ( minfreq - abcissa[0] ) / resol ;
     3255          double cfreq = ( minfreq - abcissa[0] + 0.5 * resol ) / resol ;
     3256          nminchan = int(cfreq) + ( ( cfreq - int(cfreq) <= 0.5 ) ? 0 : 1 ) ;
     3257        }
     3258        if ( maxfreq >= abcissa[abcissa.size()-1] )
     3259          nmaxchan = abcissa.size() - 1 ;
     3260        else {
     3261          //double cfreq = ( abcissa[abcissa.size()-1] - maxfreq ) / resol ;
     3262          double cfreq = ( abcissa[abcissa.size()-1] - maxfreq + 0.5 * resol ) / resol ;
     3263          nmaxchan = abcissa.size() - 1 - int(cfreq) - ( ( cfreq - int(cfreq) >= 0.5 ) ? 1 : 0 ) ;
     3264        }
     3265        //os << "channel range (" << irow << "): [" << nminchan << "," << nmaxchan << "]" << LogIO::POST ;
     3266        if ( nmaxchan > nminchan ) {
     3267          newin[itable]->reshapeSpectrum( nminchan, nmaxchan, irow ) ;
     3268          int newchan = nmaxchan - nminchan + 1 ;
     3269          if ( count( freqIdUpdate.begin(), freqIdUpdate.end(), freqIdVec[itable][irow] ) == 0 && newchan < nchan )
     3270            freqIdUpdate.push_back( freqIdVec[itable][irow] ) ;
     3271        }
     3272        else {
     3273          throw(AipsError("Failed to pick up common part of frequency range.")) ;
     3274        }
     3275      }
     3276      for ( uInt i = 0 ; i < freqIdUpdate.size() ; i++ ) {
     3277        uInt freqId = freqIdUpdate[i] ;
     3278        Double refpix ;
     3279        Double refval ;
     3280        Double increment ;
     3281       
     3282        // update row
     3283        newin[itable]->frequencies().getEntry( refpix, refval, increment, freqId ) ;
     3284        refval = refval - ( refpix - nminchan ) * increment ;
     3285        refpix = 0 ;
     3286        newin[itable]->frequencies().setEntry( refpix, refval, increment, freqId ) ;
     3287      }   
     3288    }
     3289
     3290   
     3291    // reset spectra and flagtra: align spectral resolution
     3292    //os << "Align spectral resolution" << LogIO::POST ;
     3293    // gmaxdnu: the coarsest frequency resolution in the frequency group
     3294    // gmemid: member index that have a resolution equal to gmaxdnu
     3295    // gmaxdnu[numfreqgrp]
     3296    // gmaxdnu: [dnu0, dnu1, ...]
     3297    // gmemid[numfreqgrp]
     3298    // gmemid: [id0, id1, ...]
     3299    vector<double> gmaxdnu( freqgrp.size(), 0.0 ) ;
     3300    vector<uInt> gmemid( freqgrp.size(), 0 ) ;
     3301    for ( uInt igrp = 0 ; igrp < ifgrp.size() ; igrp++ ) {
     3302      double maxdnu = 0.0 ;       // maximum (coarsest) frequency resolution
     3303      int minchan = INT_MAX ;     // minimum channel number
     3304      Double refpixref = -1 ;     // reference of 'reference pixel'
     3305      Double refvalref = -1 ;     // reference of 'reference frequency'
     3306      Double refinc = -1 ;        // reference frequency resolution
     3307      uInt refreqid ;
     3308      uInt reftable = INT_MAX;
     3309      // process only if group member > 1
     3310      if ( ifgrp[igrp].size() > 2 ) {
     3311        // find minchan and maxdnu in each group
     3312        for ( uInt imem = 0 ; imem < ifgrp[igrp].size()/2 ; imem++ ) {
     3313          uInt tableid = ifgrp[igrp][2*imem] ;
     3314          uInt rowid = ifgrp[igrp][2*imem+1] ;
     3315          vector<uInt>::iterator iter = find( freqIdVec[tableid].begin(), freqIdVec[tableid].end(), rowid ) ;
     3316          if ( iter != freqIdVec[tableid].end() ) {
     3317            uInt index = distance( freqIdVec[tableid].begin(), iter ) ;
     3318            vector<double> abcissa = newin[tableid]->getAbcissa( index ) ;
     3319            int nchan = abcissa.size() ;
     3320            double dnu = abcissa[1] - abcissa[0] ;
     3321            //os << "GROUP " << igrp << " (" << tableid << "," << rowid << "): nchan = " << nchan << " (minchan = " << minchan << ")" << LogIO::POST ;
     3322            if ( nchan < minchan ) {
     3323              minchan = nchan ;
     3324              maxdnu = dnu ;
     3325              newin[tableid]->frequencies().getEntry( refpixref, refvalref, refinc, rowid ) ;
     3326              refreqid = rowid ;
     3327              reftable = tableid ;
     3328            }
     3329          }
     3330        }
     3331        // regrid spectra in each group
     3332        os << "GROUP " << igrp << endl ;
     3333        os << "   Channel number is adjusted to " << minchan << endl ;
     3334        os << "   Corresponding frequency resolution is " << maxdnu << "Hz" << LogIO::POST ;
     3335        for ( uInt imem = 0 ; imem < ifgrp[igrp].size()/2 ; imem++ ) {
     3336          uInt tableid = ifgrp[igrp][2*imem] ;
     3337          uInt rowid = ifgrp[igrp][2*imem+1] ;
     3338          freqIDCol.attach( newin[tableid]->table(), "FREQ_ID" ) ;
     3339          //os << "tableid = " << tableid << " rowid = " << rowid << ": " << LogIO::POST ;
     3340          //os << "   regridChannel applied to " ;
     3341          if ( tableid != reftable )
     3342            refreqid = newin[tableid]->frequencies().addEntry( refpixref, refvalref, refinc ) ;
     3343          for ( uInt irow = 0 ; irow < newin[tableid]->table().nrow() ; irow++ ) {
     3344            uInt tfreqid = freqIdVec[tableid][irow] ;
     3345            if ( tfreqid == rowid ) {     
     3346              //os << irow << " " ;
     3347              newin[tableid]->regridChannel( minchan, maxdnu, irow ) ;
     3348              freqIDCol.put( irow, refreqid ) ;
     3349              freqIdVec[tableid][irow] = refreqid ;
     3350            }
     3351          }
     3352          //os << LogIO::POST ;
     3353        }
     3354      }
     3355      else {
     3356        uInt tableid = ifgrp[igrp][0] ;
     3357        uInt rowid = ifgrp[igrp][1] ;
     3358        vector<uInt>::iterator iter = find( freqIdVec[tableid].begin(), freqIdVec[tableid].end(), rowid ) ;
     3359        if ( iter != freqIdVec[tableid].end() ) {
     3360          uInt index = distance( freqIdVec[tableid].begin(), iter ) ;
     3361          vector<double> abcissa = newin[tableid]->getAbcissa( index ) ;
     3362          minchan = abcissa.size() ;
     3363          maxdnu = abcissa[1] - abcissa[0] ;
     3364        }
     3365      }
     3366      for ( uInt i = 0 ; i < freqgrp.size() ; i++ ) {
     3367        if ( count( freqgrp[i].begin(), freqgrp[i].end(), igrp ) > 0 ) {
     3368          if ( maxdnu > gmaxdnu[i] ) {
     3369            gmaxdnu[i] = maxdnu ;
     3370            gmemid[i] = igrp ;
     3371          }
     3372          break ;
     3373        }
     3374      }
     3375    }
     3376
     3377    // set back coordinfo
     3378    for ( uInt itable = 0 ; itable < insize ; itable++ ) {
     3379      vector<string> coordinfo = newin[itable]->getCoordInfo() ;
     3380      coordinfo[0] = oldinfo[itable] ;
     3381      newin[itable]->setCoordInfo( coordinfo ) ;
     3382    }     
     3383
     3384    // accumulate all rows into the first table
     3385    // NOTE: assumed in.size() = 1
     3386    vector< CountedPtr<Scantable> > tmp( 1 ) ;
     3387    if ( newin.size() == 1 )
     3388      tmp[0] = newin[0] ;
     3389    else
     3390      tmp[0] = merge( newin ) ;
     3391
     3392    //return tmp[0] ;
     3393
     3394    // average
     3395    CountedPtr<Scantable> tmpout = average( tmp, mask, weight, avmode ) ;
     3396
     3397    //return tmpout ;
     3398
     3399    // combine frequency group
     3400    os << "Combine spectra based on frequency grouping" << LogIO::POST ;
     3401    os << "IFNO is renumbered as frequency group ID (see above)" << LogIO::POST ;
     3402    vector<string> coordinfo = tmpout->getCoordInfo() ;
     3403    oldinfo[0] = coordinfo[0] ;
     3404    coordinfo[0] = "Hz" ;
     3405    tmpout->setCoordInfo( coordinfo ) ;
     3406    // create proformas of output table
     3407    stringstream taqlstream ;
     3408    taqlstream << "SELECT FROM $1 WHERE IFNO IN [" ;
     3409    for ( uInt i = 0 ; i < gmemid.size() ; i++ ) {
     3410      taqlstream << gmemid[i] ;
     3411      if ( i < gmemid.size() - 1 )
     3412        taqlstream << "," ;
     3413      else
     3414        taqlstream << "]" ;
     3415    }
     3416    string taql = taqlstream.str() ;
     3417    //os << "taql = " << taql << LogIO::POST ;
     3418    STSelector selector = STSelector() ;
     3419    selector.setTaQL( taql ) ;
     3420    oldInsitu = insitu_ ;
     3421    setInsitu( false ) ;
     3422    out = getScantable( tmpout, false ) ;
     3423    setInsitu( oldInsitu ) ;
     3424    out->setSelection( selector ) ;
     3425    // regrid rows
     3426    ifnoCol.attach( tmpout->table(), "IFNO" ) ;
     3427    for ( uInt irow = 0 ; irow < tmpout->table().nrow() ; irow++ ) {
     3428      uInt ifno = ifnoCol( irow ) ;
     3429      for ( uInt igrp = 0 ; igrp < freqgrp.size() ; igrp++ ) {
     3430        if ( count( freqgrp[igrp].begin(), freqgrp[igrp].end(), ifno ) > 0 ) {
     3431          vector<double> abcissa = tmpout->getAbcissa( irow ) ;
     3432          double bw = ( abcissa[1] - abcissa[0] ) * abcissa.size() ;
     3433          int nchan = (int)( bw / gmaxdnu[igrp] ) ;
     3434          tmpout->regridChannel( nchan, gmaxdnu[igrp], irow ) ;
     3435          break ;
     3436        }
     3437      }
     3438    }
     3439    // combine spectra
     3440    ArrayColumn<Float> specColOut ;
     3441    specColOut.attach( out->table(), "SPECTRA" ) ;
     3442    ArrayColumn<uChar> flagColOut ;
     3443    flagColOut.attach( out->table(), "FLAGTRA" ) ;
     3444    ScalarColumn<uInt> ifnoColOut ;
     3445    ifnoColOut.attach( out->table(), "IFNO" ) ;
     3446    ScalarColumn<uInt> polnoColOut ;
     3447    polnoColOut.attach( out->table(), "POLNO" ) ;
     3448    ScalarColumn<uInt> freqidColOut ;
     3449    freqidColOut.attach( out->table(), "FREQ_ID" ) ;
     3450    MDirection::ScalarColumn dirColOut ;
     3451    dirColOut.attach( out->table(), "DIRECTION" ) ;
     3452    Table &tab = tmpout->table() ;
     3453    Block<String> cols(1);
     3454    cols[0] = String("POLNO") ;
     3455    TableIterator iter( tab, cols ) ;
     3456    bool done = false ;
     3457    vector< vector<uInt> > sizes( freqgrp.size() ) ;
     3458    while( !iter.pastEnd() ) {
     3459      vector< vector<Float> > specout( freqgrp.size() ) ;
     3460      vector< vector<uChar> > flagout( freqgrp.size() ) ;
     3461      ArrayColumn<Float> specCols ;
     3462      specCols.attach( iter.table(), "SPECTRA" ) ;
     3463      ArrayColumn<uChar> flagCols ;
     3464      flagCols.attach( iter.table(), "FLAGTRA" ) ;
     3465      ifnoCol.attach( iter.table(), "IFNO" ) ;
     3466      ScalarColumn<uInt> polnos ;
     3467      polnos.attach( iter.table(), "POLNO" ) ;
     3468      MDirection::ScalarColumn dircol ;
     3469      dircol.attach( iter.table(), "DIRECTION" ) ;
     3470      uInt polno = polnos( 0 ) ;
     3471      //os << "POLNO iteration: " << polno << LogIO::POST ;
     3472//       for ( uInt igrp = 0 ; igrp < freqgrp.size() ; igrp++ ) {
     3473//      sizes[igrp].resize( freqgrp[igrp].size() ) ;
     3474//      for ( uInt imem = 0 ; imem < freqgrp[igrp].size() ; imem++ ) {
     3475//        for ( uInt irow = 0 ; irow < iter.table().nrow() ; irow++ ) {
     3476//          uInt ifno = ifnoCol( irow ) ;
     3477//          if ( ifno == freqgrp[igrp][imem] ) {
     3478//            Vector<Float> spec = specCols( irow ) ;
     3479//            Vector<uChar> flag = flagCols( irow ) ;
     3480//            vector<Float> svec ;
     3481//            spec.tovector( svec ) ;
     3482//            vector<uChar> fvec ;
     3483//            flag.tovector( fvec ) ;
     3484//            //os << "spec.size() = " << svec.size() << " fvec.size() = " << fvec.size() << LogIO::POST ;
     3485//            specout[igrp].insert( specout[igrp].end(), svec.begin(), svec.end() ) ;
     3486//            flagout[igrp].insert( flagout[igrp].end(), fvec.begin(), fvec.end() ) ;
     3487//            //os << "specout[" << igrp << "].size() = " << specout[igrp].size() << LogIO::POST ;
     3488//            sizes[igrp][imem] = spec.nelements() ;
     3489//          }
     3490//        }
     3491//      }
     3492//      for ( uInt irow = 0 ; irow < out->table().nrow() ; irow++ ) {
     3493//        uInt ifout = ifnoColOut( irow ) ;
     3494//        uInt polout = polnoColOut( irow ) ;
     3495//        if ( ifout == gmemid[igrp] && polout == polno ) {
     3496//          // set SPECTRA and FRAGTRA
     3497//          Vector<Float> newspec( specout[igrp] ) ;
     3498//          Vector<uChar> newflag( flagout[igrp] ) ;
     3499//          specColOut.put( irow, newspec ) ;
     3500//          flagColOut.put( irow, newflag ) ;
     3501//          // IFNO renumbering
     3502//          ifnoColOut.put( irow, igrp ) ;
     3503//        }
     3504//      }
     3505//       }
     3506      // get a list of number of channels for each frequency group member
     3507      if ( !done ) {
     3508        for ( uInt igrp = 0 ; igrp < freqgrp.size() ; igrp++ ) {
     3509          sizes[igrp].resize( freqgrp[igrp].size() ) ;
     3510          for ( uInt imem = 0 ; imem < freqgrp[igrp].size() ; imem++ ) {
     3511            for ( uInt irow = 0 ; irow < iter.table().nrow() ; irow++ ) {
     3512              uInt ifno = ifnoCol( irow ) ;
     3513              if ( ifno == freqgrp[igrp][imem] ) {
     3514                Vector<Float> spec = specCols( irow ) ;
     3515                sizes[igrp][imem] = spec.nelements() ;
     3516                break ;
     3517              }               
     3518            }
     3519          }
     3520        }
     3521        done = true ;
     3522      }
     3523      // combine spectra
     3524      for ( uInt irow = 0 ; irow < out->table().nrow() ; irow++ ) {
     3525        uInt polout = polnoColOut( irow ) ;
     3526        if ( polout == polno ) {
     3527          uInt ifout = ifnoColOut( irow ) ;
     3528          Vector<Double> direction = dirColOut(irow).getAngle(Unit(String("rad"))).getValue() ;
     3529          uInt igrp ;
     3530          for ( uInt jgrp = 0 ; jgrp < freqgrp.size() ; jgrp++ ) {
     3531            if ( ifout == gmemid[jgrp] ) {
     3532              igrp = jgrp ;
     3533              break ;
     3534            }
     3535          }
     3536          for ( uInt imem = 0 ; imem < freqgrp[igrp].size() ; imem++ ) {
     3537            for ( uInt jrow = 0 ; jrow < iter.table().nrow() ; jrow++ ) {
     3538              uInt ifno = ifnoCol( jrow ) ;
     3539              Vector<Double> tdir = dircol(jrow).getAngle(Unit(String("rad"))).getValue() ;
     3540              //if ( ifno == freqgrp[igrp][imem] && allTrue( tdir == direction  ) ) {
     3541              Double dx = tdir[0] - direction[0] ;
     3542              Double dy = tdir[1] - direction[1] ;
     3543              Double dd = sqrt( dx * dx + dy * dy ) ;
     3544              //if ( ifno == freqgrp[igrp][imem] && allNearAbs( tdir, direction, tol ) ) {
     3545              if ( ifno == freqgrp[igrp][imem] && dd <= tol ) {
     3546                Vector<Float> spec = specCols( jrow ) ;
     3547                Vector<uChar> flag = flagCols( jrow ) ;
     3548                vector<Float> svec ;
     3549                spec.tovector( svec ) ;
     3550                vector<uChar> fvec ;
     3551                flag.tovector( fvec ) ;
     3552                //os << "spec.size() = " << svec.size() << " fvec.size() = " << fvec.size() << LogIO::POST ;
     3553                specout[igrp].insert( specout[igrp].end(), svec.begin(), svec.end() ) ;
     3554                flagout[igrp].insert( flagout[igrp].end(), fvec.begin(), fvec.end() ) ;
     3555                //os << "specout[" << igrp << "].size() = " << specout[igrp].size() << LogIO::POST ;
     3556              }
     3557            }
     3558          }
     3559          // set SPECTRA and FRAGTRA
     3560          Vector<Float> newspec( specout[igrp] ) ;
     3561          Vector<uChar> newflag( flagout[igrp] ) ;
     3562          specColOut.put( irow, newspec ) ;
     3563          flagColOut.put( irow, newflag ) ;
     3564          // IFNO renumbering
     3565          ifnoColOut.put( irow, igrp ) ;
     3566        }
     3567      }
     3568      iter++ ;
     3569    }
     3570    // update FREQUENCIES subtable
     3571    vector<bool> updated( freqgrp.size(), false ) ;
     3572    for ( uInt igrp = 0 ; igrp < freqgrp.size() ; igrp++ ) {
     3573      uInt index = 0 ;
     3574      uInt pixShift = 0 ;
     3575      while ( freqgrp[igrp][index] != gmemid[igrp] ) {
     3576        pixShift += sizes[igrp][index++] ;
     3577      }
     3578      for ( uInt irow = 0 ; irow < out->table().nrow() ; irow++ ) {
     3579        if ( ifnoColOut( irow ) == gmemid[igrp] && !updated[igrp] ) {
     3580          uInt freqidOut = freqidColOut( irow ) ;
     3581          //os << "freqgrp " << igrp << " freqidOut = " << freqidOut << LogIO::POST ;
     3582          double refpix ;
     3583          double refval ;
     3584          double increm ;
     3585          out->frequencies().getEntry( refpix, refval, increm, freqidOut ) ;
     3586          refpix += pixShift ;
     3587          out->frequencies().setEntry( refpix, refval, increm, freqidOut ) ;
     3588          updated[igrp] = true ;
     3589        }
     3590      }
     3591    }
     3592
     3593    //out = tmpout ;
     3594
     3595    coordinfo = tmpout->getCoordInfo() ;
     3596    coordinfo[0] = oldinfo[0] ;
     3597    tmpout->setCoordInfo( coordinfo ) ;
     3598  }
     3599  else {
     3600    // simple average
     3601    out =  average( in, mask, weight, avmode ) ;
     3602  }
     3603 
     3604  return out ;
     3605}
     3606
     3607CountedPtr<Scantable> STMath::cwcal( const CountedPtr<Scantable>& s,
     3608                                     const String calmode,
     3609                                     const String antname )
     3610{
     3611  // frequency switch
     3612  if ( calmode == "fs" ) {
     3613    return cwcalfs( s, antname ) ;
     3614  }
     3615  else {
     3616    vector<bool> masks = s->getMask( 0 ) ;
     3617    vector<int> types ;
     3618
     3619    // sky scan
     3620    STSelector sel = STSelector() ;
     3621    types.push_back( SrcType::SKY ) ;
     3622    sel.setTypes( types ) ;
     3623    s->setSelection( sel ) ;
     3624    vector< CountedPtr<Scantable> > tmp( 1, getScantable( s, false ) ) ;
     3625    CountedPtr<Scantable> asky = average( tmp, masks, "TINT", "SCAN" ) ;
     3626    s->unsetSelection() ;
     3627    sel.reset() ;
     3628    types.clear() ;
     3629
     3630    // hot scan
     3631    types.push_back( SrcType::HOT ) ;
     3632    sel.setTypes( types ) ;
     3633    s->setSelection( sel ) ;
     3634    tmp.clear() ;
     3635    tmp.push_back( getScantable( s, false ) ) ;
     3636    CountedPtr<Scantable> ahot = average( tmp, masks, "TINT", "SCAN" ) ;
     3637    s->unsetSelection() ;
     3638    sel.reset() ;
     3639    types.clear() ;
     3640   
     3641    // cold scan
     3642    CountedPtr<Scantable> acold ;
     3643//     types.push_back( SrcType::COLD ) ;
     3644//     sel.setTypes( types ) ;
     3645//     s->setSelection( sel ) ;
     3646//     tmp.clear() ;
     3647//     tmp.push_back( getScantable( s, false ) ) ;
     3648//     CountedPtr<Scantable> acold = average( tmp, masks, "TINT", "SCNAN" ) ;
     3649//     s->unsetSelection() ;
     3650//     sel.reset() ;
     3651//     types.clear() ;
     3652
     3653    // off scan
     3654    types.push_back( SrcType::PSOFF ) ;
     3655    sel.setTypes( types ) ;
     3656    s->setSelection( sel ) ;
     3657    tmp.clear() ;
     3658    tmp.push_back( getScantable( s, false ) ) ;
     3659    CountedPtr<Scantable> aoff = average( tmp, masks, "TINT", "SCAN" ) ;
     3660    s->unsetSelection() ;
     3661    sel.reset() ;
     3662    types.clear() ;
     3663   
     3664    // on scan
     3665    bool insitu = insitu_ ;
     3666    insitu_ = false ;
     3667    CountedPtr<Scantable> out = getScantable( s, true ) ;
     3668    insitu_ = insitu ;
     3669    types.push_back( SrcType::PSON ) ;
     3670    sel.setTypes( types ) ;
     3671    s->setSelection( sel ) ;
     3672    TableCopy::copyRows( out->table(), s->table() ) ;
     3673    s->unsetSelection() ;
     3674    sel.reset() ;
     3675    types.clear() ;
     3676   
     3677    // process each on scan
     3678    ArrayColumn<Float> tsysCol ;
     3679    tsysCol.attach( out->table(), "TSYS" ) ;
     3680    for ( int i = 0 ; i < out->nrow() ; i++ ) {
     3681      vector<float> sp = getCalibratedSpectra( out, aoff, asky, ahot, acold, i, antname ) ;
     3682      out->setSpectrum( sp, i ) ;
     3683      string reftime = out->getTime( i ) ;
     3684      vector<int> ii( 1, out->getIF( i ) ) ;
     3685      vector<int> ib( 1, out->getBeam( i ) ) ;
     3686      vector<int> ip( 1, out->getPol( i ) ) ;
     3687      sel.setIFs( ii ) ;
     3688      sel.setBeams( ib ) ;
     3689      sel.setPolarizations( ip ) ;
     3690      asky->setSelection( sel ) ;   
     3691      vector<float> sptsys = getTsysFromTime( reftime, asky, "linear" ) ;
     3692      const Vector<Float> Vtsys( sptsys ) ;
     3693      tsysCol.put( i, Vtsys ) ;
     3694      asky->unsetSelection() ;
     3695      sel.reset() ;
     3696    }
     3697
     3698    // flux unit
     3699    out->setFluxUnit( "K" ) ;
     3700
     3701    return out ;
     3702  }
     3703}
     3704 
     3705CountedPtr<Scantable> STMath::almacal( const CountedPtr<Scantable>& s,
     3706                                       const String calmode )
     3707{
     3708  // frequency switch
     3709  if ( calmode == "fs" ) {
     3710    return almacalfs( s ) ;
     3711  }
     3712  else {
     3713    vector<bool> masks = s->getMask( 0 ) ;
     3714   
     3715    // off scan
     3716    STSelector sel = STSelector() ;
     3717    vector<int> types ;
     3718    types.push_back( SrcType::PSOFF ) ;
     3719    sel.setTypes( types ) ;
     3720    s->setSelection( sel ) ;
     3721    // TODO 2010/01/08 TN
     3722    // Grouping by time should be needed before averaging.
     3723    // Each group must have own unique SCANNO (should be renumbered).
     3724    // See PIPELINE/SDCalibration.py
     3725    CountedPtr<Scantable> soff = getScantable( s, false ) ;
     3726    Table ttab = soff->table() ;
     3727    ROScalarColumn<Double> timeCol( ttab, "TIME" ) ;
     3728    uInt nrow = timeCol.nrow() ;
     3729    Vector<Double> timeSep( nrow - 1 ) ;
     3730    for ( uInt i = 0 ; i < nrow - 1 ; i++ ) {
     3731      timeSep[i] = timeCol(i+1) - timeCol(i) ;
     3732    }
     3733    ScalarColumn<Double> intervalCol( ttab, "INTERVAL" ) ;
     3734    Vector<Double> interval = intervalCol.getColumn() ;
     3735    interval /= 86400.0 ;
     3736    ScalarColumn<uInt> scanCol( ttab, "SCANNO" ) ;
     3737    vector<uInt> glist ;
     3738    for ( uInt i = 0 ; i < nrow - 1 ; i++ ) {
     3739      double gap = 2.0 * timeSep[i] / ( interval[i] + interval[i+1] ) ;
     3740      //cout << "gap[" << i << "]=" << setw(5) << gap << endl ;
     3741      if ( gap > 1.1 ) {
     3742        glist.push_back( i ) ;
     3743      }
     3744    }
     3745    Vector<uInt> gaplist( glist ) ;
     3746    //cout << "gaplist = " << gaplist << endl ;
     3747    uInt newid = 0 ;
     3748    for ( uInt i = 0 ; i < nrow ; i++ ) {
     3749      scanCol.put( i, newid ) ;
     3750      if ( i == gaplist[newid] ) {
     3751        newid++ ;
     3752      }
     3753    }
     3754    //cout << "new scancol = " << scanCol.getColumn() << endl ;
     3755    vector< CountedPtr<Scantable> > tmp( 1, soff ) ;
     3756    CountedPtr<Scantable> aoff = average( tmp, masks, "TINT", "SCAN" ) ;
     3757    //cout << "aoff.nrow = " << aoff->nrow() << endl ;
     3758    s->unsetSelection() ;
     3759    sel.reset() ;
     3760    types.clear() ;
     3761   
     3762    // on scan
     3763    bool insitu = insitu_ ;
     3764    insitu_ = false ;
     3765    CountedPtr<Scantable> out = getScantable( s, true ) ;
     3766    insitu_ = insitu ;
     3767    types.push_back( SrcType::PSON ) ;
     3768    sel.setTypes( types ) ;
     3769    s->setSelection( sel ) ;
     3770    TableCopy::copyRows( out->table(), s->table() ) ;
     3771    s->unsetSelection() ;
     3772    sel.reset() ;
     3773    types.clear() ;
     3774   
     3775    // process each on scan
     3776    ArrayColumn<Float> tsysCol ;
     3777    tsysCol.attach( out->table(), "TSYS" ) ;
     3778    for ( int i = 0 ; i < out->nrow() ; i++ ) {
     3779      vector<float> sp = getCalibratedSpectra( out, aoff, i ) ;
     3780      out->setSpectrum( sp, i ) ;
     3781    }
     3782
     3783    // flux unit
     3784    out->setFluxUnit( "K" ) ;
     3785
     3786    return out ;
     3787  }
     3788}
     3789
     3790CountedPtr<Scantable> STMath::cwcalfs( const CountedPtr<Scantable>& s,
     3791                                       const String antname )
     3792{
     3793  vector<int> types ;
     3794
     3795  // APEX calibration mode
     3796  int apexcalmode = 1 ;
     3797 
     3798  if ( antname.find( "APEX" ) != string::npos ) {
     3799    // check if off scan exists or not
     3800    STSelector sel = STSelector() ;
     3801    //sel.setName( offstr1 ) ;
     3802    types.push_back( SrcType::FLOOFF ) ;
     3803    sel.setTypes( types ) ;
     3804    try {
     3805      s->setSelection( sel ) ;
     3806    }
     3807    catch ( AipsError &e ) {
     3808      apexcalmode = 0 ;
     3809    }
     3810    sel.reset() ;
     3811  }
     3812  s->unsetSelection() ;
     3813  types.clear() ;
     3814
     3815  vector<bool> masks = s->getMask( 0 ) ;
     3816  CountedPtr<Scantable> ssig, sref ;
     3817  CountedPtr<Scantable> out ;
     3818
     3819  if ( antname.find( "APEX" ) != string::npos ) {
     3820    // APEX calibration
     3821    // sky scan
     3822    STSelector sel = STSelector() ;
     3823    types.push_back( SrcType::FLOSKY ) ;
     3824    sel.setTypes( types ) ;
     3825    s->setSelection( sel ) ;
     3826    vector< CountedPtr<Scantable> > tmp( 1, getScantable( s, false ) ) ;
     3827    CountedPtr<Scantable> askylo = average( tmp, masks, "TINT", "SCAN" ) ;
     3828    s->unsetSelection() ;
     3829    sel.reset() ;
     3830    types.clear() ;
     3831    types.push_back( SrcType::FHISKY ) ;
     3832    sel.setTypes( types ) ;
     3833    s->setSelection( sel ) ;
     3834    tmp.clear() ;
     3835    tmp.push_back( getScantable( s, false ) ) ;
     3836    CountedPtr<Scantable> askyhi = average( tmp, masks, "TINT", "SCAN" ) ;
     3837    s->unsetSelection() ;
     3838    sel.reset() ;
     3839    types.clear() ;
     3840   
     3841    // hot scan
     3842    types.push_back( SrcType::FLOHOT ) ;
     3843    sel.setTypes( types ) ;
     3844    s->setSelection( sel ) ;
     3845    tmp.clear() ;
     3846    tmp.push_back( getScantable( s, false ) ) ;
     3847    CountedPtr<Scantable> ahotlo = average( tmp, masks, "TINT", "SCAN" ) ;
     3848    s->unsetSelection() ;
     3849    sel.reset() ;
     3850    types.clear() ;
     3851    types.push_back( SrcType::FHIHOT ) ;
     3852    sel.setTypes( types ) ;
     3853    s->setSelection( sel ) ;
     3854    tmp.clear() ;
     3855    tmp.push_back( getScantable( s, false ) ) ;
     3856    CountedPtr<Scantable> ahothi = average( tmp, masks, "TINT", "SCAN" ) ;
     3857    s->unsetSelection() ;
     3858    sel.reset() ;
     3859    types.clear() ;
     3860   
     3861    // cold scan
     3862    CountedPtr<Scantable> acoldlo, acoldhi ;
     3863//     types.push_back( SrcType::FLOCOLD ) ;
     3864//     sel.setTypes( types ) ;
     3865//     s->setSelection( sel ) ;
     3866//     tmp.clear() ;
     3867//     tmp.push_back( getScantable( s, false ) ) ;
     3868//     CountedPtr<Scantable> acoldlo = average( tmp, masks, "TINT", "SCAN" ) ;
     3869//     s->unsetSelection() ;
     3870//     sel.reset() ;
     3871//     types.clear() ;
     3872//     types.push_back( SrcType::FHICOLD ) ;
     3873//     sel.setTypes( types ) ;
     3874//     s->setSelection( sel ) ;
     3875//     tmp.clear() ;
     3876//     tmp.push_back( getScantable( s, false ) ) ;
     3877//     CountedPtr<Scantable> acoldhi = average( tmp, masks, "TINT", "SCAN" ) ;
     3878//     s->unsetSelection() ;
     3879//     sel.reset() ;
     3880//     types.clear() ;
     3881
     3882    // ref scan
     3883    bool insitu = insitu_ ;
     3884    insitu_ = false ;
     3885    sref = getScantable( s, true ) ;
     3886    insitu_ = insitu ;
     3887    types.push_back( SrcType::FSLO ) ;
     3888    sel.setTypes( types ) ;
     3889    s->setSelection( sel ) ;
     3890    TableCopy::copyRows( sref->table(), s->table() ) ;
     3891    s->unsetSelection() ;
     3892    sel.reset() ;
     3893    types.clear() ;
     3894   
     3895    // sig scan
     3896    insitu_ = false ;
     3897    ssig = getScantable( s, true ) ;
     3898    insitu_ = insitu ;
     3899    types.push_back( SrcType::FSHI ) ;
     3900    sel.setTypes( types ) ;
     3901    s->setSelection( sel ) ;
     3902    TableCopy::copyRows( ssig->table(), s->table() ) ;
     3903    s->unsetSelection() ;
     3904    sel.reset() ; 
     3905    types.clear() ;
     3906         
     3907    if ( apexcalmode == 0 ) {
     3908      // APEX fs data without off scan
     3909      // process each sig and ref scan
     3910      ArrayColumn<Float> tsysCollo ;
     3911      tsysCollo.attach( ssig->table(), "TSYS" ) ;
     3912      ArrayColumn<Float> tsysColhi ;
     3913      tsysColhi.attach( sref->table(), "TSYS" ) ;
     3914      for ( int i = 0 ; i < ssig->nrow() ; i++ ) {
     3915        vector< CountedPtr<Scantable> > sky( 2 ) ;
     3916        sky[0] = askylo ;
     3917        sky[1] = askyhi ;
     3918        vector< CountedPtr<Scantable> > hot( 2 ) ;
     3919        hot[0] = ahotlo ;
     3920        hot[1] = ahothi ;
     3921        vector< CountedPtr<Scantable> > cold( 2 ) ;
     3922        //cold[0] = acoldlo ;
     3923        //cold[1] = acoldhi ;
     3924        vector<float> sp = getFSCalibratedSpectra( ssig, sref, sky, hot, cold, i ) ;
     3925        ssig->setSpectrum( sp, i ) ;
     3926        string reftime = ssig->getTime( i ) ;
     3927        vector<int> ii( 1, ssig->getIF( i ) ) ;
     3928        vector<int> ib( 1, ssig->getBeam( i ) ) ;
     3929        vector<int> ip( 1, ssig->getPol( i ) ) ;
     3930        sel.setIFs( ii ) ;
     3931        sel.setBeams( ib ) ;
     3932        sel.setPolarizations( ip ) ;
     3933        askylo->setSelection( sel ) ;
     3934        vector<float> sptsys = getTsysFromTime( reftime, askylo, "linear" ) ;
     3935        const Vector<Float> Vtsyslo( sptsys ) ;
     3936        tsysCollo.put( i, Vtsyslo ) ;
     3937        askylo->unsetSelection() ;
     3938        sel.reset() ;
     3939        sky[0] = askyhi ;
     3940        sky[1] = askylo ;
     3941        hot[0] = ahothi ;
     3942        hot[1] = ahotlo ;
     3943        cold[0] = acoldhi ;
     3944        cold[1] = acoldlo ;
     3945        sp = getFSCalibratedSpectra( sref, ssig, sky, hot, cold, i ) ;
     3946        sref->setSpectrum( sp, i ) ;
     3947        reftime = sref->getTime( i ) ;
     3948        ii[0] = sref->getIF( i )  ;
     3949        ib[0] = sref->getBeam( i ) ;
     3950        ip[0] = sref->getPol( i ) ;
     3951        sel.setIFs( ii ) ;
     3952        sel.setBeams( ib ) ;
     3953        sel.setPolarizations( ip ) ;
     3954        askyhi->setSelection( sel ) ;   
     3955        sptsys = getTsysFromTime( reftime, askyhi, "linear" ) ;
     3956        const Vector<Float> Vtsyshi( sptsys ) ;
     3957        tsysColhi.put( i, Vtsyshi ) ;
     3958        askyhi->unsetSelection() ;
     3959        sel.reset() ;
     3960      }
     3961    }
     3962    else if ( apexcalmode == 1 ) {
     3963      // APEX fs data with off scan
     3964      // off scan
     3965      types.push_back( SrcType::FLOOFF ) ;
     3966      sel.setTypes( types ) ;
     3967      s->setSelection( sel ) ;
     3968      tmp.clear() ;
     3969      tmp.push_back( getScantable( s, false ) ) ;
     3970      CountedPtr<Scantable> aofflo = average( tmp, masks, "TINT", "SCAN" ) ;
     3971      s->unsetSelection() ;
     3972      sel.reset() ;
     3973      types.clear() ;
     3974      types.push_back( SrcType::FHIOFF ) ;
     3975      sel.setTypes( types ) ;
     3976      s->setSelection( sel ) ;
     3977      tmp.clear() ;
     3978      tmp.push_back( getScantable( s, false ) ) ;
     3979      CountedPtr<Scantable> aoffhi = average( tmp, masks, "TINT", "SCAN" ) ;
     3980      s->unsetSelection() ;
     3981      sel.reset() ;
     3982      types.clear() ;
     3983     
     3984      // process each sig and ref scan
     3985      ArrayColumn<Float> tsysCollo ;
     3986      tsysCollo.attach( ssig->table(), "TSYS" ) ;
     3987      ArrayColumn<Float> tsysColhi ;
     3988      tsysColhi.attach( sref->table(), "TSYS" ) ;
     3989      for ( int i = 0 ; i < ssig->nrow() ; i++ ) {
     3990        vector<float> sp = getCalibratedSpectra( ssig, aofflo, askylo, ahotlo, acoldlo, i, antname ) ;
     3991        ssig->setSpectrum( sp, i ) ;
     3992        sp = getCalibratedSpectra( sref, aoffhi, askyhi, ahothi, acoldhi, i, antname ) ;
     3993        string reftime = ssig->getTime( i ) ;
     3994        vector<int> ii( 1, ssig->getIF( i ) ) ;
     3995        vector<int> ib( 1, ssig->getBeam( i ) ) ;
     3996        vector<int> ip( 1, ssig->getPol( i ) ) ;
     3997        sel.setIFs( ii ) ;
     3998        sel.setBeams( ib ) ;
     3999        sel.setPolarizations( ip ) ;
     4000        askylo->setSelection( sel ) ;
     4001        vector<float> sptsys = getTsysFromTime( reftime, askylo, "linear" ) ;
     4002        const Vector<Float> Vtsyslo( sptsys ) ;
     4003        tsysCollo.put( i, Vtsyslo ) ;
     4004        askylo->unsetSelection() ;
     4005        sel.reset() ;
     4006        sref->setSpectrum( sp, i ) ;
     4007        reftime = sref->getTime( i ) ;
     4008        ii[0] = sref->getIF( i )  ;
     4009        ib[0] = sref->getBeam( i ) ;
     4010        ip[0] = sref->getPol( i ) ;
     4011        sel.setIFs( ii ) ;
     4012        sel.setBeams( ib ) ;
     4013        sel.setPolarizations( ip ) ;
     4014        askyhi->setSelection( sel ) ;   
     4015        sptsys = getTsysFromTime( reftime, askyhi, "linear" ) ;
     4016        const Vector<Float> Vtsyshi( sptsys ) ;
     4017        tsysColhi.put( i, Vtsyshi ) ;
     4018        askyhi->unsetSelection() ;
     4019        sel.reset() ;
     4020      }
     4021    }
     4022  }
     4023  else {
     4024    // non-APEX fs data
     4025    // sky scan
     4026    STSelector sel = STSelector() ;
     4027    types.push_back( SrcType::SKY ) ;
     4028    sel.setTypes( types ) ;
     4029    s->setSelection( sel ) ;
     4030    vector< CountedPtr<Scantable> > tmp( 1, getScantable( s, false ) ) ;
     4031    CountedPtr<Scantable> asky = average( tmp, masks, "TINT", "SCAN" ) ;
     4032    s->unsetSelection() ;
     4033    sel.reset() ;
     4034    types.clear() ;
     4035   
     4036    // hot scan
     4037    types.push_back( SrcType::HOT ) ;
     4038    sel.setTypes( types ) ;
     4039    s->setSelection( sel ) ;
     4040    tmp.clear() ;
     4041    tmp.push_back( getScantable( s, false ) ) ;
     4042    CountedPtr<Scantable> ahot = average( tmp, masks, "TINT", "SCAN" ) ;
     4043    s->unsetSelection() ;
     4044    sel.reset() ;
     4045    types.clear() ;
     4046
     4047    // cold scan
     4048    CountedPtr<Scantable> acold ;
     4049//     types.push_back( SrcType::COLD ) ;
     4050//     sel.setTypes( types ) ;
     4051//     s->setSelection( sel ) ;
     4052//     tmp.clear() ;
     4053//     tmp.push_back( getScantable( s, false ) ) ;
     4054//     CountedPtr<Scantable> acold = average( tmp, masks, "TINT", "SCAN" ) ;
     4055//     s->unsetSelection() ;
     4056//     sel.reset() ;
     4057//     types.clear() ;
     4058   
     4059    // ref scan
     4060    bool insitu = insitu_ ;
     4061    insitu_ = false ;
     4062    sref = getScantable( s, true ) ;
     4063    insitu_ = insitu ;
     4064    types.push_back( SrcType::FSOFF ) ;
     4065    sel.setTypes( types ) ;
     4066    s->setSelection( sel ) ;
     4067    TableCopy::copyRows( sref->table(), s->table() ) ;
     4068    s->unsetSelection() ;
     4069    sel.reset() ;
     4070    types.clear() ;
     4071   
     4072    // sig scan
     4073    insitu_ = false ;
     4074    ssig = getScantable( s, true ) ;
     4075    insitu_ = insitu ;
     4076    types.push_back( SrcType::FSON ) ;
     4077    sel.setTypes( types ) ;
     4078    s->setSelection( sel ) ;
     4079    TableCopy::copyRows( ssig->table(), s->table() ) ;
     4080    s->unsetSelection() ;
     4081    sel.reset() ;
     4082    types.clear() ;
     4083
     4084    // process each sig and ref scan
     4085    ArrayColumn<Float> tsysColsig ;
     4086    tsysColsig.attach( ssig->table(), "TSYS" ) ;
     4087    ArrayColumn<Float> tsysColref ;
     4088    tsysColref.attach( ssig->table(), "TSYS" ) ;
     4089    for ( int i = 0 ; i < ssig->nrow() ; i++ ) {
     4090      vector<float> sp = getFSCalibratedSpectra( ssig, sref, asky, ahot, acold, i ) ;
     4091      ssig->setSpectrum( sp, i ) ;
     4092      string reftime = ssig->getTime( i ) ;
     4093      vector<int> ii( 1, ssig->getIF( i ) ) ;
     4094      vector<int> ib( 1, ssig->getBeam( i ) ) ;
     4095      vector<int> ip( 1, ssig->getPol( i ) ) ;
     4096      sel.setIFs( ii ) ;
     4097      sel.setBeams( ib ) ;
     4098      sel.setPolarizations( ip ) ;
     4099      asky->setSelection( sel ) ;
     4100      vector<float> sptsys = getTsysFromTime( reftime, asky, "linear" ) ;
     4101      const Vector<Float> Vtsys( sptsys ) ;
     4102      tsysColsig.put( i, Vtsys ) ;
     4103      asky->unsetSelection() ;
     4104      sel.reset() ;
     4105      sp = getFSCalibratedSpectra( sref, ssig, asky, ahot, acold, i ) ;
     4106      sref->setSpectrum( sp, i ) ;
     4107      tsysColref.put( i, Vtsys ) ;
     4108    }
     4109  }
     4110
     4111  // do folding if necessary
     4112  Table sigtab = ssig->table() ;
     4113  Table reftab = sref->table() ;
     4114  ScalarColumn<uInt> sigifnoCol ;
     4115  ScalarColumn<uInt> refifnoCol ;
     4116  ScalarColumn<uInt> sigfidCol ;
     4117  ScalarColumn<uInt> reffidCol ;
     4118  Int nchan = (Int)ssig->nchan() ;
     4119  sigifnoCol.attach( sigtab, "IFNO" ) ;
     4120  refifnoCol.attach( reftab, "IFNO" ) ;
     4121  sigfidCol.attach( sigtab, "FREQ_ID" ) ;
     4122  reffidCol.attach( reftab, "FREQ_ID" ) ;
     4123  Vector<uInt> sfids( sigfidCol.getColumn() ) ;
     4124  Vector<uInt> rfids( reffidCol.getColumn() ) ;
     4125  vector<uInt> sfids_unique ;
     4126  vector<uInt> rfids_unique ;
     4127  vector<uInt> sifno_unique ;
     4128  vector<uInt> rifno_unique ;
     4129  for ( uInt i = 0 ; i < sfids.nelements() ; i++ ) {
     4130    if ( count( sfids_unique.begin(), sfids_unique.end(), sfids[i] ) == 0 ) {
     4131      sfids_unique.push_back( sfids[i] ) ;
     4132      sifno_unique.push_back( ssig->getIF( i ) ) ;
     4133    }
     4134    if ( count( rfids_unique.begin(), rfids_unique.end(),  rfids[i] ) == 0 ) {
     4135      rfids_unique.push_back( rfids[i] ) ;
     4136      rifno_unique.push_back( sref->getIF( i ) ) ;
     4137    }
     4138  }
     4139  double refpix_sig, refval_sig, increment_sig ;
     4140  double refpix_ref, refval_ref, increment_ref ;
     4141  vector< CountedPtr<Scantable> > tmp( sfids_unique.size() ) ;
     4142  for ( uInt i = 0 ; i < sfids_unique.size() ; i++ ) {
     4143    ssig->frequencies().getEntry( refpix_sig, refval_sig, increment_sig, sfids_unique[i] ) ;
     4144    sref->frequencies().getEntry( refpix_ref, refval_ref, increment_ref, rfids_unique[i] ) ;
     4145    if ( refpix_sig == refpix_ref ) {
     4146      double foffset = refval_ref - refval_sig ;
     4147      int choffset = static_cast<int>(foffset/increment_sig) ;
     4148      double doffset = foffset / increment_sig ;
     4149      if ( abs(choffset) >= nchan ) {
     4150        LogIO os( LogOrigin( "STMath", "cwcalfs", WHERE ) ) ;
     4151        os << "FREQ_ID=[" << sfids_unique[i] << "," << rfids_unique[i] << "]: out-band frequency switching, no folding" << LogIO::POST ;
     4152        os << "Just return signal data" << LogIO::POST ;
     4153        //std::vector< CountedPtr<Scantable> > tabs ;
     4154        //tabs.push_back( ssig ) ;
     4155        //tabs.push_back( sref ) ;
     4156        //out = merge( tabs ) ;
     4157        tmp[i] = ssig ;
     4158      }
     4159      else {
     4160        STSelector sel = STSelector() ;
     4161        vector<int> v( 1, sifno_unique[i] ) ;
     4162        sel.setIFs( v ) ;
     4163        ssig->setSelection( sel ) ;
     4164        sel.reset() ;
     4165        v[0] = rifno_unique[i] ;
     4166        sel.setIFs( v ) ;
     4167        sref->setSelection( sel ) ;
     4168        sel.reset() ;
     4169        if ( antname.find( "APEX" ) != string::npos ) {
     4170          tmp[i] = dofold( ssig, sref, 0.5*doffset, -0.5*doffset ) ;
     4171          //tmp[i] = dofold( ssig, sref, doffset ) ;
     4172        }
     4173        else {
     4174          tmp[i] = dofold( ssig, sref, doffset ) ;
     4175        }
     4176        ssig->unsetSelection() ;
     4177        sref->unsetSelection() ;
     4178      }
     4179    }
     4180  }
     4181
     4182  if ( tmp.size() > 1 ) {
     4183    out = merge( tmp ) ;
     4184  }
     4185  else {
     4186    out = tmp[0] ;
     4187  }
     4188
     4189  // flux unit
     4190  out->setFluxUnit( "K" ) ;
     4191
     4192  return out ;
     4193}
     4194
     4195CountedPtr<Scantable> STMath::almacalfs( const CountedPtr<Scantable>& s )
     4196{
     4197  CountedPtr<Scantable> out ;
     4198
     4199  return out ;
     4200}
     4201
     4202vector<float> STMath::getSpectrumFromTime( string reftime,
     4203                                           CountedPtr<Scantable>& s,
     4204                                           string mode )
     4205{
     4206  LogIO os( LogOrigin( "STMath", "getSpectrumFromTime", WHERE ) ) ;
     4207  vector<float> sp ;
     4208
     4209  if ( s->nrow() == 0 ) {
     4210    os << LogIO::SEVERE << "No spectra in the input scantable. Return empty spectrum." << LogIO::POST ;
     4211    return sp ;
     4212  }
     4213  else if ( s->nrow() == 1 ) {
     4214    //os << "use row " << 0 << " (scanno = " << s->getScan( 0 ) << ")" << LogIO::POST ;
     4215    return s->getSpectrum( 0 ) ;
     4216  }
     4217  else {
     4218    vector<int> idx = getRowIdFromTime( reftime, s ) ;
     4219    if ( mode == "before" ) {
     4220      int id = -1 ;
     4221      if ( idx[0] != -1 ) {
     4222        id = idx[0] ;
     4223      }
     4224      else if ( idx[1] != -1 ) {
     4225        os << LogIO::WARN << "Failed to find a scan before reftime. return a spectrum just after the reftime." << LogIO::POST ;
     4226        id = idx[1] ;
     4227      }
     4228      //os << "use row " << id << " (scanno = " << s->getScan( id ) << ")" << LogIO::POST ;
     4229      sp = s->getSpectrum( id ) ;
     4230    }
     4231    else if ( mode == "after" ) {
     4232      int id = -1 ;
     4233      if ( idx[1] != -1 ) {
     4234        id = idx[1] ;
     4235      }
     4236      else if ( idx[0] != -1 ) {
     4237        os << LogIO::WARN << "Failed to find a scan after reftime. return a spectrum just before the reftime." << LogIO::POST ;
     4238        id = idx[1] ;
     4239      }
     4240      //os << "use row " << id << " (scanno = " << s->getScan( id ) << ")" << LogIO::POST ;
     4241      sp = s->getSpectrum( id ) ;
     4242    }
     4243    else if ( mode == "nearest" ) {
     4244      int id = -1 ;
     4245      if ( idx[0] == -1 ) {
     4246        id = idx[1] ;
     4247      }
     4248      else if ( idx[1] == -1 ) {
     4249        id = idx[0] ;
     4250      }
     4251      else if ( idx[0] == idx[1] ) {
     4252        id = idx[0] ;
     4253      }
     4254      else {
     4255        double t0 = getMJD( s->getTime( idx[0] ) ) ;
     4256        double t1 = getMJD( s->getTime( idx[1] ) ) ;
     4257        double tref = getMJD( reftime ) ;
     4258        if ( abs( t0 - tref ) > abs( t1 - tref ) ) {
     4259          id = idx[1] ;
     4260        }
     4261        else {
     4262          id = idx[0] ;
     4263        }
     4264      }
     4265      //os << "use row " << id << " (scanno = " << s->getScan( id ) << ")" << LogIO::POST ;
     4266      sp = s->getSpectrum( id ) ;     
     4267    }
     4268    else if ( mode == "linear" ) {
     4269      if ( idx[0] == -1 ) {
     4270        // use after
     4271        os << LogIO::WARN << "Failed to interpolate. return a spectrum just after the reftime." << LogIO::POST ;
     4272        int id = idx[1] ;
     4273        //os << "use row " << id << " (scanno = " << s->getScan( id ) << ")" << LogIO::POST ;
     4274        sp = s->getSpectrum( id ) ;
     4275      }
     4276      else if ( idx[1] == -1 ) {
     4277        // use before
     4278        os << LogIO::WARN << "Failed to interpolate. return a spectrum just before the reftime." << LogIO::POST ;
     4279        int id = idx[0] ;
     4280        //os << "use row " << id << " (scanno = " << s->getScan( id ) << ")" << LogIO::POST ;
     4281        sp = s->getSpectrum( id ) ;
     4282      }
     4283      else if ( idx[0] == idx[1] ) {
     4284        // use before
     4285        //os << "No need to interporate." << LogIO::POST ;
     4286        int id = idx[0] ;
     4287        //os << "use row " << id << " (scanno = " << s->getScan( id ) << ")" << LogIO::POST ;
     4288        sp = s->getSpectrum( id ) ;
     4289      }
     4290      else {
     4291        // do interpolation
     4292        //os << "interpolate between " << idx[0] << " and " << idx[1] << " (scanno: " << s->getScan( idx[0] ) << ", " << s->getScan( idx[1] ) << ")" << LogIO::POST ;
     4293        double t0 = getMJD( s->getTime( idx[0] ) ) ;
     4294        double t1 = getMJD( s->getTime( idx[1] ) ) ;
     4295        double tref = getMJD( reftime ) ;
     4296        vector<float> sp0 = s->getSpectrum( idx[0] ) ;
     4297        vector<float> sp1 = s->getSpectrum( idx[1] ) ;
     4298        for ( unsigned int i = 0 ; i < sp0.size() ; i++ ) {
     4299          float v = ( sp1[i] - sp0[i] ) / ( t1 - t0 ) * ( tref - t0 ) + sp0[i] ;
     4300          sp.push_back( v ) ;
     4301        }
     4302      }
     4303    }
     4304    else {
     4305      os << LogIO::SEVERE << "Unknown mode" << LogIO::POST ;
     4306    }
     4307    return sp ;
     4308  }
     4309}
     4310
     4311double STMath::getMJD( string strtime )
     4312{
     4313  if ( strtime.find("/") == string::npos ) {
     4314    // MJD time string
     4315    return atof( strtime.c_str() ) ;
     4316  }
     4317  else {
     4318    // string in YYYY/MM/DD/HH:MM:SS format
     4319    uInt year = atoi( strtime.substr( 0, 4 ).c_str() ) ;
     4320    uInt month = atoi( strtime.substr( 5, 2 ).c_str() ) ;
     4321    uInt day = atoi( strtime.substr( 8, 2 ).c_str() ) ;
     4322    uInt hour = atoi( strtime.substr( 11, 2 ).c_str() ) ;
     4323    uInt minute = atoi( strtime.substr( 14, 2 ).c_str() ) ;
     4324    uInt sec = atoi( strtime.substr( 17, 2 ).c_str() ) ;
     4325    Time t( year, month, day, hour, minute, sec ) ;
     4326    return t.modifiedJulianDay() ;
     4327  }
     4328}
     4329
     4330vector<int> STMath::getRowIdFromTime( string reftime, CountedPtr<Scantable> &s )
     4331{
     4332  double reft = getMJD( reftime ) ;
     4333  double dtmin = 1.0e100 ;
     4334  double dtmax = -1.0e100 ;
     4335  vector<double> dt ;
     4336  int just_before = -1 ;
     4337  int just_after = -1 ;
     4338  for ( int i = 0 ; i < s->nrow() ; i++ ) {
     4339    dt.push_back( getMJD( s->getTime( i ) ) - reft ) ;
     4340  }
     4341  for ( unsigned int i = 0 ; i < dt.size() ; i++ ) {
     4342    if ( dt[i] > 0.0 ) {
     4343      // after reftime
     4344      if ( dt[i] < dtmin ) {
     4345        just_after = i ;
     4346        dtmin = dt[i] ;
     4347      }
     4348    }
     4349    else if ( dt[i] < 0.0 ) {
     4350      // before reftime
     4351      if ( dt[i] > dtmax ) {
     4352        just_before = i ;
     4353        dtmax = dt[i] ;
     4354      }
     4355    }
     4356    else {
     4357      // just a reftime
     4358      just_before = i ;
     4359      just_after = i ;
     4360      dtmax = 0 ;
     4361      dtmin = 0 ;
     4362      break ;
     4363    }
     4364  }
     4365
     4366  vector<int> v ;
     4367  v.push_back( just_before ) ;
     4368  v.push_back( just_after ) ;
     4369
     4370  return v ;
     4371}
     4372
     4373vector<float> STMath::getTcalFromTime( string reftime,
     4374                                       CountedPtr<Scantable>& s,
     4375                                       string mode )
     4376{
     4377  LogIO os( LogOrigin( "STMath", "getTcalFromTime", WHERE ) ) ;
     4378  vector<float> tcal ;
     4379  STTcal tcalTable = s->tcal() ;
     4380  String time ;
     4381  Vector<Float> tcalval ;
     4382  if ( s->nrow() == 0 ) {
     4383    os << LogIO::SEVERE << "No row in the input scantable. Return empty tcal." << LogIO::POST ;
     4384    return tcal ;
     4385  }
     4386  else if ( s->nrow() == 1 ) {
     4387    uInt tcalid = s->getTcalId( 0 ) ;
     4388    //os << "use row " << 0 << " (tcalid = " << tcalid << ")" << LogIO::POST ;
     4389    tcalTable.getEntry( time, tcalval, tcalid ) ;
     4390    tcalval.tovector( tcal ) ;
     4391    return tcal ;
     4392  }
     4393  else {
     4394    vector<int> idx = getRowIdFromTime( reftime, s ) ;
     4395    if ( mode == "before" ) {
     4396      int id = -1 ;
     4397      if ( idx[0] != -1 ) {
     4398        id = idx[0] ;
     4399      }
     4400      else if ( idx[1] != -1 ) {
     4401        os << LogIO::WARN << "Failed to find a scan before reftime. return a spectrum just after the reftime." << LogIO::POST ;
     4402        id = idx[1] ;
     4403      }
     4404      uInt tcalid = s->getTcalId( id ) ;
     4405      //os << "use row " << id << " (tcalid = " << tcalid << ")" << LogIO::POST ;
     4406      tcalTable.getEntry( time, tcalval, tcalid ) ;
     4407      tcalval.tovector( tcal ) ;
     4408    }
     4409    else if ( mode == "after" ) {
     4410      int id = -1 ;
     4411      if ( idx[1] != -1 ) {
     4412        id = idx[1] ;
     4413      }
     4414      else if ( idx[0] != -1 ) {
     4415        os << LogIO::WARN << "Failed to find a scan after reftime. return a spectrum just before the reftime." << LogIO::POST ;
     4416        id = idx[1] ;
     4417      }
     4418      uInt tcalid = s->getTcalId( id ) ;
     4419      //os << "use row " << id << " (tcalid = " << tcalid << ")" << LogIO::POST ;
     4420      tcalTable.getEntry( time, tcalval, tcalid ) ;
     4421      tcalval.tovector( tcal ) ;
     4422    }
     4423    else if ( mode == "nearest" ) {
     4424      int id = -1 ;
     4425      if ( idx[0] == -1 ) {
     4426        id = idx[1] ;
     4427      }
     4428      else if ( idx[1] == -1 ) {
     4429        id = idx[0] ;
     4430      }
     4431      else if ( idx[0] == idx[1] ) {
     4432        id = idx[0] ;
     4433      }
     4434      else {
     4435        double t0 = getMJD( s->getTime( idx[0] ) ) ;
     4436        double t1 = getMJD( s->getTime( idx[1] ) ) ;
     4437        double tref = getMJD( reftime ) ;
     4438        if ( abs( t0 - tref ) > abs( t1 - tref ) ) {
     4439          id = idx[1] ;
     4440        }
     4441        else {
     4442          id = idx[0] ;
     4443        }
     4444      }
     4445      uInt tcalid = s->getTcalId( id ) ;
     4446      //os << "use row " << id << " (tcalid = " << tcalid << ")" << LogIO::POST ;
     4447      tcalTable.getEntry( time, tcalval, tcalid ) ;
     4448      tcalval.tovector( tcal ) ;
     4449    }
     4450    else if ( mode == "linear" ) {
     4451      if ( idx[0] == -1 ) {
     4452        // use after
     4453        os << LogIO::WARN << "Failed to interpolate. return a spectrum just after the reftime." << LogIO::POST ;
     4454        int id = idx[1] ;
     4455        uInt tcalid = s->getTcalId( id ) ;
     4456        //os << "use row " << id << " (tcalid = " << tcalid << ")" << LogIO::POST ;
     4457        tcalTable.getEntry( time, tcalval, tcalid ) ;
     4458        tcalval.tovector( tcal ) ;
     4459      }
     4460      else if ( idx[1] == -1 ) {
     4461        // use before
     4462        os << LogIO::WARN << "Failed to interpolate. return a spectrum just before the reftime." << LogIO::POST ;
     4463        int id = idx[0] ;
     4464        uInt tcalid = s->getTcalId( id ) ;
     4465        //os << "use row " << id << " (tcalid = " << tcalid << ")" << LogIO::POST ;
     4466        tcalTable.getEntry( time, tcalval, tcalid ) ;
     4467        tcalval.tovector( tcal ) ;
     4468      }
     4469      else if ( idx[0] == idx[1] ) {
     4470        // use before
     4471        //os << "No need to interporate." << LogIO::POST ;
     4472        int id = idx[0] ;
     4473        uInt tcalid = s->getTcalId( id ) ;
     4474        //os << "use row " << id << " (tcalid = " << tcalid << ")" << LogIO::POST ;
     4475        tcalTable.getEntry( time, tcalval, tcalid ) ;
     4476        tcalval.tovector( tcal ) ;
     4477      }
     4478      else {
     4479        // do interpolation
     4480        //os << "interpolate between " << idx[0] << " and " << idx[1] << " (scanno: " << s->getScan( idx[0] ) << ", " << s->getScan( idx[1] ) << ")" << LogIO::POST ;
     4481        double t0 = getMJD( s->getTime( idx[0] ) ) ;
     4482        double t1 = getMJD( s->getTime( idx[1] ) ) ;
     4483        double tref = getMJD( reftime ) ;
     4484        vector<float> tcal0 ;
     4485        vector<float> tcal1 ;
     4486        uInt tcalid0 = s->getTcalId( idx[0] ) ;
     4487        uInt tcalid1 = s->getTcalId( idx[1] ) ;
     4488        tcalTable.getEntry( time, tcalval, tcalid0 ) ;
     4489        tcalval.tovector( tcal0 ) ;
     4490        tcalTable.getEntry( time, tcalval, tcalid1 ) ;
     4491        tcalval.tovector( tcal1 ) ;       
     4492        for ( unsigned int i = 0 ; i < tcal0.size() ; i++ ) {
     4493          float v = ( tcal1[i] - tcal0[i] ) / ( t1 - t0 ) * ( tref - t0 ) + tcal0[i] ;
     4494          tcal.push_back( v ) ;
     4495        }
     4496      }
     4497    }
     4498    else {
     4499      os << LogIO::SEVERE << "Unknown mode" << LogIO::POST ;
     4500    }
     4501    return tcal ;
     4502  }
     4503}
     4504
     4505vector<float> STMath::getTsysFromTime( string reftime,
     4506                                       CountedPtr<Scantable>& s,
     4507                                       string mode )
     4508{
     4509  LogIO os( LogOrigin( "STMath", "getTsysFromTime", WHERE ) ) ;
     4510  ArrayColumn<Float> tsysCol ;
     4511  tsysCol.attach( s->table(), "TSYS" ) ;
     4512  vector<float> tsys ;
     4513  String time ;
     4514  Vector<Float> tsysval ;
     4515  if ( s->nrow() == 0 ) {
     4516    os << LogIO::SEVERE << "No row in the input scantable. Return empty tsys." << LogIO::POST ;
     4517    return tsys ;
     4518  }
     4519  else if ( s->nrow() == 1 ) {
     4520    //os << "use row " << 0 << LogIO::POST ;
     4521    tsysval = tsysCol( 0 ) ;
     4522    tsysval.tovector( tsys ) ;
     4523    return tsys ;
     4524  }
     4525  else {
     4526    vector<int> idx = getRowIdFromTime( reftime, s ) ;
     4527    if ( mode == "before" ) {
     4528      int id = -1 ;
     4529      if ( idx[0] != -1 ) {
     4530        id = idx[0] ;
     4531      }
     4532      else if ( idx[1] != -1 ) {
     4533        os << LogIO::WARN << "Failed to find a scan before reftime. return a spectrum just after the reftime." << LogIO::POST ;
     4534        id = idx[1] ;
     4535      }
     4536      //os << "use row " << id << LogIO::POST ;
     4537      tsysval = tsysCol( id ) ;
     4538      tsysval.tovector( tsys ) ;
     4539    }
     4540    else if ( mode == "after" ) {
     4541      int id = -1 ;
     4542      if ( idx[1] != -1 ) {
     4543        id = idx[1] ;
     4544      }
     4545      else if ( idx[0] != -1 ) {
     4546        os << LogIO::WARN << "Failed to find a scan after reftime. return a spectrum just before the reftime." << LogIO::POST ;
     4547        id = idx[1] ;
     4548      }
     4549      //os << "use row " << id << LogIO::POST ;
     4550      tsysval = tsysCol( id ) ;
     4551      tsysval.tovector( tsys ) ;
     4552    }
     4553    else if ( mode == "nearest" ) {
     4554      int id = -1 ;
     4555      if ( idx[0] == -1 ) {
     4556        id = idx[1] ;
     4557      }
     4558      else if ( idx[1] == -1 ) {
     4559        id = idx[0] ;
     4560      }
     4561      else if ( idx[0] == idx[1] ) {
     4562        id = idx[0] ;
     4563      }
     4564      else {
     4565        double t0 = getMJD( s->getTime( idx[0] ) ) ;
     4566        double t1 = getMJD( s->getTime( idx[1] ) ) ;
     4567        double tref = getMJD( reftime ) ;
     4568        if ( abs( t0 - tref ) > abs( t1 - tref ) ) {
     4569          id = idx[1] ;
     4570        }
     4571        else {
     4572          id = idx[0] ;
     4573        }
     4574      }
     4575      //os << "use row " << id << LogIO::POST ;
     4576      tsysval = tsysCol( id ) ;
     4577      tsysval.tovector( tsys ) ;
     4578    }
     4579    else if ( mode == "linear" ) {
     4580      if ( idx[0] == -1 ) {
     4581        // use after
     4582        os << LogIO::WARN << "Failed to interpolate. return a spectrum just after the reftime." << LogIO::POST ;
     4583        int id = idx[1] ;
     4584        //os << "use row " << id << LogIO::POST ;
     4585        tsysval = tsysCol( id ) ;
     4586        tsysval.tovector( tsys ) ;
     4587      }
     4588      else if ( idx[1] == -1 ) {
     4589        // use before
     4590        os << LogIO::WARN << "Failed to interpolate. return a spectrum just before the reftime." << LogIO::POST ;
     4591        int id = idx[0] ;
     4592        //os << "use row " << id << LogIO::POST ;
     4593        tsysval = tsysCol( id ) ;
     4594        tsysval.tovector( tsys ) ;
     4595      }
     4596      else if ( idx[0] == idx[1] ) {
     4597        // use before
     4598        //os << "No need to interporate." << LogIO::POST ;
     4599        int id = idx[0] ;
     4600        //os << "use row " << id << LogIO::POST ;
     4601        tsysval = tsysCol( id ) ;
     4602        tsysval.tovector( tsys ) ;
     4603      }
     4604      else {
     4605        // do interpolation
     4606        //os << "interpolate between " << idx[0] << " and " << idx[1] << " (scanno: " << s->getScan( idx[0] ) << ", " << s->getScan( idx[1] ) << ")" << LogIO::POST ;
     4607        double t0 = getMJD( s->getTime( idx[0] ) ) ;
     4608        double t1 = getMJD( s->getTime( idx[1] ) ) ;
     4609        double tref = getMJD( reftime ) ;
     4610        vector<float> tsys0 ;
     4611        vector<float> tsys1 ;
     4612        tsysval = tsysCol( idx[0] ) ;
     4613        tsysval.tovector( tsys0 ) ;
     4614        tsysval = tsysCol( idx[1] ) ;
     4615        tsysval.tovector( tsys1 ) ;       
     4616        for ( unsigned int i = 0 ; i < tsys0.size() ; i++ ) {
     4617          float v = ( tsys1[i] - tsys0[i] ) / ( t1 - t0 ) * ( tref - t0 ) + tsys0[i] ;
     4618          tsys.push_back( v ) ;
     4619        }
     4620      }
     4621    }
     4622    else {
     4623      os << LogIO::SEVERE << "Unknown mode" << LogIO::POST ;
     4624    }
     4625    return tsys ;
     4626  }
     4627}
     4628
     4629vector<float> STMath::getCalibratedSpectra( CountedPtr<Scantable>& on,
     4630                                            CountedPtr<Scantable>& off,
     4631                                            CountedPtr<Scantable>& sky,
     4632                                            CountedPtr<Scantable>& hot,
     4633                                            CountedPtr<Scantable>& cold,
     4634                                            int index,
     4635                                            string antname )
     4636{
     4637  string reftime = on->getTime( index ) ;
     4638  vector<int> ii( 1, on->getIF( index ) ) ;
     4639  vector<int> ib( 1, on->getBeam( index ) ) ;
     4640  vector<int> ip( 1, on->getPol( index ) ) ;
     4641  vector<int> ic( 1, on->getScan( index ) ) ;
     4642  STSelector sel = STSelector() ;
     4643  sel.setIFs( ii ) ;
     4644  sel.setBeams( ib ) ;
     4645  sel.setPolarizations( ip ) ;
     4646  sky->setSelection( sel ) ;
     4647  hot->setSelection( sel ) ;
     4648  //cold->setSelection( sel ) ;
     4649  off->setSelection( sel ) ;
     4650  vector<float> spsky = getSpectrumFromTime( reftime, sky, "linear" ) ;
     4651  vector<float> sphot = getSpectrumFromTime( reftime, hot, "linear" ) ;
     4652  //vector<float> spcold = getSpectrumFromTime( reftime, cold, "linear" ) ;
     4653  vector<float> spoff = getSpectrumFromTime( reftime, off, "linear" ) ;
     4654  vector<float> spec = on->getSpectrum( index ) ;
     4655  vector<float> tcal = getTcalFromTime( reftime, sky, "linear" ) ;
     4656  vector<float> sp( tcal.size() ) ;
     4657  if ( antname.find( "APEX" ) != string::npos ) {
     4658    // using gain array
     4659    for ( unsigned int j = 0 ; j < tcal.size() ; j++ ) {
     4660      float v = ( ( spec[j] - spoff[j] ) / spoff[j] )
     4661        * ( spsky[j] / ( sphot[j] - spsky[j] ) ) * tcal[j] ;
     4662      sp[j] = v ;
     4663    }
     4664  }
     4665  else {
     4666    // Chopper-Wheel calibration (Ulich & Haas 1976)
     4667    for ( unsigned int j = 0 ; j < tcal.size() ; j++ ) {
     4668      float v = ( spec[j] - spoff[j] ) / ( sphot[j] - spsky[j] ) * tcal[j] ;
     4669      sp[j] = v ;
     4670    }
     4671  }
     4672  sel.reset() ;
     4673  sky->unsetSelection() ;
     4674  hot->unsetSelection() ;
     4675  //cold->unsetSelection() ;
     4676  off->unsetSelection() ;
     4677
     4678  return sp ;
     4679}
     4680
     4681vector<float> STMath::getCalibratedSpectra( CountedPtr<Scantable>& on,
     4682                                            CountedPtr<Scantable>& off,
     4683                                            int index )
     4684{
     4685  string reftime = on->getTime( index ) ;
     4686  vector<int> ii( 1, on->getIF( index ) ) ;
     4687  vector<int> ib( 1, on->getBeam( index ) ) ;
     4688  vector<int> ip( 1, on->getPol( index ) ) ;
     4689  vector<int> ic( 1, on->getScan( index ) ) ;
     4690  STSelector sel = STSelector() ;
     4691  sel.setIFs( ii ) ;
     4692  sel.setBeams( ib ) ;
     4693  sel.setPolarizations( ip ) ;
     4694  off->setSelection( sel ) ;
     4695  vector<float> spoff = getSpectrumFromTime( reftime, off, "linear" ) ;
     4696  vector<float> spec = on->getSpectrum( index ) ;
     4697  //vector<float> tcal = getTcalFromTime( reftime, sky, "linear" ) ;
     4698  //vector<float> tsys = on->getTsysVec( index ) ;
     4699  ArrayColumn<Float> tsysCol( on->table(), "TSYS" ) ;
     4700  Vector<Float> tsys = tsysCol( index ) ;
     4701  vector<float> sp( spec.size() ) ;
     4702  // ALMA Calibration
     4703  //
     4704  // Ta* = Tsys * ( ON - OFF ) / OFF
     4705  //
     4706  // 2010/01/07 Takeshi Nakazato
     4707  unsigned int tsyssize = tsys.nelements() ;
     4708  unsigned int spsize = sp.size() ;
     4709  for ( unsigned int j = 0 ; j < sp.size() ; j++ ) {
     4710    float tscale = 0.0 ;
     4711    if ( tsyssize == spsize )
     4712      tscale = tsys[j] ;
     4713    else
     4714      tscale = tsys[0] ;
     4715    float v = tscale * ( spec[j] - spoff[j] ) / spoff[j] ;
     4716    sp[j] = v ;
     4717  }
     4718  sel.reset() ;
     4719  off->unsetSelection() ;
     4720
     4721  return sp ;
     4722}
     4723
     4724vector<float> STMath::getFSCalibratedSpectra( CountedPtr<Scantable>& sig,
     4725                                              CountedPtr<Scantable>& ref,
     4726                                              CountedPtr<Scantable>& sky,
     4727                                              CountedPtr<Scantable>& hot,
     4728                                              CountedPtr<Scantable>& cold,
     4729                                              int index )
     4730{
     4731  string reftime = sig->getTime( index ) ;
     4732  vector<int> ii( 1, sig->getIF( index ) ) ;
     4733  vector<int> ib( 1, sig->getBeam( index ) ) ;
     4734  vector<int> ip( 1, sig->getPol( index ) ) ;
     4735  vector<int> ic( 1, sig->getScan( index ) ) ;
     4736  STSelector sel = STSelector() ;
     4737  sel.setIFs( ii ) ;
     4738  sel.setBeams( ib ) ;
     4739  sel.setPolarizations( ip ) ;
     4740  sky->setSelection( sel ) ;
     4741  hot->setSelection( sel ) ;
     4742  //cold->setSelection( sel ) ;
     4743  vector<float> spsky = getSpectrumFromTime( reftime, sky, "linear" ) ;
     4744  vector<float> sphot = getSpectrumFromTime( reftime, hot, "linear" ) ;
     4745  //vector<float> spcold = getSpectrumFromTime( reftime, cold, "linear" ) ;
     4746  vector<float> spref = ref->getSpectrum( index ) ;
     4747  vector<float> spsig = sig->getSpectrum( index ) ;
     4748  vector<float> tcal = getTcalFromTime( reftime, sky, "linear" ) ;
     4749  vector<float> sp( tcal.size() ) ;
     4750  for ( unsigned int j = 0 ; j < tcal.size() ; j++ ) {
     4751    float v = tcal[j] * spsky[j] / ( sphot[j] - spsky[j] ) * ( spsig[j] - spref[j] ) / spref[j] ;
     4752    sp[j] = v ;
     4753  }
     4754  sel.reset() ;
     4755  sky->unsetSelection() ;
     4756  hot->unsetSelection() ;
     4757  //cold->unsetSelection() ;
     4758
     4759  return sp ;
     4760}
     4761
     4762vector<float> STMath::getFSCalibratedSpectra( CountedPtr<Scantable>& sig,
     4763                                              CountedPtr<Scantable>& ref,
     4764                                              vector< CountedPtr<Scantable> >& sky,
     4765                                              vector< CountedPtr<Scantable> >& hot,
     4766                                              vector< CountedPtr<Scantable> >& cold,
     4767                                              int index )
     4768{
     4769  string reftime = sig->getTime( index ) ;
     4770  vector<int> ii( 1, sig->getIF( index ) ) ;
     4771  vector<int> ib( 1, sig->getBeam( index ) ) ;
     4772  vector<int> ip( 1, sig->getPol( index ) ) ;
     4773  vector<int> ic( 1, sig->getScan( index ) ) ;
     4774  STSelector sel = STSelector() ;
     4775  sel.setIFs( ii ) ;
     4776  sel.setBeams( ib ) ;
     4777  sel.setPolarizations( ip ) ;
     4778  sky[0]->setSelection( sel ) ;
     4779  hot[0]->setSelection( sel ) ;
     4780  //cold[0]->setSelection( sel ) ;
     4781  vector<float> spskys = getSpectrumFromTime( reftime, sky[0], "linear" ) ;
     4782  vector<float> sphots = getSpectrumFromTime( reftime, hot[0], "linear" ) ;
     4783  //vector<float> spcolds = getSpectrumFromTime( reftime, cold[0], "linear" ) ;
     4784  vector<float> tcals = getTcalFromTime( reftime, sky[0], "linear" ) ;
     4785  sel.reset() ;
     4786  ii[0] = ref->getIF( index ) ;
     4787  sel.setIFs( ii ) ;
     4788  sel.setBeams( ib ) ;
     4789  sel.setPolarizations( ip ) ;
     4790  sky[1]->setSelection( sel ) ;
     4791  hot[1]->setSelection( sel ) ;
     4792  //cold[1]->setSelection( sel ) ;
     4793  vector<float> spskyr = getSpectrumFromTime( reftime, sky[1], "linear" ) ;
     4794  vector<float> sphotr = getSpectrumFromTime( reftime, hot[1], "linear" ) ;
     4795  //vector<float> spcoldr = getSpectrumFromTime( reftime, cold[1], "linear" ) ;
     4796  vector<float> tcalr = getTcalFromTime( reftime, sky[1], "linear" ) ; 
     4797  vector<float> spref = ref->getSpectrum( index ) ;
     4798  vector<float> spsig = sig->getSpectrum( index ) ;
     4799  vector<float> sp( tcals.size() ) ;
     4800  for ( unsigned int j = 0 ; j < tcals.size() ; j++ ) {
     4801    float v = tcals[j] * spsig[j] / ( sphots[j] - spskys[j] ) - tcalr[j] * spref[j] / ( sphotr[j] - spskyr[j] ) ;
     4802    sp[j] = v ;
     4803  }
     4804  sel.reset() ;
     4805  sky[0]->unsetSelection() ;
     4806  hot[0]->unsetSelection() ;
     4807  //cold[0]->unsetSelection() ;
     4808  sky[1]->unsetSelection() ;
     4809  hot[1]->unsetSelection() ;
     4810  //cold[1]->unsetSelection() ;
     4811
     4812  return sp ;
     4813}
  • trunk/src/STMath.h

    r1689 r1819  
    119119                  const std::string& mode, bool tsys=false );
    120120
     121  // array operation
     122  casa::CountedPtr<Scantable>
     123    arrayOperate( const casa::CountedPtr<Scantable>& in,
     124                  const std::vector<float> val,
     125                  const std::string& mode,
     126                  const std::string& opmode="channel", 
     127                  bool tsys=false );
     128
     129  // channel operation
     130  casa::CountedPtr<Scantable>
     131    arrayOperateChannel( const casa::CountedPtr<Scantable>& in,
     132                         const std::vector<float> val,
     133                         const std::string& mode, bool tsys=false );
     134
     135  // row operation
     136  casa::CountedPtr<Scantable>
     137    arrayOperateRow( const casa::CountedPtr<Scantable>& in,
     138                     const std::vector<float> val,
     139                     const std::string& mode, bool tsys=false );
     140
     141  // 2d array operation
     142  casa::CountedPtr<Scantable>
     143    array2dOperate( const casa::CountedPtr<Scantable>& in,
     144                  const std::vector< std::vector<float> > val,
     145                  const std::string& mode, bool tsys=false );
     146
    121147  casa::CountedPtr<Scantable>
    122148    binaryOperate( const casa::CountedPtr<Scantable>& left,
     
    134160  /**
    135161    * Calibrate total power scans (translated from GBTIDL)
    136     * @param calon uncalibrated Scantable with CAL noise signal
     162    * @param calon uncalibrated Scantable with CAL noise signal 
    137163    * @param caloff uncalibrated Scantable with no CAL signal
    138164    * @param tcal optional scalar Tcal, CAL temperature (K)
    139     * @return casa::CountedPtr<Scantable> which holds a calibrated Scantable
     165    * @return casa::CountedPtr<Scantable> which holds a calibrated Scantable 
    140166    * (spectrum - average of the two CAL on and off spectra;
    141167    * tsys - mean Tsys = <caloff>*Tcal/<calon-caloff> + Tcal/2)
    142     */
     168    */             
    143169  casa::CountedPtr<Scantable> dototalpower( const casa::CountedPtr<Scantable>& calon,
    144170                                            const casa::CountedPtr<Scantable>& caloff,
     
    151177    * @param smoothref optional Boxcar smooth width of the reference scans
    152178    * default: no smoothing (=1)
    153     * @param tsysv optional scalar Tsys value at the zenith, required to
    154     * set tau, as well
     179    * @param tsysv optional scalar Tsys value at the zenith, required to 
     180    * set tau, as well 
    155181    * @param tau optional scalar Tau value
    156182    * @return casa::CountedPtr<Scantable> which holds combined scans
     
    163189                                        casa::Float tau=0.0 );
    164190
    165  /**
     191  /**
    166192    * Calibrate GBT Nod scan pairs (translated from GBTIDL)
    167193    * @param s Scantable which contains Nod scans
     
    170196    * @param tsysv optional scalar Tsys value at the zenith, required to
    171197    * set tau, as well
    172     * @param tau optional scalar Tau value
     198    * @param tau optional scalar Tau value 
    173199    * @param tcal optional scalar Tcal, CAL temperature (K)
    174200    * @return casa::CountedPtr<Scantable> which holds calibrated scans
     
    199225                                    casa::Float tcal=0.0 );
    200226
     227  /**
     228   * Calibrate data with Chopper-Wheel like calibration method
     229   * which adopts position switching by antenna motion,
     230   * wobbler (nutator) switching and On-The-Fly observation.
     231   *
     232   * The method is applicable to APEX, and other telescopes other than GBT.
     233   *
     234   * @param a Scantable which contains ON and OFF scans
     235   * @param a string that indicates calibration mode
     236   * @param a string that indicates antenna name
     237   **/
     238  casa::CountedPtr<Scantable> cwcal( const casa::CountedPtr<Scantable>& s,
     239                                       const casa::String calmode,
     240                                       const casa::String antname );
     241
     242  /**
     243   * Calibrate frequency switched scans with Chopper-Wheel like
     244   * calibration method.
     245   *
     246   * The method is applicable to APEX, and other telescopes other than GBT.
     247   *
     248   * @param a Scantable which contains ON and OFF scans
     249   * @param a string that indicates antenna name
     250   **/
     251  casa::CountedPtr<Scantable> cwcalfs( const casa::CountedPtr<Scantable>& s,
     252                                       const casa::String antname );
     253
     254
     255  /**
     256   * Folding frequency-switch data
     257   * @param sig
     258   * @param ref
     259   * @param choffset
     260   **/
     261  casa::CountedPtr<Scantable> dofold( const casa::CountedPtr<Scantable> &sig,
     262                                      const casa::CountedPtr<Scantable> &ref,
     263                                      casa::Double choffset,
     264                                      casa::Double choffset = 0.0 );
     265
     266  /**
     267   * ALMA calibration
     268   **/
     269  casa::CountedPtr<Scantable> almacal( const casa::CountedPtr<Scantable>& s,
     270                                       const casa::String calmode ) ;
     271  casa::CountedPtr<Scantable> almacalfs( const casa::CountedPtr<Scantable>& s ) ;
    201272
    202273  casa::CountedPtr<Scantable>
     
    206277                               const std::vector<bool>& mask,
    207278                               const std::string& which);
     279
     280  std::vector< int > minMaxChan(const casa::CountedPtr<Scantable>& in,
     281                                const std::vector<bool>& mask,
     282                                const std::string& which);
    208283
    209284  casa::CountedPtr<Scantable> bin( const casa::CountedPtr<Scantable>& in,
     
    266341             double end, const std::string& mode="frequency");
    267342
     343  // test for average spectra with different channel/resolution
     344  casa::CountedPtr<Scantable>
     345    new_average( const std::vector<casa::CountedPtr<Scantable> >& in,
     346                 const bool& compel,
     347                 const std::vector<bool>& mask = std::vector<bool>(),
     348                 const std::string& weight = "NONE",
     349                 const std::string& avmode = "SCAN" )
     350    throw (casa::AipsError) ;
     351
    268352private:
    269353  casa::CountedPtr<Scantable>  applyToPol( const casa::CountedPtr<Scantable>& in,
     
    301385    maskedArray( const casa::Vector<casa::Float>& s,
    302386                 const casa::Vector<casa::uChar>& f );
     387  casa::MaskedArray<casa::Double>
     388    maskedArray( const casa::Vector<casa::Double>& s,
     389                 const casa::Vector<casa::uChar>& f );
    303390  casa::Vector<casa::uChar>
    304391    flagsFromMA(const casa::MaskedArray<casa::Float>& ma);
    305392
     393  vector<float> getSpectrumFromTime( string reftime, casa::CountedPtr<Scantable>& s, string mode = "before" ) ;
     394  vector<float> getTcalFromTime( string reftime, casa::CountedPtr<Scantable>& s, string mode="before" ) ;
     395  vector<float> getTsysFromTime( string reftime, casa::CountedPtr<Scantable>& s, string mode="before" ) ;
     396  vector<int> getRowIdFromTime( string reftime, casa::CountedPtr<Scantable>& s ) ;
     397
     398  // Chopper-Wheel type calibration
     399  vector<float> getCalibratedSpectra( casa::CountedPtr<Scantable>& on,
     400                                      casa::CountedPtr<Scantable>& off,
     401                                      casa::CountedPtr<Scantable>& sky,
     402                                      casa::CountedPtr<Scantable>& hot,
     403                                      casa::CountedPtr<Scantable>& cold,
     404                                      int index,
     405                                      string antname ) ;
     406  // Tsys * (ON-OFF)/OFF
     407  vector<float> getCalibratedSpectra( casa::CountedPtr<Scantable>& on,
     408                                      casa::CountedPtr<Scantable>& off,
     409                                      int index ) ;
     410  vector<float> getFSCalibratedSpectra( casa::CountedPtr<Scantable>& sig,
     411                                        casa::CountedPtr<Scantable>& ref,
     412                                        casa::CountedPtr<Scantable>& sky,
     413                                        casa::CountedPtr<Scantable>& hot,
     414                                        casa::CountedPtr<Scantable>& cold,
     415                                        int index ) ;
     416  vector<float> getFSCalibratedSpectra( casa::CountedPtr<Scantable>& sig,
     417                                        casa::CountedPtr<Scantable>& ref,
     418                                        vector< casa::CountedPtr<Scantable> >& sky,
     419                                        vector< casa::CountedPtr<Scantable> >& hot,
     420                                        vector< casa::CountedPtr<Scantable> >& cold,
     421                                        int index ) ;
     422  double getMJD( string strtime ) ;
     423
    306424  bool insitu_;
    307425};
  • trunk/src/STMathWrapper.h

    r1689 r1819  
    7373  { return ScantableWrapper(STMath::unaryOperate(in.getCP(), val, mode, tsys)); }
    7474
     75  ScantableWrapper arrayOperate( const ScantableWrapper& in,
     76                                 const std::vector<float> val,
     77                                 const std::string& mode,
     78                                 bool tsys=false )
     79  { return ScantableWrapper(STMath::arrayOperateChannel(in.getCP(), val, mode, tsys)); }
     80
     81  ScantableWrapper array2dOperate( const ScantableWrapper& in,
     82                                   const std::vector< std::vector<float> > val,
     83                                   const std::string& mode, bool tsys=false )
     84  { return ScantableWrapper(STMath::array2dOperate(in.getCP(), val, mode, tsys)); }
     85
    7586  ScantableWrapper binaryOperate( const ScantableWrapper& left,
    7687                                  const ScantableWrapper& right,
     
    121132  { return STMath::statistic(in.getCP(), mask, which); }
    122133
     134  std::vector<int> minMaxChan(const ScantableWrapper& in,
     135                               const std::vector<bool>& mask,
     136                               const std::string& which)
     137  { return STMath::minMaxChan(in.getCP(), mask, which); }
     138
    123139  ScantableWrapper bin( const ScantableWrapper& in, int width=5)
    124140  { return ScantableWrapper(STMath::bin(in.getCP(), width)); }
     
    175191                                   const std::string& refTime,
    176192                                   const std::string& method  )
    177   { return ScantableWrapper(STMath::frequencyAlign(in.getCP(), refTime, method)); }
     193  { return ScantableWrapper(STMath::frequencyAlign(in.getCP())); }
    178194
    179195  ScantableWrapper convertPolarisation( const ScantableWrapper& in,
     
    191207                                            mode)); }
    192208
     209  // test for average spectra with different channel/resolution
     210  ScantableWrapper
     211    new_average( const std::vector<ScantableWrapper>& in,
     212                 const bool& compel,
     213                 const std::vector<bool>& mask,
     214                 const std::string& weight,
     215                 const std::string& avmode )
     216  {
     217    std::vector<casa::CountedPtr<Scantable> > sts;
     218    for (unsigned int i=0; i<in.size(); ++i) sts.push_back(in[i].getCP());
     219    return ScantableWrapper(STMath::new_average(sts, compel, mask, weight, avmode));
     220  }
     221
     222  // cwcal
     223  ScantableWrapper cwcal( const ScantableWrapper &in,
     224                          const std::string calmode,
     225                          const std::string antname )
     226  {
     227    casa::CountedPtr<Scantable> tab = in.getCP() ;
     228    casa::String mode( calmode ) ;
     229    casa::String name( antname ) ;
     230    return ScantableWrapper( STMath::cwcal( tab, mode, name ) ) ;
     231  }
     232  // almacal
     233  ScantableWrapper almacal( const ScantableWrapper &in,
     234                          const std::string calmode )
     235  {
     236    casa::CountedPtr<Scantable> tab = in.getCP() ;
     237    casa::String mode( calmode ) ;
     238    return ScantableWrapper( STMath::almacal( tab, mode ) ) ;
     239  }
    193240};
    194241
  • trunk/src/STMolecules.cpp

    r870 r1819  
    1414#include <tables/Tables/SetupNewTab.h>
    1515#include <tables/Tables/ScaColDesc.h>
     16#include <tables/Tables/ArrColDesc.h>
    1617#include <tables/Tables/TableRecord.h>
    1718#include <tables/Tables/TableParse.h>
    1819#include <tables/Tables/TableRow.h>
    1920#include <casa/Containers/RecordField.h>
     21
     22#include <tables/Tables/TableProxy.h>
    2023
    2124#include "STMolecules.h"
     
    5962{
    6063  // add to base class table
    61   table_.addColumn(ScalarColumnDesc<Double>("RESTFREQUENCY"));
    62   table_.addColumn(ScalarColumnDesc<String>("NAME"));
    63   table_.addColumn(ScalarColumnDesc<String>("FORMATTEDNAME"));
     64  //table_.addColumn(ScalarColumnDesc<Double>("RESTFREQUENCY"));
     65  table_.addColumn(ArrayColumnDesc<Double>("RESTFREQUENCY"));
     66  //table_.addColumn(ScalarColumnDesc<String>("NAME"));
     67  table_.addColumn(ArrayColumnDesc<String>("NAME"));
     68  //table_.addColumn(ScalarColumnDesc<String>("FORMATTEDNAME"));
     69  table_.addColumn(ArrayColumnDesc<String>("FORMATTEDNAME"));
    6470  table_.rwKeywordSet().define("UNIT", String("Hz"));
    6571  // new cached columns
     
    6975}
    7076
     77/***
    7178uInt STMolecules::addEntry( Double restfreq, const String& name,
    7279                            const String& formattedname )
     
    94101  return resultid;
    95102}
    96 
     103***/
     104uInt STMolecules::addEntry( Vector<Double> restfreq, const Vector<String>& name,
     105                            const Vector<String>& formattedname )
     106{
     107// How to handle this...?
     108  Table result =
     109    table_( nelements(table_.col("RESTFREQUENCY")) == uInt (restfreq.size()) &&
     110            all(table_.col("RESTFREQUENCY")== restfreq) );
     111  uInt resultid = 0;
     112  if ( result.nrow() > 0) {
     113    ROScalarColumn<uInt> c(result, "ID");
     114    c.get(0, resultid);
     115  } else {
     116    uInt rno = table_.nrow();
     117    table_.addRow();
     118    // get last assigned _id and increment
     119    if ( rno > 0 ) {
     120      idCol_.get(rno-1, resultid);
     121      resultid++;
     122    }
     123    restfreqCol_.put(rno, restfreq);
     124    nameCol_.put(rno, name);
     125    formattednameCol_.put(rno, formattedname);
     126    idCol_.put(rno, resultid);
     127  }
     128  return resultid;
     129}
     130
     131
     132
     133
     134/***
    97135void STMolecules::getEntry( Double& restfreq, String& name,
    98136                            String& formattedname, uInt id ) const
     
    104142  ROTableRow row(t);
    105143  // get first row - there should only be one matching id
     144
    106145  const TableRecord& rec = row.get(0);
    107146  restfreq = rec.asDouble("RESTFREQUENCY");
     
    109148  formattedname = rec.asString("FORMATTEDNAME");
    110149}
     150***/
     151void STMolecules::getEntry( Vector<Double>& restfreq, Vector<String>& name,
     152                            Vector<String>& formattedname, uInt id ) const
     153{
     154  Table t = table_(table_.col("ID") == Int(id) );
     155  if (t.nrow() == 0 ) {
     156    throw(AipsError("STMolecules::getEntry - id out of range"));
     157  }
     158  ROTableRow row(t);
     159  // get first row - there should only be one matching id
     160
     161  const TableRecord& rec = row.get(0);
     162  //restfreq = rec.asDouble("RESTFREQUENCY");
     163  restfreq = rec.asArrayDouble("RESTFREQUENCY");
     164  //name = rec.asString("NAME");
     165  name = rec.asArrayString("NAME");
     166  //formattedname = rec.asString("FORMATTEDNAME");
     167  formattedname = rec.asArrayString("FORMATTEDNAME");
     168}
    111169
    112170std::vector< double > asap::STMolecules::getRestFrequencies( ) const
    113171{
    114172  std::vector<double> out;
     173  //TableProxy itsTable(table_);
     174  //Record rec;
    115175  Vector<Double> rfs = restfreqCol_.getColumn();
    116176  rfs.tovector(out);
     177  //rec = itsTable.getVarColumn("RESTFREQUENCY", 0, 1, 1);
    117178  return out;
    118179}
    119180
    120 double asap::STMolecules::getRestFrequency( uInt id ) const
    121 {
     181std::vector< double > asap::STMolecules::getRestFrequency( uInt id ) const
     182{
     183  std::vector<double> out;
    122184  Table t = table_(table_.col("ID") == Int(id) );
    123185  if (t.nrow() == 0 ) {
     
    126188  ROTableRow row(t);
    127189  const TableRecord& rec = row.get(0);
    128   return double(rec.asDouble("RESTFREQUENCY"));
    129 }
    130 
     190  //return double(rec.asDouble("RESTFREQUENCY"));
     191  Vector<Double> rfs = rec.asArrayDouble("RESTFREQUENCY");
     192  rfs.tovector(out);
     193  return out;
     194}
     195
     196int asap::STMolecules::nrow() const
     197{
     198  return int(table_.nrow());
     199}
    131200
    132201}//namespace
  • trunk/src/STMolecules.h

    r1353 r1819  
    1717#include <tables/Tables/Table.h>
    1818#include <tables/Tables/ScalarColumn.h>
     19#include <tables/Tables/ArrayColumn.h>
     20#include <casa/Arrays/Array.h>
    1921
    2022#include "STSubTable.h"
     
    3739  STMolecules& operator=(const STMolecules& other);
    3840
     41/***
    3942  casa::uInt addEntry( casa::Double restfreq, const casa::String& name="",
    4043                       const casa::String& formattedname="");
     44***/
    4145
     46  casa::uInt addEntry( casa::Vector<casa::Double> restfreq, const casa::Vector<casa::String>& name=casa::Vector<casa::String>(0),
     47                       const casa::Vector<casa::String>& formattedname=casa::Vector<casa::String>(0));
     48
     49/***
    4250  void getEntry( casa::Double& restfreq, casa::String& name,
    4351                 casa::String& formattedname, casa::uInt id) const;
     52***/
     53  void getEntry( casa::Vector<casa::Double>& restfreq, casa::Vector<casa::String>& name,
     54                 casa::Vector<casa::String>& formattedname, casa::uInt id) const;
    4455
    4556  std::vector<double> getRestFrequencies() const;
    46   double getRestFrequency( casa::uInt id ) const;
     57  std::vector<double> getRestFrequency( casa::uInt id ) const;
    4758  const casa::String& name() const { return name_; }
     59  int nrow() const;
    4860
    4961private:
     
    5264  //casa::Table table_;
    5365  //casa::ScalarColumn<casa::uInt> freqidCol_;
    54   casa::ScalarColumn<casa::Double> restfreqCol_;
    55   casa::ScalarColumn<casa::String> nameCol_;
    56   casa::ScalarColumn<casa::String> formattednameCol_; // e.g. latex
     66  //casa::ScalarColumn<casa::Double> restfreqCol_;
     67  casa::ArrayColumn<casa::Double> restfreqCol_;
     68  //casa::ScalarColumn<casa::String> nameCol_;
     69  casa::ArrayColumn<casa::String> nameCol_;
     70  //casa::ScalarColumn<casa::String> formattednameCol_; // e.g. latex
     71  casa::ArrayColumn<casa::String> formattednameCol_; // e.g. latex
    5772
    5873};
  • trunk/src/STSelector.cpp

    r1542 r1819  
    8787}
    8888
     89void STSelector::setTypes( const std::vector< int >& types )
     90{
     91  setint("SRCTYPE", types);
     92}
     93
    8994void STSelector::setint(const std::string& key, const std::vector< int >& val)
    9095{
     
    116121}
    117122
     123void STSelector::setRows( const std::vector< int >& rows )
     124{
     125  rowselection_ = rows;
     126}
     127
     128// Table STSelector::apply( const Table& tab )
     129// {
     130//   if ( empty() ) {
     131//     return sort(tab);
     132//   }
     133//   TableExprNode query;
     134//   intidmap::const_iterator it;
     135//   for (it = intselections_.begin(); it != intselections_.end(); ++it) {
     136//     TableExprNode theset(Vector<Int>( (*it).second ));
     137//     if ( query.isNull() ) {
     138//       query = tab.col((*it).first).in(theset);
     139//     } else {
     140//       query = tab.col((*it).first).in(theset) && query;
     141//     }
     142//   }
     143//   stringidmap::const_iterator it1;
     144//   for (it1 = stringselections_.begin(); it1 != stringselections_.end(); ++it1) {
     145//     TableExprNode theset(mathutil::toVectorString( (*it1).second ));
     146//     if ( query.isNull() ) {
     147//       query = tab.col((*it1).first).in(theset);
     148//     } else {
     149//       query = tab.col((*it1).first).in(theset) && query;
     150//     }
     151//   }
     152//   // add taql query
     153//   if ( taql_.size() > 0 ) {
     154//     Table tmpt = tab;
     155//     std::string pytaql = "USING STYLE PYTHON " + taql_;
     156
     157//     if ( !query.isNull() ) { // taql and selection
     158//       tmpt = tableCommand(pytaql, tab(query));
     159//     } else { // taql only
     160//       tmpt = tableCommand(pytaql, tab);
     161//     }
     162//     return sort(tmpt);
     163//   } else {
     164//     if ( query.isNull() ) {
     165//       return sort(tab);
     166//     } else {
     167//       return sort(tab(query));
     168//     }
     169//   }
     170// }
    118171Table STSelector::apply( const Table& tab )
    119172{
    120173  if ( empty() ) {
    121174    return sort(tab);
     175  }
     176  Table basetab = tab;
     177  // Important!! Be sure to apply row selection first.
     178  if (rowselection_.size() > 0){
     179    //Vector<Int> intrownrs(rowselection_);
     180    Vector<uInt> rownrs( rowselection_.size() );
     181    convertArray(rownrs, Vector<Int> ( rowselection_ ));
     182    basetab = tab( rownrs );
     183    ///TableExprNode theset(Vector<Int>( rowselection_ ));
     184    ///query = tab.nodeRownr().in(theset);
    122185  }
    123186  TableExprNode query;
     
    126189    TableExprNode theset(Vector<Int>( (*it).second ));
    127190    if ( query.isNull() ) {
    128       query = tab.col((*it).first).in(theset);
     191      //query = tab.col((*it).first).in(theset);
     192      query = basetab.col((*it).first).in(theset);
    129193    } else {
    130       query = tab.col((*it).first).in(theset) && query;
     194      //query = tab.col((*it).first).in(theset) && query;
     195      query = basetab.col((*it).first).in(theset) && query;
    131196    }
    132197  }
     
    135200    TableExprNode theset(mathutil::toVectorString( (*it1).second ));
    136201    if ( query.isNull() ) {
    137       query = tab.col((*it1).first).in(theset);
     202      //query = tab.col((*it1).first).in(theset);
     203      query = basetab.col((*it1).first).in(theset);
    138204    } else {
    139       query = tab.col((*it1).first).in(theset) && query;
     205      //query = tab.col((*it1).first).in(theset) && query;
     206      query = basetab.col((*it1).first).in(theset) && query;
    140207    }
    141208  }
    142209  // add taql query
    143210  if ( taql_.size() > 0 ) {
    144     Table tmpt = tab;
     211    //Table tmpt = tab;
     212    Table tmpt = basetab;
    145213    std::string pytaql = "USING STYLE PYTHON " + taql_;
    146214
    147215    if ( !query.isNull() ) { // taql and selection
    148       tmpt = tableCommand(pytaql, tab(query));
     216      //tmpt = tableCommand(pytaql, tab(query));
     217      tmpt = tableCommand(pytaql, basetab(query));
    149218    } else { // taql only
    150       tmpt = tableCommand(pytaql, tab);
     219      //tmpt = tableCommand(pytaql, tab);
     220      tmpt = tableCommand(pytaql, basetab);
    151221    }
    152222    return sort(tmpt);
    153223  } else {
    154224    if ( query.isNull() ) {
    155       return sort(tab);
     225      //return sort(tab);
     226      return sort(basetab);
    156227    } else {
    157       return sort(tab(query));
     228      //return sort(tab(query));
     229      return sort(basetab(query));
    158230    }
    159231  }
     
    191263{
    192264  return getint("CYCLENO");
     265}
     266
     267std::vector< int > asap::STSelector::getTypes( ) const
     268{
     269  return getint("SRCTYPE") ;
    193270}
    194271
     
    227304bool asap::STSelector::empty( ) const
    228305{
    229   return (intselections_.empty() && taql_.size() == 0 );
     306  //return (intselections_.empty() && taql_.size() == 0 );
     307  return (intselections_.empty() && taql_.size() == 0 && rowselection_.size() == 0);
    230308}
    231309
  • trunk/src/STSelector.h

    r939 r1819  
    4545  void setCycles(const std::vector<int>& cycs);
    4646  void setName(const std::string&);
     47  void setTypes(const std::vector<int>& types);
    4748  virtual void setTaQL(const std::string& taql);
    4849
    4950  void setSortOrder(const std::vector<std::string>& order);
     51  void setRows(const std::vector<int>& rows);
    5052
    5153  std::vector<int> getScans() const;
     
    5456  std::vector<int> getPols() const;
    5557  std::vector<int> getCycles() const;
     58  std::vector<int> getTypes() const;
    5659  std::vector<std::string> getPolTypes() const;
    5760  std::string getTaQL() const { return taql_; }
     
    8689  casa::Block<casa::String> order_;
    8790  std::string taql_;
     91  std::vector<int> rowselection_;
    8892};
    8993
  • trunk/src/STWriter.cpp

    r1688 r1819  
    4242#include <atnf/PKSIO/PKSMS2writer.h>
    4343#include <atnf/PKSIO/PKSSDwriter.h>
     44#include <atnf/PKSIO/SrcType.h>
    4445
    4546#include <tables/Tables/Table.h>
     
    154155    havexpol(ifs[i]) = nPol(ifs[i]) > 2;
    155156  }
    156   Vector<String> obstypes(2);
    157   obstypes(0) = "TR";//on
    158   obstypes(1) = "RF TR";//off
     157//   Vector<String> obstypes(2);
     158//   obstypes(0) = "TR";//on
     159//   obstypes(1) = "RF TR";//off
    159160  const Table table = inst->table();
    160161
     
    182183    while (!beamit.pastEnd() ) {
    183184      Table btable = beamit.table();
     185      //MDirection::ScalarColumn dirCol(btable, "DIRECTION");
     186      //pksrec.direction = dirCol(0).getAngle("rad").getValue();
    184187      TableIterator cycit(btable, "CYCLENO");
    185188      ROArrayColumn<Double> srateCol(btable, "SCANRATE");
     
    188191      Vector<Float> srateflt(sratedbl.nelements());
    189192      convertArray(srateflt, sratedbl);
    190       pksrec.scanRate = srateflt;
     193      //pksrec.scanRate = srateflt;
     194      pksrec.scanRate = sratedbl;
    191195      ROArrayColumn<Double> spmCol(btable, "SRCPROPERMOTION");
    192196      spmCol.get(0, pksrec.srcPM);
     
    200204      while (!cycit.pastEnd() ) {
    201205        Table ctable = cycit.table();
    202         TableIterator ifit(ctable, "IFNO");
     206        TableIterator ifit(ctable, "IFNO", TableIterator::Ascending, TableIterator::HeapSort);
    203207        MDirection::ScalarColumn dirCol(ctable, "DIRECTION");
    204208        pksrec.direction = dirCol(0).getAngle("rad").getValue();
     
    213217          uInt nchan = specCol(0).nelements();
    214218          Double crval,crpix;
     219          //Vector<Double> restfreq;
    215220          Float tmp0,tmp1,tmp2,tmp3,tmp4;
    216           String stmp0,stmp1;
     221          String tcalt;
     222          Vector<String> stmp0, stmp1;
    217223          inst->frequencies().getEntry(crpix,crval, pksrec.freqInc,
    218224                                     rec.asuInt("FREQ_ID"));
     
    239245          pksrec.fieldName = rec.asString("FIELDNAME");
    240246          pksrec.srcName   = rec.asString("SRCNAME");
    241           pksrec.obsType   = obstypes[rec.asInt("SRCTYPE")];
     247          //pksrec.obsType   = obstypes[rec.asInt("SRCTYPE")];
     248          pksrec.obsType = getObsTypes( rec.asInt("SRCTYPE") ) ;
    242249          pksrec.bandwidth = nchan * abs(pksrec.freqInc);
    243250          pksrec.azimuth   = rec.asFloat("AZIMUTH");
     
    253260          pksrec.baseSub   = 0.0f;
    254261          pksrec.xCalFctr  = 0.0;
     262          pksrec.flagrow = rec.asuInt("FLAGROW");
    255263
    256264          status = writer_->write(pksrec);
     
    348356}
    349357
    350 }
     358// get obsType string from SRCTYPE value
     359String STWriter::getObsTypes( Int srctype )
     360{
     361  String obsType ;
     362  switch( srctype ) {
     363  case Int(SrcType::PSON):
     364    obsType = "PSON" ;
     365    break ;
     366  case Int(SrcType::PSOFF):
     367    obsType = "PSOFF" ;
     368    break ;
     369  case Int(SrcType::NOD):
     370    obsType = "NOD" ;
     371    break ;
     372  case Int(SrcType::FSON):
     373    obsType = "FSON" ;
     374    break ;
     375  case Int(SrcType::FSOFF):
     376    obsType = "FSOFF" ;
     377    break ;
     378  case Int(SrcType::SKY):
     379    obsType = "SKY" ;
     380    break ;
     381  case Int(SrcType::HOT):
     382    obsType = "HOT" ;
     383    break ;
     384  case Int(SrcType::WARM):
     385    obsType = "WARM" ;
     386    break ;
     387  case Int(SrcType::COLD):
     388    obsType = "COLD" ;
     389    break ;
     390  case Int(SrcType::PONCAL):
     391    obsType = "PSON:CALON" ;
     392    break ;
     393  case Int(SrcType::POFFCAL):
     394    obsType = "PSOFF:CALON" ;
     395    break ;
     396  case Int(SrcType::NODCAL):
     397    obsType = "NOD:CALON" ;
     398    break ;
     399  case Int(SrcType::FONCAL):
     400    obsType = "FSON:CALON" ;
     401    break ;
     402  case Int(SrcType::FOFFCAL):
     403    obsType = "FSOFF:CALOFF" ;
     404    break ;
     405  case Int(SrcType::FSLO):
     406    obsType = "FSLO" ;
     407    break ;
     408  case Int(SrcType::FLOOFF):
     409    obsType = "FS:LOWER:OFF" ;
     410    break ;
     411  case Int(SrcType::FLOSKY):
     412    obsType = "FS:LOWER:SKY" ;
     413    break ;
     414  case Int(SrcType::FLOHOT):
     415    obsType = "FS:LOWER:HOT" ;
     416    break ;
     417  case Int(SrcType::FLOWARM):
     418    obsType = "FS:LOWER:WARM" ;
     419    break ;
     420  case Int(SrcType::FLOCOLD):
     421    obsType = "FS:LOWER:COLD" ;
     422    break ;
     423  case Int(SrcType::FSHI):
     424    obsType = "FSHI" ;
     425    break ;
     426  case Int(SrcType::FHIOFF):
     427    obsType = "FS:HIGHER:OFF" ;
     428    break ;
     429  case Int(SrcType::FHISKY):
     430    obsType = "FS:HIGHER:SKY" ;
     431    break ;
     432  case Int(SrcType::FHIHOT):
     433    obsType = "FS:HIGHER:HOT" ;
     434    break ;
     435  case Int(SrcType::FHIWARM):
     436    obsType = "FS:HIGHER:WARM" ;
     437    break ;
     438  case Int(SrcType::FHICOLD):
     439    obsType = "FS:HIGHER:COLD" ;
     440    break ;
     441  default:
     442    obsType = "NOTYPE" ;
     443  }
     444
     445  return obsType ;
     446}
     447
     448}
  • trunk/src/STWriter.h

    r1391 r1819  
    3636#include <casa/aips.h>
    3737#include <casa/Utilities/CountedPtr.h>
     38#include <casa/BasicSL/String.h>
    3839
    3940#include "Logger.h"
     
    8485  void replacePtTab(const casa::Table& tab, const std::string& fname);
    8586
     87  casa::String getObsTypes( casa::Int srctype ) ;
     88
    8689  std::string     format_;
    8790  PKSwriter* writer_;
  • trunk/src/Scantable.cpp

    r1743 r1819  
    1111//
    1212#include <map>
     13#include <fstream>
    1314
    1415#include <casa/aips.h>
     
    2425#include <casa/Arrays/Vector.h>
    2526#include <casa/Arrays/VectorSTLIterator.h>
     27#include <casa/Arrays/Slice.h>
    2628#include <casa/BasicMath/Math.h>
    2729#include <casa/BasicSL/Constants.h>
     
    2931#include <casa/Containers/RecordField.h>
    3032#include <casa/Utilities/GenSort.h>
     33#include <casa/Logging/LogIO.h>
    3134
    3235#include <tables/Tables/TableParse.h>
     
    106109{
    107110  initFactories();
     111
    108112  Table tab(name, Table::Update);
    109113  uInt version = tab.keywordSet().asuInt("VERSION");
     
    121125  attach();
    122126}
     127/*
     128Scantable::Scantable(const std::string& name, Table::TableType ttype) :
     129  type_(ttype)
     130{
     131  initFactories();
     132  Table tab(name, Table::Update);
     133  uInt version = tab.keywordSet().asuInt("VERSION");
     134  if (version != version_) {
     135    throw(AipsError("Unsupported version of ASAP file."));
     136  }
     137  if ( type_ == Table::Memory ) {
     138    table_ = tab.copyToMemoryTable(generateName());
     139  } else {
     140    table_ = tab;
     141  }
     142
     143  attachSubtables();
     144  originalTable_ = table_;
     145  attach();
     146}
     147*/
    123148
    124149Scantable::Scantable( const Scantable& other, bool clear )
     
    199224  td.addColumn(ScalarColumnDesc<uInt>("FREQ_ID"));
    200225  td.addColumn(ScalarColumnDesc<uInt>("MOLECULE_ID"));
    201   td.addColumn(ScalarColumnDesc<Int>("REFBEAMNO"));
     226
     227  ScalarColumnDesc<Int> refbeamnoColumn("REFBEAMNO");
     228  refbeamnoColumn.setDefault(Int(-1));
     229  td.addColumn(refbeamnoColumn);
     230
     231  ScalarColumnDesc<uInt> flagrowColumn("FLAGROW");
     232  flagrowColumn.setDefault(uInt(0));
     233  td.addColumn(flagrowColumn);
    202234
    203235  td.addColumn(ScalarColumnDesc<Double>("TIME"));
     
    257289  originalTable_ = table_;
    258290}
    259 
    260291
    261292void Scantable::attach()
     
    285316  mfocusidCol_.attach(table_, "FOCUS_ID");
    286317  mmolidCol_.attach(table_, "MOLECULE_ID");
     318
     319  //Add auxiliary column for row-based flagging (CAS-1433 Wataru Kawasaki)
     320  attachAuxColumnDef(flagrowCol_, "FLAGROW", 0);
     321
     322}
     323
     324template<class T, class T2>
     325void Scantable::attachAuxColumnDef(ScalarColumn<T>& col,
     326                                   const String& colName,
     327                                   const T2& defValue)
     328{
     329  try {
     330    col.attach(table_, colName);
     331  } catch (TableError& err) {
     332    String errMesg = err.getMesg();
     333    if (errMesg == "Table column " + colName + " is unknown") {
     334      table_.addColumn(ScalarColumnDesc<T>(colName));
     335      col.attach(table_, colName);
     336      col.fillColumn(static_cast<T>(defValue));
     337    } else {
     338      throw;
     339    }
     340  } catch (...) {
     341    throw;
     342  }
     343}
     344
     345template<class T, class T2>
     346void Scantable::attachAuxColumnDef(ArrayColumn<T>& col,
     347                                   const String& colName,
     348                                   const Array<T2>& defValue)
     349{
     350  try {
     351    col.attach(table_, colName);
     352  } catch (TableError& err) {
     353    String errMesg = err.getMesg();
     354    if (errMesg == "Table column " + colName + " is unknown") {
     355      table_.addColumn(ArrayColumnDesc<T>(colName));
     356      col.attach(table_, colName);
     357
     358      int size = 0;
     359      ArrayIterator<T2>& it = defValue.begin();
     360      while (it != defValue.end()) {
     361        ++size;
     362        ++it;
     363      }
     364      IPosition ip(1, size);
     365      Array<T>& arr(ip);
     366      for (int i = 0; i < size; ++i)
     367        arr[i] = static_cast<T>(defValue[i]);
     368
     369      col.fillColumn(arr);
     370    } else {
     371      throw;
     372    }
     373  } catch (...) {
     374    throw;
     375  }
    287376}
    288377
     
    627716}
    628717
     718void Scantable::clip(const Float uthres, const Float dthres, bool clipoutside, bool unflag)
     719{
     720  for (uInt i=0; i<table_.nrow(); ++i) {
     721    Vector<uChar> flgs = flagsCol_(i);
     722    srchChannelsToClip(i, uthres, dthres, clipoutside, unflag, flgs);
     723    flagsCol_.put(i, flgs);
     724  }
     725}
     726
     727std::vector<bool> Scantable::getClipMask(int whichrow, const Float uthres, const Float dthres, bool clipoutside, bool unflag)
     728{
     729  Vector<uChar> flags;
     730  flagsCol_.get(uInt(whichrow), flags);
     731  srchChannelsToClip(uInt(whichrow), uthres, dthres, clipoutside, unflag, flags);
     732  Vector<Bool> bflag(flags.shape());
     733  convertArray(bflag, flags);
     734  //bflag = !bflag;
     735
     736  std::vector<bool> mask;
     737  bflag.tovector(mask);
     738  return mask;
     739}
     740
     741void Scantable::srchChannelsToClip(uInt whichrow, const Float uthres, const Float dthres, bool clipoutside, bool unflag,
     742                                   Vector<uChar> flgs)
     743{
     744    Vector<Float> spcs = specCol_(whichrow);
     745    uInt nchannel = nchan();
     746    if (spcs.nelements() != nchannel) {
     747      throw(AipsError("Data has incorrect number of channels"));
     748    }
     749    uChar userflag = 1 << 7;
     750    if (unflag) {
     751      userflag = 0 << 7;
     752    }
     753    if (clipoutside) {
     754      for (uInt j = 0; j < nchannel; ++j) {
     755        Float spc = spcs(j);
     756        if ((spc >= uthres) || (spc <= dthres)) {
     757          flgs(j) = userflag;
     758        }
     759      }
     760    } else {
     761      for (uInt j = 0; j < nchannel; ++j) {
     762        Float spc = spcs(j);
     763        if ((spc < uthres) && (spc > dthres)) {
     764          flgs(j) = userflag;
     765        }
     766      }
     767    }
     768}
     769
    629770void Scantable::flag(const std::vector<bool>& msk, bool unflag)
    630771{
     
    673814    flagsCol_.put(i, flgs);
    674815  }
     816}
     817
     818void Scantable::flagRow(const std::vector<uInt>& rows, bool unflag)
     819{
     820  if ( selector_.empty() && (rows.size() == table_.nrow()) )
     821    throw(AipsError("Trying to flag whole scantable."));
     822
     823  uInt rowflag = (unflag ? 0 : 1);
     824  std::vector<uInt>::const_iterator it;
     825  for (it = rows.begin(); it != rows.end(); ++it)
     826    flagrowCol_.put(*it, rowflag);
    675827}
    676828
     
    793945  table_.keywordSet().get("FluxUnit", tmp);
    794946  oss << setw(15) << "Flux Unit:" << tmp << endl;
    795   Vector<Double> vec(moleculeTable_.getRestFrequencies());
     947  //Vector<Double> vec(moleculeTable_.getRestFrequencies());
     948  int nid = moleculeTable_.nrow();
     949  Bool firstline = True;
    796950  oss << setw(15) << "Rest Freqs:";
    797   if (vec.nelements() > 0) {
    798       oss << setprecision(10) << vec << " [Hz]" << endl;
    799   } else {
    800       oss << "none" << endl;
     951  for (int i=0; i<nid; i++) {
     952      Table t = table_(table_.col("MOLECULE_ID") == i);
     953      if (t.nrow() >  0) {
     954          Vector<Double> vec(moleculeTable_.getRestFrequency(i));
     955          if (vec.nelements() > 0) {
     956               if (firstline) {
     957                   oss << setprecision(10) << vec << " [Hz]" << endl;
     958                   firstline=False;
     959               }
     960               else{
     961                   oss << setw(15)<<" " << setprecision(10) << vec << " [Hz]" << endl;
     962               }
     963          } else {
     964              oss << "none" << endl;
     965          }
     966      }
    801967  }
    802968
     
    9011067  const MDirection& md = getDirection(whichrow);
    9021068  const MEpoch& me = timeCol_(whichrow);
    903   Double rf = moleculeTable_.getRestFrequency(mmolidCol_(whichrow));
     1069  //Double rf = moleculeTable_.getRestFrequency(mmolidCol_(whichrow));
     1070  Vector<Double> rf = moleculeTable_.getRestFrequency(mmolidCol_(whichrow));
    9041071  return freqTable_.getSpectralCoordinate(md, mp, me, rf,
    9051072                                          mfreqidCol_(whichrow));
     
    9751142  const MDirection& md = getDirection(whichrow);
    9761143  const MEpoch& me = timeCol_(whichrow);
    977   const Double& rf = mmolidCol_(whichrow);
     1144  //const Double& rf = mmolidCol_(whichrow);
     1145  const Vector<Double> rf = moleculeTable_.getRestFrequency(mmolidCol_(whichrow));
    9781146  SpectralCoordinate spc =
    9791147    freqTable_.getSpectralCoordinate(md, mp, me, rf, mfreqidCol_(whichrow));
     
    9921160}
    9931161
    994 void Scantable::setRestFrequencies( double rf, const std::string& name,
     1162/**
     1163void asap::Scantable::setRestFrequencies( double rf, const std::string& name,
    9951164                                          const std::string& unit )
     1165**/
     1166void Scantable::setRestFrequencies( vector<double> rf, const vector<std::string>& name,
     1167                                          const std::string& unit )
     1168
    9961169{
    9971170  ///@todo lookup in line table to fill in name and formattedname
    9981171  Unit u(unit);
    999   Quantum<Double> urf(rf, u);
    1000   uInt id = moleculeTable_.addEntry(urf.getValue("Hz"), name, "");
     1172  //Quantum<Double> urf(rf, u);
     1173  Quantum<Vector<Double> >urf(rf, u);
     1174  Vector<String> formattedname(0);
     1175  //cerr<<"Scantable::setRestFrequnecies="<<urf<<endl;
     1176
     1177  //uInt id = moleculeTable_.addEntry(urf.getValue("Hz"), name, "");
     1178  uInt id = moleculeTable_.addEntry(urf.getValue("Hz"), mathutil::toVectorString(name), formattedname);
    10011179  TableVector<uInt> tabvec(table_, "MOLECULE_ID");
    10021180  tabvec = id;
    10031181}
    10041182
    1005 void Scantable::setRestFrequencies( const std::string& name )
     1183/**
     1184void asap::Scantable::setRestFrequencies( const std::string& name )
    10061185{
    10071186  throw(AipsError("setRestFrequencies( const std::string& name ) NYI"));
     1187  ///@todo implement
     1188}
     1189**/
     1190void Scantable::setRestFrequencies( const vector<std::string>& name )
     1191{
     1192  throw(AipsError("setRestFrequencies( const vector<std::string>& name ) NYI"));
    10081193  ///@todo implement
    10091194}
     
    10441229void Scantable::addFit( const STFitEntry& fit, int row )
    10451230{
    1046   cout << mfitidCol_(uInt(row)) << endl;
     1231  //cout << mfitidCol_(uInt(row)) << endl;
     1232  LogIO os( LogOrigin( "Scantable", "addFit()", WHERE ) ) ;
     1233  os << mfitidCol_(uInt(row)) << LogIO::POST ;
    10471234  uInt id = fitTable_.addEntry(fit, mfitidCol_(uInt(row)));
    10481235  mfitidCol_.put(uInt(row), id);
     
    10591246}
    10601247
    1061 std::string Scantable::getAntennaName() const
     1248String Scantable::getAntennaName() const
    10621249{
    10631250  String out;
     
    10781265      Table subt = t( t.col("SCAN") == scanlist[i]+1 );
    10791266      if (subt.nrow()==0) {
    1080         cerr <<"Scan "<<scanlist[i]<<" cannot be found in the scantable."<<endl;
     1267        //cerr <<"Scan "<<scanlist[i]<<" cannot be found in the scantable."<<endl;
     1268        LogIO os( LogOrigin( "Scantable", "checkScanInfo()", WHERE ) ) ;
     1269        os <<LogIO::WARN<<"Scan "<<scanlist[i]<<" cannot be found in the scantable."<<LogIO::POST;
    10811270        ret = 1;
    10821271        break;
     
    10901279          Table subt2 = t( t.col("SCAN") == scanlist[i+1]+1 );
    10911280          if ( subt2.nrow() == 0) {
    1092             cerr<<"Scan "<<scanlist[i+1]<<" cannot be found in the scantable."<<endl;
     1281            LogIO os( LogOrigin( "Scantable", "checkScanInfo()", WHERE ) ) ;
     1282
     1283            //cerr<<"Scan "<<scanlist[i+1]<<" cannot be found in the scantable."<<endl;
     1284            os<<LogIO::WARN<<"Scan "<<scanlist[i+1]<<" cannot be found in the scantable."<<LogIO::POST;
    10931285            ret = 1;
    10941286            break;
     
    11001292          if (scan1seqn == 1 && scan2seqn == 2) {
    11011293            if (laston1 == laston2) {
    1102               cerr<<"A valid scan pair ["<<scanlist[i]<<","<<scanlist[i+1]<<"]"<<endl;
     1294              LogIO os( LogOrigin( "Scantable", "checkScanInfo()", WHERE ) ) ;
     1295              //cerr<<"A valid scan pair ["<<scanlist[i]<<","<<scanlist[i+1]<<"]"<<endl;
     1296              os<<"A valid scan pair ["<<scanlist[i]<<","<<scanlist[i+1]<<"]"<<LogIO::POST;
    11031297              i +=1;
    11041298            }
    11051299            else {
    1106               cerr<<"Incorrect scan pair ["<<scanlist[i]<<","<<scanlist[i+1]<<"]"<<endl;
     1300              LogIO os( LogOrigin( "Scantable", "checkScanInfo()", WHERE ) ) ;
     1301              //cerr<<"Incorrect scan pair ["<<scanlist[i]<<","<<scanlist[i+1]<<"]"<<endl;
     1302              os<<LogIO::WARN<<"Incorrect scan pair ["<<scanlist[i]<<","<<scanlist[i+1]<<"]"<<LogIO::POST;
    11071303            }
    11081304          }
    11091305          else if (scan1seqn==2 && scan2seqn == 1) {
    11101306            if (laston1 == laston2) {
    1111               cerr<<"["<<scanlist[i]<<","<<scanlist[i+1]<<"] is a valid scan pair but in incorrect order."<<endl;
     1307              LogIO os( LogOrigin( "Scantable", "checkScanInfo()", WHERE ) ) ;
     1308              //cerr<<"["<<scanlist[i]<<","<<scanlist[i+1]<<"] is a valid scan pair but in incorrect order."<<endl;
     1309              os<<LogIO::WARN<<"["<<scanlist[i]<<","<<scanlist[i+1]<<"] is a valid scan pair but in incorrect order."<<LogIO::POST;
    11121310              ret = 1;
    11131311              break;
     
    11151313          }
    11161314          else {
    1117             cerr<<"The other scan for  "<<scanlist[i]<<" appears to be missing. Check the input scan numbers."<<endl;
     1315            LogIO os( LogOrigin( "Scantable", "checkScanInfo()", WHERE ) ) ;
     1316            //cerr<<"The other scan for  "<<scanlist[i]<<" appears to be missing. Check the input scan numbers."<<endl;
     1317            os<<LogIO::WARN<<"The other scan for  "<<scanlist[i]<<" appears to be missing. Check the input scan numbers."<<LogIO::POST;
    11181318            ret = 1;
    11191319            break;
     
    11221322      }
    11231323      else {
    1124         cerr<<"The scan does not appear to be standard obsevation."<<endl;
     1324        LogIO os( LogOrigin( "Scantable", "checkScanInfo()", WHERE ) ) ;
     1325        //cerr<<"The scan does not appear to be standard obsevation."<<endl;
     1326        os<<LogIO::WARN<<"The scan does not appear to be standard obsevation."<<LogIO::POST;
    11251327      }
    11261328    //if ( i >= nscan ) break;
     
    11281330  }
    11291331  else {
    1130     cerr<<"No reference to GBT_GO table."<<endl;
     1332    LogIO os( LogOrigin( "Scantable", "checkScanInfo()", WHERE ) ) ;
     1333    //cerr<<"No reference to GBT_GO table."<<endl;
     1334    os<<LogIO::WARN<<"No reference to GBT_GO table."<<LogIO::POST;
    11311335    ret = 1;
    11321336  }
     
    11421346}
    11431347
     1348void asap::Scantable::reshapeSpectrum( int nmin, int nmax )
     1349  throw( casa::AipsError )
     1350{
     1351  // assumed that all rows have same nChan
     1352  Vector<Float> arr = specCol_( 0 ) ;
     1353  int nChan = arr.nelements() ;
     1354
     1355  // if nmin < 0 or nmax < 0, nothing to do
     1356  if (  nmin < 0 ) {
     1357    throw( casa::indexError<int>( nmin, "asap::Scantable::reshapeSpectrum: Invalid range. Negative index is specified." ) ) ;
     1358    }
     1359  if (  nmax < 0  ) {
     1360    throw( casa::indexError<int>( nmax, "asap::Scantable::reshapeSpectrum: Invalid range. Negative index is specified." ) ) ;
     1361  }
     1362
     1363  // if nmin > nmax, exchange values
     1364  if ( nmin > nmax ) {
     1365    int tmp = nmax ;
     1366    nmax = nmin ;
     1367    nmin = tmp ;
     1368    LogIO os( LogOrigin( "Scantable", "reshapeSpectrum()", WHERE ) ) ;
     1369    os << "Swap values. Applied range is ["
     1370       << nmin << ", " << nmax << "]" << LogIO::POST ;
     1371  }
     1372
     1373  // if nmin exceeds nChan, nothing to do
     1374  if ( nmin >= nChan ) {
     1375    throw( casa::indexError<int>( nmin, "asap::Scantable::reshapeSpectrum: Invalid range. Specified minimum exceeds nChan." ) ) ;
     1376  }
     1377
     1378  // if nmax exceeds nChan, reset nmax to nChan
     1379  if ( nmax >= nChan ) {
     1380    if ( nmin == 0 ) {
     1381      // nothing to do
     1382      LogIO os( LogOrigin( "Scantable", "reshapeSpectrum()", WHERE ) ) ;
     1383      os << "Whole range is selected. Nothing to do." << LogIO::POST ;
     1384      return ;
     1385    }
     1386    else {
     1387      LogIO os( LogOrigin( "Scantable", "reshapeSpectrum()", WHERE ) ) ;
     1388      os << "Specified maximum exceeds nChan. Applied range is ["
     1389         << nmin << ", " << nChan-1 << "]." << LogIO::POST ;
     1390      nmax = nChan - 1 ;
     1391    }
     1392  }
     1393
     1394  // reshape specCol_ and flagCol_
     1395  for ( int irow = 0 ; irow < nrow() ; irow++ ) {
     1396    reshapeSpectrum( nmin, nmax, irow ) ;
     1397  }
     1398
     1399  // update FREQUENCIES subtable
     1400  Double refpix ;
     1401  Double refval ;
     1402  Double increment ;
     1403  int freqnrow = freqTable_.table().nrow() ;
     1404  Vector<uInt> oldId( freqnrow ) ;
     1405  Vector<uInt> newId( freqnrow ) ;
     1406  for ( int irow = 0 ; irow < freqnrow ; irow++ ) {
     1407    freqTable_.getEntry( refpix, refval, increment, irow ) ;
     1408    /***
     1409     * need to shift refpix to nmin
     1410     * note that channel nmin in old index will be channel 0 in new one
     1411     ***/
     1412    refval = refval - ( refpix - nmin ) * increment ;
     1413    refpix = 0 ;
     1414    freqTable_.setEntry( refpix, refval, increment, irow ) ;
     1415  }
     1416
     1417  // update nchan
     1418  int newsize = nmax - nmin + 1 ;
     1419  table_.rwKeywordSet().define( "nChan", newsize ) ;
     1420
     1421  // update bandwidth
     1422  // assumed all spectra in the scantable have same bandwidth
     1423  table_.rwKeywordSet().define( "Bandwidth", increment * newsize ) ;
     1424
     1425  return ;
     1426}
     1427
     1428void asap::Scantable::reshapeSpectrum( int nmin, int nmax, int irow )
     1429{
     1430  // reshape specCol_ and flagCol_
     1431  Vector<Float> oldspec = specCol_( irow ) ;
     1432  Vector<uChar> oldflag = flagsCol_( irow ) ;
     1433  uInt newsize = nmax - nmin + 1 ;
     1434  specCol_.put( irow, oldspec( Slice( nmin, newsize, 1 ) ) ) ;
     1435  flagsCol_.put( irow, oldflag( Slice( nmin, newsize, 1 ) ) ) ;
     1436
     1437  return ;
     1438}
     1439
     1440void asap::Scantable::regridChannel( int nChan, double dnu )
     1441{
     1442  LogIO os( LogOrigin( "Scantable", "regridChannel()", WHERE ) ) ;
     1443  os << "Regrid abcissa with channel number " << nChan << " and spectral resoultion " << dnu << "Hz." << LogIO::POST ;
     1444  // assumed that all rows have same nChan
     1445  Vector<Float> arr = specCol_( 0 ) ;
     1446  int oldsize = arr.nelements() ;
     1447
     1448  // if oldsize == nChan, nothing to do
     1449  if ( oldsize == nChan ) {
     1450    os << "Specified channel number is same as current one. Nothing to do." << LogIO::POST ;
     1451    return ;
     1452  }
     1453
     1454  // if oldChan < nChan, unphysical operation
     1455  if ( oldsize < nChan ) {
     1456    os << "Unphysical operation. Nothing to do." << LogIO::POST ;
     1457    return ;
     1458  }
     1459
     1460  // change channel number for specCol_ and flagCol_
     1461  Vector<Float> newspec( nChan, 0 ) ;
     1462  Vector<uChar> newflag( nChan, false ) ;
     1463  vector<string> coordinfo = getCoordInfo() ;
     1464  string oldinfo = coordinfo[0] ;
     1465  coordinfo[0] = "Hz" ;
     1466  setCoordInfo( coordinfo ) ;
     1467  for ( int irow = 0 ; irow < nrow() ; irow++ ) {
     1468    regridChannel( nChan, dnu, irow ) ;
     1469  }
     1470  coordinfo[0] = oldinfo ;
     1471  setCoordInfo( coordinfo ) ;
     1472
     1473
     1474  // NOTE: this method does not update metadata such as
     1475  //       FREQUENCIES subtable, nChan, Bandwidth, etc.
     1476
     1477  return ;
     1478}
     1479
     1480void asap::Scantable::regridChannel( int nChan, double dnu, int irow )
     1481{
     1482  // logging
     1483  //ofstream ofs( "average.log", std::ios::out | std::ios::app ) ;
     1484  //ofs << "IFNO = " << getIF( irow ) << " irow = " << irow << endl ;
     1485
     1486  Vector<Float> oldspec = specCol_( irow ) ;
     1487  Vector<uChar> oldflag = flagsCol_( irow ) ;
     1488  Vector<Float> newspec( nChan, 0 ) ;
     1489  Vector<uChar> newflag( nChan, false ) ;
     1490
     1491  // regrid
     1492  vector<double> abcissa = getAbcissa( irow ) ;
     1493  int oldsize = abcissa.size() ;
     1494  double olddnu = abcissa[1] - abcissa[0] ;
     1495  //int refChan = 0 ;
     1496  //double frac = 0.0 ;
     1497  //double wedge = 0.0 ;
     1498  //double pile = 0.0 ;
     1499  int ichan = 0 ;
     1500  double wsum = 0.0 ;
     1501  Vector<Float> z( nChan ) ;
     1502  z[0] = abcissa[0] - 0.5 * olddnu + 0.5 * dnu ;
     1503  for ( int ii = 1 ; ii < nChan ; ii++ )
     1504    z[ii] = z[ii-1] + dnu ;
     1505  Vector<Float> zi( nChan+1 ) ;
     1506  Vector<Float> yi( oldsize + 1 ) ;
     1507  zi[0] = z[0] - 0.5 * dnu ;
     1508  zi[1] = z[0] + 0.5 * dnu ;
     1509  for ( int ii = 2 ; ii < nChan ; ii++ )
     1510    zi[ii] = zi[ii-1] + dnu ;
     1511  zi[nChan] = z[nChan-1] + 0.5 * dnu ;
     1512  yi[0] = abcissa[0] - 0.5 * olddnu ;
     1513  yi[1] = abcissa[1] + 0.5 * olddnu ;
     1514  for ( int ii = 2 ; ii < oldsize ; ii++ )
     1515    yi[ii] = abcissa[ii-1] + olddnu ;
     1516  yi[oldsize] = abcissa[oldsize-1] + 0.5 * olddnu ;
     1517  if ( dnu > 0.0 ) {
     1518    for ( int ii = 0 ; ii < nChan ; ii++ ) {
     1519      double zl = zi[ii] ;
     1520      double zr = zi[ii+1] ;
     1521      for ( int j = ichan ; j < oldsize ; j++ ) {
     1522        double yl = yi[j] ;
     1523        double yr = yi[j+1] ;
     1524        if ( yl <= zl ) {
     1525          if ( yr <= zl ) {
     1526            continue ;
     1527          }
     1528          else if ( yr <= zr ) {
     1529            newspec[ii] += oldspec[j] * ( yr - zl ) ;
     1530            newflag[ii] = newflag[ii] || oldflag[j] ;
     1531            wsum += ( yr - zl ) ;
     1532          }
     1533          else {
     1534            newspec[ii] += oldspec[j] * dnu ;
     1535            newflag[ii] = newflag[ii] || oldflag[j] ;
     1536            wsum += dnu ;
     1537            ichan = j ;
     1538            break ;
     1539          }
     1540        }
     1541        else if ( yl < zr ) {
     1542          if ( yr <= zr ) {
     1543              newspec[ii] += oldspec[j] * ( yr - yl ) ;
     1544              newflag[ii] = newflag[ii] || oldflag[j] ;
     1545              wsum += ( yr - yl ) ;
     1546          }
     1547          else {
     1548            newspec[ii] += oldspec[j] * ( zr - yl ) ;
     1549            newflag[ii] = newflag[ii] || oldflag[j] ;
     1550            wsum += ( zr - yl ) ;
     1551            ichan = j ;
     1552            break ;
     1553          }
     1554        }
     1555        else {
     1556          ichan = j - 1 ;
     1557          break ;
     1558        }
     1559      }
     1560      newspec[ii] /= wsum ;
     1561      wsum = 0.0 ;
     1562    }
     1563  }
     1564  else if ( dnu < 0.0 ) {
     1565    for ( int ii = 0 ; ii < nChan ; ii++ ) {
     1566      double zl = zi[ii] ;
     1567      double zr = zi[ii+1] ;
     1568      for ( int j = ichan ; j < oldsize ; j++ ) {
     1569        double yl = yi[j] ;
     1570        double yr = yi[j+1] ;
     1571        if ( yl >= zl ) {
     1572          if ( yr >= zl ) {
     1573            continue ;
     1574          }
     1575          else if ( yr >= zr ) {
     1576            newspec[ii] += oldspec[j] * abs( yr - zl ) ;
     1577            newflag[ii] = newflag[ii] || oldflag[j] ;
     1578            wsum += abs( yr - zl ) ;
     1579          }
     1580          else {
     1581            newspec[ii] += oldspec[j] * abs( dnu ) ;
     1582            newflag[ii] = newflag[ii] || oldflag[j] ;
     1583            wsum += abs( dnu ) ;
     1584            ichan = j ;
     1585            break ;
     1586          }
     1587        }
     1588        else if ( yl > zr ) {
     1589          if ( yr >= zr ) {
     1590            newspec[ii] += oldspec[j] * abs( yr - yl ) ;
     1591            newflag[ii] = newflag[ii] || oldflag[j] ;
     1592            wsum += abs( yr - yl ) ;
     1593          }
     1594          else {
     1595            newspec[ii] += oldspec[j] * abs( zr - yl ) ;
     1596            newflag[ii] = newflag[ii] || oldflag[j] ;
     1597            wsum += abs( zr - yl ) ;
     1598            ichan = j ;
     1599            break ;
     1600          }
     1601        }
     1602        else {
     1603          ichan = j - 1 ;
     1604          break ;
     1605        }
     1606      }
     1607      newspec[ii] /= wsum ;
     1608      wsum = 0.0 ;
     1609    }
     1610  }
     1611//    * ichan = 0
     1612//    ***/
     1613//   //ofs << "olddnu = " << olddnu << ", dnu = " << dnu << endl ;
     1614//   pile += dnu ;
     1615//   wedge = olddnu * ( refChan + 1 ) ;
     1616//   while ( wedge < pile ) {
     1617//     newspec[0] += olddnu * oldspec[refChan] ;
     1618//     newflag[0] = newflag[0] || oldflag[refChan] ;
     1619//     //ofs << "channel " << refChan << " is included in new channel 0" << endl ;
     1620//     refChan++ ;
     1621//     wedge += olddnu ;
     1622//     wsum += olddnu ;
     1623//     //ofs << "newspec[0] = " << newspec[0] << " wsum = " << wsum << endl ;
     1624//   }
     1625//   frac = ( wedge - pile ) / olddnu ;
     1626//   wsum += ( 1.0 - frac ) * olddnu ;
     1627//   newspec[0] += ( 1.0 - frac ) * olddnu * oldspec[refChan] ;
     1628//   newflag[0] = newflag[0] || oldflag[refChan] ;
     1629//   //ofs << "channel " << refChan << " is partly included in new channel 0" << " with fraction of " << ( 1.0 - frac ) << endl ;
     1630//   //ofs << "newspec[0] = " << newspec[0] << " wsum = " << wsum << endl ;
     1631//   newspec[0] /= wsum ;
     1632//   //ofs << "newspec[0] = " << newspec[0] << endl ;
     1633//   //ofs << "wedge = " << wedge << ", pile = " << pile << endl ;
     1634
     1635//   /***
     1636//    * ichan = 1 - nChan-2
     1637//    ***/
     1638//   for ( int ichan = 1 ; ichan < nChan - 1 ; ichan++ ) {
     1639//     pile += dnu ;
     1640//     newspec[ichan] += frac * olddnu * oldspec[refChan] ;
     1641//     newflag[ichan] = newflag[ichan] || oldflag[refChan] ;
     1642//     //ofs << "channel " << refChan << " is partly included in new channel " << ichan << " with fraction of " << frac << endl ;
     1643//     refChan++ ;
     1644//     wedge += olddnu ;
     1645//     wsum = frac * olddnu ;
     1646//     //ofs << "newspec[" << ichan << "] = " << newspec[ichan] << " wsum = " << wsum << endl ;
     1647//     while ( wedge < pile ) {
     1648//       newspec[ichan] += olddnu * oldspec[refChan] ;
     1649//       newflag[ichan] = newflag[ichan] || oldflag[refChan] ;
     1650//       //ofs << "channel " << refChan << " is included in new channel " << ichan << endl ;
     1651//       refChan++ ;
     1652//       wedge += olddnu ;
     1653//       wsum += olddnu ;
     1654//       //ofs << "newspec[" << ichan << "] = " << newspec[ichan] << " wsum = " << wsum << endl ;
     1655//     }
     1656//     frac = ( wedge - pile ) / olddnu ;
     1657//     wsum += ( 1.0 - frac ) * olddnu ;
     1658//     newspec[ichan] += ( 1.0 - frac ) * olddnu * oldspec[refChan] ;
     1659//     newflag[ichan] = newflag[ichan] || oldflag[refChan] ;
     1660//     //ofs << "channel " << refChan << " is partly included in new channel " << ichan << " with fraction of " << ( 1.0 - frac ) << endl ;
     1661//     //ofs << "wedge = " << wedge << ", pile = " << pile << endl ;
     1662//     //ofs << "newspec[" << ichan << "] = " << newspec[ichan] << " wsum = " << wsum << endl ;
     1663//     newspec[ichan] /= wsum ;
     1664//     //ofs << "newspec[" << ichan << "] = " << newspec[ichan] << endl ;
     1665//   }
     1666
     1667//   /***
     1668//    * ichan = nChan-1
     1669//    ***/
     1670//   // NOTE: Assumed that all spectra have the same bandwidth
     1671//   pile += dnu ;
     1672//   newspec[nChan-1] += frac * olddnu * oldspec[refChan] ;
     1673//   newflag[nChan-1] = newflag[nChan-1] || oldflag[refChan] ;
     1674//   //ofs << "channel " << refChan << " is partly included in new channel " << nChan-1 << " with fraction of " << frac << endl ;
     1675//   refChan++ ;
     1676//   wedge += olddnu ;
     1677//   wsum = frac * olddnu ;
     1678//   //ofs << "newspec[" << nChan - 1 << "] = " << newspec[nChan-1] << " wsum = " << wsum << endl ;
     1679//   for ( int jchan = refChan ; jchan < oldsize ; jchan++ ) {
     1680//     newspec[nChan-1] += olddnu * oldspec[jchan] ;
     1681//     newflag[nChan-1] = newflag[nChan-1] || oldflag[jchan] ;
     1682//     wsum += olddnu ;
     1683//     //ofs << "channel " << jchan << " is included in new channel " << nChan-1 << " with fraction of " << frac << endl ;
     1684//     //ofs << "newspec[" << nChan - 1 << "] = " << newspec[nChan-1] << " wsum = " << wsum << endl ;
     1685//   }
     1686//   //ofs << "wedge = " << wedge << ", pile = " << pile << endl ;
     1687//   //ofs << "newspec[" << nChan - 1 << "] = " << newspec[nChan-1] << " wsum = " << wsum << endl ;
     1688//   newspec[nChan-1] /= wsum ;
     1689//   //ofs << "newspec[" << nChan - 1 << "] = " << newspec[nChan-1] << endl ;
     1690
     1691//   specCol_.put( irow, newspec ) ;
     1692//   flagsCol_.put( irow, newflag ) ;
     1693
     1694//   // ofs.close() ;
     1695
     1696
     1697  return ;
     1698}
     1699
    11441700std::vector<float> Scantable::getWeather(int whichrow) const
    11451701{
     
    11541710
    11551711}
    1156  //namespace asap
     1712//namespace asap
  • trunk/src/Scantable.h

    r1730 r1819  
    2929
    3030#include <coordinates/Coordinates/SpectralCoordinate.h>
     31
     32#include <casa/Arrays/Vector.h>
     33#include <casa/Quanta/Quantum.h>
     34
     35#include <casa/Exceptions/Error.h>
    3136
    3237#include "Logger.h"
     
    226231
    227232  /**
     233   * Flag the data in a row-based manner. (CAS-1433 Wataru Kawasaki)
     234   * param[in] rows    list of row numbers to be flagged
     235   */
     236  void flagRow( const std::vector<casa::uInt>& rows = std::vector<casa::uInt>(), bool unflag=false);
     237
     238  /**
     239   * Get flagRow info at the specified row. If true, the whole data
     240   * at the row should be flagged.
     241   */
     242  bool getFlagRow(int whichrow) const
     243    { return (flagrowCol_(whichrow) > 0); }
     244
     245  /**
     246   * Flag the data outside a specified range (in a channel-based manner).
     247   * (CAS-1807 Wataru Kawasaki)
     248   */
     249  void clip(const casa::Float uthres, const casa::Float dthres, bool clipoutside, bool unflag);
     250
     251  /**
     252   * Return a list of booleans with the size of nchan for a specified row, to get info
     253   * about which channel is clipped.
     254   */
     255  std::vector<bool> getClipMask(int whichrow, const casa::Float uthres, const casa::Float dthres, bool clipoutside, bool unflag);
     256  void srchChannelsToClip(casa::uInt whichrow, const casa::Float uthres, const casa::Float dthres, bool clipoutside, bool unflag,
     257                          casa::Vector<casa::uChar> flgs);
     258
     259  /**
    228260   * Return a list of row numbers with respect to the original table.
    229261   * @return a list of unsigned ints
     
    276308  std::vector<uint> getScanNos() const { return getNumbers(scanCol_); }
    277309  int getScan(int whichrow) const { return scanCol_(whichrow); }
     310
     311  //TT addition
     312  std::vector<uint> getMolNos() {return getNumbers(mmolidCol_); }
    278313
    279314  /**
     
    300335    { return azCol_(whichrow); }
    301336  float getParAngle(int whichrow) const
    302   { return focus().getParAngle(mfocusidCol_(whichrow)); }
     337    { return focus().getParAngle(mfocusidCol_(whichrow)); }
     338  int getTcalId(int whichrow) const
     339    { return mtcalidCol_(whichrow); }
    303340
    304341  std::string getSourceName(int whichrow) const
     
    353390  std::vector<double> getRestFrequencies() const
    354391    { return moleculeTable_.getRestFrequencies(); }
    355 
     392  std::vector<double> getRestFrequency(int id) const
     393    { return moleculeTable_.getRestFrequency(id); }
     394
     395  /**
    356396  void setRestFrequencies(double rf, const std::string& name = "",
    357397                          const std::string& = "Hz");
    358   void setRestFrequencies(const std::string& name);
     398  **/
     399  // Modified by Takeshi Nakazato 05/09/2008
     400  /***
     401  void setRestFrequencies(vector<double> rf, const vector<std::string>& name = "",
     402                          const std::string& = "Hz");
     403  ***/
     404  void setRestFrequencies(vector<double> rf,
     405                          const vector<std::string>& name = vector<std::string>(1,""),
     406                          const std::string& = "Hz");
     407
     408  //void setRestFrequencies(const std::string& name);
     409  void setRestFrequencies(const vector<std::string>& name);
    359410
    360411  void shift(int npix);
     
    390441   * @return antenna name string
    391442   */
    392   std::string getAntennaName() const;
     443  casa::String getAntennaName() const;
    393444
    394445  /**
     
    414465  void parallactify(bool flag)
    415466    { focus().setParallactify(flag); }
     467
     468  /**
     469   * Reshape spectrum
     470   * @param[in] nmin, nmax minimum and maximum channel
     471   * @param[in] irow       row number
     472   *
     473   * 30/07/2008 Takeshi Nakazato
     474   **/
     475  void reshapeSpectrum( int nmin, int nmax ) throw( casa::AipsError );
     476  void reshapeSpectrum( int nmin, int nmax, int irow ) ;
     477
     478  /**
     479   * Change channel number under fixed bandwidth
     480   * @param[in] nchan, dnu new channel number and spectral resolution
     481   * @param[in] irow       row number
     482   *
     483   * 27/08/2008 Takeshi Nakazato
     484   **/
     485  void regridChannel( int nchan, double dnu ) ;
     486  void regridChannel( int nchan, double dnu, int irow ) ;
     487
    416488
    417489private:
     
    489561  casa::ScalarColumn<casa::Float> elCol_;
    490562  casa::ScalarColumn<casa::String> srcnCol_, fldnCol_;
    491   casa::ScalarColumn<casa::uInt> scanCol_, beamCol_, ifCol_, polCol_, cycleCol_;
     563  casa::ScalarColumn<casa::uInt> scanCol_, beamCol_, ifCol_, polCol_, cycleCol_, flagrowCol_;
    492564  casa::ScalarColumn<casa::Int> rbeamCol_, srctCol_;
    493565  casa::ArrayColumn<casa::Float> specCol_, tsysCol_;
     
    510582  void initFactories();
    511583
     584  /**
     585   * Add an auxiliary column to the main table and attach it to a
     586   * cached column. Use for adding new columns that the original asap2
     587   * tables do not have.
     588   * @param[in] col      reference to the cached column to be attached
     589   * @param[in] colName  column name in asap table
     590   * @param[in] defValue default value to fill in the column
     591   *
     592   * 25/10/2009 Wataru Kawasaki
     593   */
     594  template<class T, class T2> void attachAuxColumnDef(casa::ScalarColumn<T>&,
     595                                                       const casa::String&,
     596                                                       const T2&);
     597  template<class T, class T2> void attachAuxColumnDef(casa::ArrayColumn<T>&,
     598                                                      const casa::String&,
     599                                                      const casa::Array<T2>&);
    512600};
    513601
  • trunk/src/ScantableWrapper.h

    r1730 r1819  
    109109    { table_->flag(msk, unflag); }
    110110
     111  void flagRow(const std::vector<casa::uInt>& rows=std::vector<casa::uInt>(), bool unflag=false)
     112    { table_->flagRow(rows, unflag); }
     113
     114  bool getFlagRow(int whichrow=0) const
     115    { return table_->getFlagRow(whichrow); }
     116
     117  void clip(const casa::Float uthres, const casa::Float dthres, bool clipoutside=true, bool unflag=false)
     118    { table_->clip(uthres, dthres, clipoutside, unflag); }
     119
     120  std::vector<bool> getClipMask(int whichrow, const casa::Float uthres, const casa::Float dthres, bool clipoutside, bool unflag) const
     121    { return table_->getClipMask(whichrow, uthres, dthres, clipoutside, unflag); }
     122
    111123  std::string getSourceName(int whichrow=0) const
    112124    { return table_->getSourceName(whichrow); }
     
    134146  std::vector<uint> getScanNos() { return table_->getScanNos(); }
    135147  int getScan(int whichrow) const {return table_->getScan(whichrow);}
     148  std::vector<uint> getMolNos() { return table_->getMolNos();}
    136149
    137150  STSelector getSelection() const { return table_->getSelection(); }
     
    158171  { table_->shift(npix); }
    159172
     173/**
     174  commented out by TT
    160175  void setRestFrequencies(double rf, const std::string& name,
    161176                          const std::string& unit)
    162177    { table_->setRestFrequencies(rf, name, unit); }
     178**/
     179  void setRestFrequencies(vector<double> rf, const vector<std::string>& name,
     180                          const std::string& unit)
     181    { table_->setRestFrequencies(rf, name, unit); }
     182
    163183/*
    164184  void setRestFrequencies(const std::string& name) {
     
    167187*/
    168188
     189/*
    169190  std::vector<double> getRestFrequencies() const
    170191    { return table_->getRestFrequencies(); }
     192*/
     193  std::vector<double> getRestFrequency(int id) const
     194    { return table_->getRestFrequency(id); }
    171195
    172196  void setCoordInfo(std::vector<string> theinfo) {
     
    209233  int checkScanInfo(const vector<int>& scanlist) const
    210234    { return table_->checkScanInfo(scanlist); }
    211 
     235 
    212236  std::vector<double> getDirectionVector(int whichrow) const
    213237    { return table_->getDirectionVector(whichrow); }
     
    222246  std::vector<float> getWeather(int whichrow) const
    223247    { return table_->getWeather(whichrow); }
     248
     249  void reshapeSpectrum( int nmin, int nmax )
     250  { table_->reshapeSpectrum( nmin, nmax ); }
    224251
    225252private:
     
    229256} // namespace
    230257#endif
     258
  • trunk/src/python_STMath.cpp

    r1391 r1819  
    4949        .def("_averagebeams", &STMathWrapper::averageBeams)
    5050        .def("_unaryop", &STMathWrapper::unaryOperate)
     51        .def("_arrayop", &STMathWrapper::arrayOperate)
     52        //.def("_array2dop", &STMathWrapper::array2dOperate)
    5153        .def("_binaryop", &STMathWrapper::binaryOperate)
    5254        .def("_auto_quotient", &STMathWrapper::autoQuotient)
     
    5759        .def("_dofs", &STMathWrapper::dofs)
    5860        .def("_stats", &STMathWrapper::statistic)
     61        .def("_minmaxchan", &STMathWrapper::minMaxChan)
    5962        .def("_freqswitch", &STMathWrapper::freqSwitch)
    6063        .def("_bin", &STMathWrapper::bin)
     
    7376        .def("_mx_extract", &STMathWrapper::mxExtract)
    7477        .def("_lag_flag", &STMathWrapper::lagFlag)
     78        // testing average spectra with different channel/resolution
     79        .def("_new_average", &STMathWrapper::new_average)
     80        // cwcal
     81        .def("cwcal", &STMathWrapper::cwcal)
     82        .def("almacal", &STMathWrapper::almacal)
    7583          ;
    7684    };
  • trunk/src/python_STSelector.cpp

    r939 r1819  
    2929        .def("_getscans", &STSelector::getScans)
    3030        .def("_getcycles", &STSelector::getCycles)
     31        .def("_gettypes", &STSelector::getTypes)
    3132        .def("_gettaql", &STSelector::getTaQL)
    3233        .def("_getorder", &STSelector::getSortOrder)
     
    4142        .def("_settaql", &STSelector::setTaQL)
    4243        .def("_setorder", &STSelector::setSortOrder)
     44        .def("_setrows", &STSelector::setRows)
     45        .def("_settypes", &STSelector::setTypes)
    4346        .def("_empty", &STSelector::empty)
    4447      ;
  • trunk/src/python_Scantable.cpp

    r1730 r1819  
    5858    .def("getscannos", &ScantableWrapper::getScanNos)
    5959    .def("getcycle", &ScantableWrapper::getCycle)
     60    .def("getmolnos", &ScantableWrapper::getMolNos)
    6061    .def("nif", &ScantableWrapper::nif,
    6162         (boost::python::arg("scanno")=-1) )
     
    8788    .def("_getmask", &ScantableWrapper::getMask,
    8889         (boost::python::arg("whichrow")=0) )
     90    .def("_getclipmask", &ScantableWrapper::getClipMask,
     91         (boost::python::arg("whichrow")=0) )
    8992    .def("_gettsys", &ScantableWrapper::getTsys)
    9093    .def("_getsourcename", &ScantableWrapper::getSourceName,
     
    103106         (boost::python::arg("whichrow")=0) )
    104107    .def("get_antennaname", &ScantableWrapper::getAntennaName)
    105     .def("_flag", &ScantableWrapper::flag,
    106                   (boost::python::arg("unflag") = false) )
     108    .def("_flag", &ScantableWrapper::flag)
     109    .def("_flag_row", &ScantableWrapper::flagRow)
     110    .def("_getflagrow", &ScantableWrapper::getFlagRow,
     111         (boost::python::arg("whichrow")=0) )
     112    .def("_clip", &ScantableWrapper::clip,
     113         (boost::python::arg("clipoutside")=true,
     114          boost::python::arg("unflag")=false) )
    107115    .def("_save",  &ScantableWrapper::makePersistent)
    108116    .def("_summary",  &ScantableWrapper::summary,
    109117         (boost::python::arg("verbose")=true) )
    110     .def("_getrestfreqs",  &ScantableWrapper::getRestFrequencies)
     118    //.def("_getrestfreqs",  &ScantableWrapper::getRestFrequencies)
     119    .def("_getrestfreqs",  &ScantableWrapper::getRestFrequency)
    111120    .def("_setrestfreqs",  &ScantableWrapper::setRestFrequencies)
    112121    .def("shift_refpix", &ScantableWrapper::shift)
     
    127136    .def("get_coordinate", &ScantableWrapper::getCoordinate)
    128137    .def("_get_weather", &ScantableWrapper::getWeather)
     138    .def("_reshape", &ScantableWrapper::reshapeSpectrum,
     139         (boost::python::arg("nmin")=-1,
     140          boost::python::arg("nmax")=-1) )
    129141  ;
    130142};
  • trunk/src/python_asap.cpp

    r1715 r1819  
    6767  asap::python::python_Scantable();
    6868  asap::python::python_STFiller();
     69  asap::python::python_Filler();
    6970  asap::python::python_STSelector();
    7071  asap::python::python_STMath();
     
    7576  asap::python::python_LineCatalog();
    7677  asap::python::python_Logger();
     78  asap::python::python_LogSink();
    7779  asap::python::python_STCoordinate();
    7880  asap::python::python_STAtmosphere();
     81  asap::python::python_SrcType();
    7982
    8083#ifndef HAVE_LIBPYRAP
  • trunk/src/python_asap.h

    r1715 r1819  
    3939    void python_Scantable();
    4040    void python_STFiller();
     41    void python_Filler();
    4142    void python_STSelector();
    4243    void python_STMath();
     
    4748    void python_LineCatalog();
    4849    void python_Logger();
     50    void python_LogSink();
    4951    void python_STCoordinate();
    5052    void python_STAtmosphere();
     53    void python_SrcType();
    5154
    5255  } // python
Note: See TracChangeset for help on using the changeset viewer.