Пример #1
0
def test_disabled():
    asaplog.disable()
    msg = "TEST"
    asaplog.push(msg)
    asaplog.post()
    out = "".join(stdout_redirect.content).strip()
    assert_equals(out, '')
Пример #2
0
 def _update_mask(self):
     # Min and Max for new mask
     xstart = self.rect['world'][0]
     xend = self.rect['world'][2]
     if xstart <= xend: newlist=[xstart,xend]
     else: newlist = [xend,xstart]
     # Mask or unmask
     invmask = None
     if self.rect['button'] == 1:
         invmask = False
         mflg = 'Mask'
     elif self.rect['button'] == 3:
         invmask = True
         mflg = 'UNmask'
     asaplog.push(mflg+': '+str(newlist))
     asaplog.post()
     newmask = self.scan.create_mask(newlist,invert=invmask)
     # Logic operation to update mask
     if invmask:
         self.mask = mask_and(self.mask,newmask)
     else:
         self.mask = mask_or(self.mask,newmask)
     # Plot masked regions
     #if self.showmask or not self.once: self._plot_mask()
     if self.showmask: self._plot_mask()
Пример #3
0
    def save(self, fname=None, orientation=None, dpi=None, papertype=None):
        """
        Save the plot to a file.

        fname is the name of the output file.  The image format is determined
        from the file suffix; 'png', 'ps', and 'eps' are recognized.  If no
        file name is specified 'yyyymmdd_hhmmss.png' is created in the current
        directory.
        """
        from asap import rcParams
        if papertype is None:
            papertype = rcParams['plotter.papertype']
        if fname is None:
            from datetime import datetime
            dstr = datetime.now().strftime('%Y%m%d_%H%M%S')
            fname = 'asap'+dstr+'.png'

        d = ['png','.ps','eps', 'svg']

        from os.path import expandvars
        fname = expandvars(fname)

        if fname[-3:].lower() in d:
            try:
                if fname[-3:].lower() == ".ps":
                    from matplotlib import __version__ as mv
                    w = self.figure.get_figwidth()
                    h = self.figure.get_figheight()

                    if orientation is None:
                        # oriented
                        if w > h:
                            orientation = 'landscape'
                        else:
                            orientation = 'portrait'
                    from matplotlib.backends.backend_ps import papersize
                    pw,ph = papersize[papertype.lower()]
                    ds = None
                    if orientation == 'landscape':
                        ds = min(ph/w, pw/h)
                    else:
                        ds = min(pw/w, ph/h)
                    ow = ds * w
                    oh = ds * h
                    self.figure.set_size_inches((ow, oh))
                    self.figure.savefig(fname, orientation=orientation,
                                        papertype=papertype.lower())
                    self.figure.set_size_inches((w, h))
                    print 'Written file %s' % (fname)
                else:
                    if dpi is None:
                        dpi =150
                    self.figure.savefig(fname,dpi=dpi)
                    print 'Written file %s' % (fname)
            except IOError, msg:
                #print 'Failed to save %s: Error msg was\n\n%s' % (fname, err)
                asaplog.post()
                asaplog.push('Failed to save %s: Error msg was\n\n%s' % (fname, str(msg)))
                asaplog.post( 'ERROR' )
                return
Пример #4
0
def test_level():
    asaplog.enable()
    msg = "TEST"
    asaplog.push(msg)
    asaplog.post('ERROR')
    out = "".join(stdout_redirect.content).strip()
    assert_equals(out, "SEVERE: "+msg)
Пример #5
0
 def set_panelling(self,which='r'):
     """ This function is not available for the class flagplotter """
     if which.lower().startswith('r'):
         return
     msg = "Pannel setting is fixed to row mode in 'flagplotter'"
     asaplog.push(msg)
     asaplog.post('ERROR')
     self._panelling = 'r'
Пример #6
0
 def stat_cal(self):
     if not self._any_selection():
         msg = "No selection to be calculated"
         asaplog.push(msg)
         asaplog.post('WARN')
         return
     self._selected_stats(rows=self._selpanels,regions=self._selregions)
     self._clearup_selections(refresh=True)
Пример #7
0
    def auto_fit(self, insitu=None, plot=False):
        """
        Return a scan where the function is applied to all rows for
        all Beams/IFs/Pols.

        """
        from asap import scantable

        if not isinstance(self.data, scantable):
            msg = "Data is not a scantable"
            raise TypeError(msg)
        if insitu is None:
            insitu = rcParams["insitu"]
        if not insitu:
            scan = self.data.copy()
        else:
            scan = self.data
        rows = xrange(scan.nrow())
        # Save parameters of baseline fits as a class attribute.
        # NOTICE: This does not reflect changes in scantable!
        if len(rows) > 0:
            self.blpars = []
        asaplog.push("Fitting:")
        for r in rows:
            out = " Scan[%d] Beam[%d] IF[%d] Pol[%d] Cycle[%d]" % (
                scan.getscan(r),
                scan.getbeam(r),
                scan.getif(r),
                scan.getpol(r),
                scan.getcycle(r),
            )
            asaplog.push(out, False)
            self.x = scan._getabcissa(r)
            self.y = scan._getspectrum(r)
            # self.mask = mask_and(self.mask, scan._getmask(r))
            if len(self.x) == len(self.mask):
                self.mask = mask_and(self.mask, self.data._getmask(row))
            else:
                asaplog.push("lengths of data and mask are not the same. " "preset mask will be ignored")
                asaplog.post("WARN", "asapfit.fit")
                self.mask = self.data._getmask(row)
            self.data = None
            self.fit()
            x = self.get_parameters()
            fpar = self.get_parameters()
            if plot:
                self.plot(residual=True)
                x = raw_input("Accept fit ([y]/n): ")
                if x.upper() == "N":
                    self.blpars.append(None)
                    continue
            scan._setspectrum(self.fitter.getresidual(), r)
            self.blpars.append(fpar)
        if plot:
            self._p.quit()
            del self._p
            self._p = None
        return scan
Пример #8
0
 def unmap(self):
     """
     Hide the ASAPlot graphics window.
     """
     if not self.window:
         asaplog.push( "No plotter window to unmap." )
         asaplog.post( "WARN" )
         return
     self.window.wm_withdraw()
Пример #9
0
def test_push():
    asaplog.enable()
    msg = "TEST"
    asaplog.push(msg)
    asaplog.push(msg)
    asaplog.post()
    input = "\n".join([msg]*2)
    out = "".join(stdout_redirect.content).strip()
    assert_equals(out, input)
Пример #10
0
 def unmap(self):
     """
     Hide the ASAPlot graphics window.
     """
     if not self.window:
         asaplog.push("No plotter window to unmap.")
         asaplog.post("WARN")
         return
     self.window.wm_withdraw()
Пример #11
0
 def terminate(self):
     """
     Clear the figure.
     """
     if not self.window:
         asaplog.push("No plotter window to terminate.")
         asaplog.post("WARN")
         return
     self.window.destroy()
Пример #12
0
 def terminate(self):
     """
     Clear the figure.
     """
     if not self.window:
         asaplog.push( "No plotter window to terminate." )
         asaplog.post( "WARN" )
         return
     self.window.destroy()
Пример #13
0
    def auto_fit(self, insitu=None, plot=False):
        """
        Return a scan where the function is applied to all rows for
        all Beams/IFs/Pols.

        """
        from asap import scantable
        if not isinstance(self.data, scantable):
            msg = "Data is not a scantable"
            raise TypeError(msg)
        if insitu is None: insitu = rcParams['insitu']
        if not insitu:
            scan = self.data.copy()
        else:
            scan = self.data
        rows = xrange(scan.nrow())
        # Save parameters of baseline fits as a class attribute.
        # NOTICE: This does not reflect changes in scantable!
        if len(rows) > 0: self.blpars = []
        asaplog.push("Fitting:")
        for r in rows:
            out = " Scan[%d] Beam[%d] IF[%d] Pol[%d] Cycle[%d]" % (
                scan.getscan(r), scan.getbeam(r), scan.getif(r),
                scan.getpol(r), scan.getcycle(r))
            asaplog.push(out, False)
            self.x = scan._getabcissa(r)
            self.y = scan._getspectrum(r)
            #self.mask = mask_and(self.mask, scan._getmask(r))
            if len(self.x) == len(self.mask):
                self.mask = mask_and(self.mask, self.data._getmask(row))
            else:
                asaplog.push('lengths of data and mask are not the same. '
                             'preset mask will be ignored')
                asaplog.post('WARN', 'asapfit.fit')
                self.mask = self.data._getmask(row)
            self.data = None
            self.fit()
            x = self.get_parameters()
            fpar = self.get_parameters()
            if plot:
                self.plot(residual=True)
                x = raw_input("Accept fit ([y]/n): ")
                if x.upper() == 'N':
                    self.blpars.append(None)
                    continue
            scan._setspectrum(self.fitter.getresidual(), r)
            self.blpars.append(fpar)
        if plot:
            self._p.quit()
            del self._p
            self._p = None
        return scan
Пример #14
0
    def separate(self, outname="", overwrite=False):
        """
        Invoke sideband separation.

        outname   : a name of output scantable
        overwrite : overwrite existing table
        """
        out_default = "sbseparated.asap"
        if len(outname) == 0:
            outname = out_default
            asaplog.post()
            asaplog.push("The output file name is not specified.")
            asaplog.push("Using default name '%s'" % outname)
            asaplog.post("WARN")

        if os.path.exists(outname):
            if overwrite:
                asaplog.push("removing the old file '%s'" % outname)
                shutil.rmtree(outname)
            else:
                asaplog.post()
                asaplog.push("Output file '%s' already exists." % outname)
                asaplog.post("ERROR")
                return False

        self._separator.separate(outname)
Пример #15
0
    def _selected_stats(self,rows=None,regions=None):
        # check for the validity of plotter and get the plotter
        theplotter = self._get_plotter()

        scan = theplotter._data
        if not scan:
            asaplog.post()
            asaplog.push("Invalid scantable")
            asaplog.post("ERROR")
        mathobj = stmath( rcParams['insitu'] )
        statval = {}
        statstr = ['max', 'min', 'mean', 'median', 'sum', 'stddev', 'rms']
        if isinstance(rows, list) and len(rows) > 0:
            for irow in rows:
                for stat in statstr:
                    statval[stat] = mathobj._statsrow(scan,[],stat,irow)[0]
                self._print_stats(scan,irow,statval,statstr=statstr)
            del irow
        if isinstance(regions,dict) and len(regions) > 0:
            for srow, masklist in regions.iteritems():
                if not isinstance(masklist,list) or len(masklist) ==0:
                    msg = "Ignoring invalid region selection for row = "+srow
                    asaplog.post()
                    asaplog.push(msg)
                    asaplog.post("WARN")
                    continue
                irow = int(srow)
                mask = scan.create_mask(masklist,invert=False,row=irow)
                for stat in statstr:
                    statval[stat] = mathobj._statsrow(scan,mask,stat,irow)[0]
                self._print_stats(scan,irow,statval,statstr=statstr,
                                  mask=masklist)
                del irow, mask
            del srow, masklist
        del scan, statval, mathobj
Пример #16
0
    def _flag_operation(self,rows=None,regions=None,unflag=False):
        # check for the validity of plotter and get the plotter
        theplotter = self._get_plotter()

        scan = theplotter._data
        if not scan:
            asaplog.post()
            asaplog.push("Invalid scantable")
            asaplog.post("ERROR")
        if isinstance(rows,list) and len(rows) > 0:
            scan.flag_row(rows=rows,unflag=unflag)
        if isinstance(regions,dict) and len(regions) > 0:
            for srow, masklist in regions.iteritems():
                if not isinstance(masklist,list) or len(masklist) ==0:
                    msg = "Ignoring invalid region selection for row = "+srow
                    asaplog.post()
                    asaplog.push(msg)
                    asaplog.post("WARN")
                    continue
                irow = int(srow)
                mask = scan.create_mask(masklist,invert=False,row=irow)
                scan.flag(row=irow,mask=mask,unflag=unflag)
                del irow, mask
            del srow, masklist
        del scan
Пример #17
0
 def _new_custombar(self):
     backend = matplotlib.get_backend()
     # Flag plotter relys on supported GUI backends
     if not self._visible:
         asaplog.push("GUI backend is not available")
         asaplog.post("ERROR")
     elif backend == "TkAgg":
         from asap.customgui_tkagg import CustomFlagToolbarTkAgg
         return CustomFlagToolbarTkAgg(self)
     elif backend == "Qt4Agg":
         from asap.customgui_qt4agg import CustomFlagToolbarQT4Agg
         return CustomFlagToolbarQT4Agg(self)
     else:
         asaplog.push("Unsupported backend for interactive flagging. Use either TkAgg or PyQt4Agg")
         asaplog.post("ERROR")
Пример #18
0
    def _new_page(self,goback=False):
        # check for the validity of plotter and get the plotter
        theplotter = self._get_plotter()

        top = None
        header = theplotter._headtext
        reset = False
        doheader = (isinstance(header['textobj'],list) and \
                    len(header['textobj']) > 0)
        if doheader:
            top = theplotter._plotter.figure.subplotpars.top
            fontsize = header['textobj'][0].get_fontproperties().get_size()
        if theplotter._startrow <= 0:
            msg = "The page counter is reset due to chages of plot settings. "
            msg += "Plotting from the first page."
            asaplog.push(msg)
            asaplog.post('WARN')
            reset = True
            goback = False
            if doheader:
                extrastr = selstr = ''
                if header.has_key('extrastr'):
                    extrastr = header['extrastr']
                if header.has_key('selstr'):
                    selstr = header['selstr']
            theplotter._reset_header()

        theplotter._plotter.hold()
        if goback:
            self._set_prevpage_counter()
        #theplotter._plotter.clear()
        theplotter._plot(theplotter._data)
        pagenum = self._get_pagenum()
        self.set_pagecounter(pagenum)
        # Plot header information
        #if header['textobj']:
        if doheader and pagenum == 1:
            if top and top != theplotter._margins[3]:
                # work around for sdplot in CASA. complete checking in future?
                theplotter._plotter.figure.subplots_adjust(top=top)
            if reset:
                theplotter.print_header(plot=True,fontsize=fontsize,selstr=selstr, extrastr=extrastr)
            else:
                theplotter._header_plot(header['string'],fontsize=fontsize)
        theplotter._plotter.release()
        theplotter._plotter.tidy()
        theplotter._plotter.show(hardrefresh=False)
        del top
Пример #19
0
    def _set_plot_counter(self, pagemode):
        ## page operation should be either "previous", "current", or "next"
        availpage = ["p","c","n"]
        pageop = pagemode[0].lower()
        if not (pageop in availpage):
            asaplog.post()
            asaplog.push("Invalid page operation")
            asaplog.post("ERROR")
        if pageop == "n":
            # nothing necessary to plot the next page
            return

        # check for the validity of plotter and get the plotter
        theplotter = self._get_plotter()

        # set row and panel counters to those of the 1st panel of previous page
        maxpanel = 25
        # the ID of the last panel in current plot
        lastpanel = theplotter._ipanel
        # the number of current subplots
        currpnum = len(theplotter._plotter.subplots)

        # the nuber of previous subplots
        start_ipanel = None
        if pageop == "c":
            start_ipanel = max(lastpanel-currpnum+1, 0)
        else:
            ## previous page
            prevpnum = None
            if theplotter._rows and theplotter._cols:
                # when user set layout
                prevpnum = theplotter._rows*theplotter._cols
            else:
                # no user specification
                prevpnum = maxpanel
            start_ipanel = max(lastpanel-currpnum-prevpnum+1, 0)
            del prevpnum

        # set the pannel ID of the last panel of the prev(-prev) page
        theplotter._ipanel = start_ipanel-1
        if theplotter._panelling == 'r':
            theplotter._startrow = start_ipanel
        else:
            # the start row number of the next panel
            theplotter._startrow = theplotter._panelrows[start_ipanel]
        del lastpanel,currpnum,start_ipanel
Пример #20
0
    def __init__(self,plotter=None, scan=None):
        """
        Create a interactive masking object.
        Either or both 'plotter' or/and 'scan' should be defined.

        Parameters:
           plotter: an ASAP plotter object for interactive selection
           scan: a scantable to create a mask interactively
        """
        # Return if GUI is not active
        if not rcParams['plotter.gui']:
            msg = 'GUI plotter is disabled.\n'
            msg += 'Exit interactive mode.'
            asaplog.push(msg)
            asaplog.post("ERROR")
            return
        # Verify input parameters
        if scan is None and plotter is None:
            msg = "Either scantable or plotter should be defined."
            raise TypeError(msg)

        self.scan = None
        self.p = None
        self.newplot = False
        if scan and isinstance(scan, scantable):
            self.scan = scan
        from asap.asapplotter import asapplotter
        if plotter and isinstance(plotter,asapplotter):
            self.p = plotter
            if self.scan is None and isinstance(self.p._data,scantable):
                self.scan = self.p._data
        if self.scan is None:
            msg = "Invalid scantable."
            raise TypeError(msg)

        self.mask = _n_bools(self.scan.nchan(self.scan.getif(0)),True)
        self.callback = None
        self.event = None
        self.once = False
        self.showmask = True
        self.rect = {}
        self.xold = None
        self.yold = None
        self.xdataold = None
        self.ydataold = None
        self._polygons = []
Пример #21
0
 def _create_flag_from_array(self,x,masklist,invert):
     # Return True for channels which should be EXCLUDED (flag)
     if len(masklist) <= 1:
         asaplog.push()
         asaplog.post("masklist should be a list of 2 elements")
         asaplog.push("ERROR")
     n = len(x)
     # Base mask: flag out all channels
     mask = _n_bools(n, True)
     minval = min(masklist[0:2])
     maxval = max(masklist[0:2])
     for i in range(n):
         if minval <= x[i] <= maxval:
             mask[i] = False
     if invert:
         mask = mask_not(mask)
     return mask
Пример #22
0
 def _subplot_stats(self,selection):
     statstr = ['max', 'min', 'median', 'mean', 'sum', 'std'] #'rms']
     panelstr = selection['axes'].title.get_text()
     ssep = "-"*70
     asaplog.push(ssep)
     asaplog.post()
     for line in selection['axes'].lines:
         # Don't include annotations
         if line.get_label().startswith("_"):
             continue
         label = panelstr + ", "+line.get_label()
         x = line.get_xdata()
         newmsk = None
         selmsk = self._create_flag_from_array(x,
                                               selection['worldx'],
                                               selection['invert'])
         ydat = None
         y = line.get_ydata()
         if numpy.ma.isMaskedArray(y):
             ydat = y.data
             basemsk = y.mask
         else:
             ydat = y
             basemsk = False
         if not isinstance(basemsk, bool):
             # should be ndarray
             newmsk = mask_or(selmsk, basemsk)
         elif basemsk:
             # the whole original spectrum is flagged
             newmsk = basemsk
         else:
             # no channel was flagged originally
             newmsk = selmsk
         mdata = numpy.ma.masked_array(ydat, mask=newmsk)
         statval = {}
         for stat in statstr:
             # need to get the stat functions from the ma module!!!
             statval[stat] = getattr(numpy.ma,stat)(mdata)
         self._print_stats(statval, statstr=statstr, label=label,\
                           mask=selection['worldx'],\
                           unmask=selection['invert'])
         asaplog.push(ssep)
         asaplog.post()
Пример #23
0
    def _plot_page(self,pagemode="next"):
        # check for the validity of plotter and get the plotter
        theplotter = self._get_plotter()
        if theplotter._startrow <= 0:
            msg = "The page counter is reset due to chages of plot settings. "
            msg += "Plotting from the first page."
            asaplog.post()
            asaplog.push(msg)
            asaplog.post('WARN')
            goback = False

        theplotter._plotter.hold()
        #theplotter._plotter.legend(1)
        self._set_plot_counter(pagemode)
        theplotter._plot(theplotter._data)
        self.set_pagecounter(self._get_pagenum())
        theplotter._plotter.release()
        theplotter._plotter.tidy()
        theplotter._plotter.show(hardrefresh=False)
Пример #24
0
    def unflag(self):
        if not self._any_selection():
            msg = "No selection to be Flagged"
            asaplog.push(msg)
            asaplog.post('WARN')
            return
        self._pause_buttons(operation="start",msg="Unflagging data...")
        self._flag_operation(rows=self._selpanels,
                             regions=self._selregions,unflag=True)
        sout = "Unflagged:\n"
        sout += "  rows = "+str(self._selpanels)+"\n"
        sout += "  regions: "+str(self._selregions)
        asaplog.push(sout)
        del sout

        # check for the validity of plotter and get the plotter
        theplotter = self._get_plotter()
        theplotter._ismodified = True
        self._clearup_selections(refresh=False)
        self._plot_page(pagemode="current")
        self._pause_buttons(operation="end")
Пример #25
0
    def _print_stats(self,stats,statstr=None,label="",mask=None,unmask=False):
        if not isinstance(stats,dict) or len(stats) == 0:
            asaplog.post()
            asaplog.push("Invalid statistic value")
            asaplog.post("ERROR")
        maskstr = "Not available"
        if mask:
            masktype = "mask"
            maskstr = str(mask)
            if unmask: masktype = "unmask"

        sout = label + ", " + masktype + " = " + maskstr + "\n"
        statvals = []
        if not len(statstr):
            statstr = stats.keys()
        for key in statstr:
            sout += key.ljust(10)
            statvals.append(stats.pop(key))
        sout += "\n"
        sout += ("%f "*len(statstr) % tuple(statvals))
        asaplog.push(sout)
Пример #26
0
 def _add_region(self,event):
     if not self.figmgr.toolbar.mode == '':
         return
     if event.button != 1 or event.inaxes == None:
         return
     # check for the validity of plotter and get the plotter
     theplotter = self._get_plotter()
     # this row resolution assumes row panelling
     irow = int(self._getrownum(event.inaxes))
     if irow in self._selpanels:
         msg = "The whole spectrum is already selected"
         asaplog.post()
         asaplog.push(msg)
         asaplog.post('WARN')
         return
     self._thisregion = {'axes': event.inaxes,'xs': event.x,
                         'worldx': [event.xdata,event.xdata]}
     theplotter._plotter.register('button_press',None)
     self.xold = event.x
     self.xdataold = event.xdata
     theplotter._plotter.register('motion_notify', self._xspan_draw)
     theplotter._plotter.register('button_press', self._xspan_end)
Пример #27
0
    def _plot_selections(self,regions=None,panels=None):
        ### mark panels/spectra selections in the page
        if not self._any_selection() and not (regions or panels):
            return
        regions = regions or self._selregions.copy() or {}
        panels = panels or self._selpanels or []
        if not isinstance(regions,dict):
            asaplog.post()
            asaplog.push("Invalid region specification")
            asaplog.post('ERROR')
        if not isinstance(panels,list):
            asaplog.post()
            asaplog.push("Invalid panel specification")
            asaplog.post('ERROR')

        # check for the validity of plotter and get the plotter
        theplotter = self._get_plotter()

        strow = self._getrownum(theplotter._plotter.subplots[0]['axes'])
        enrow = self._getrownum(theplotter._plotter.subplots[-1]['axes'])
        for irow in range(int(strow),int(enrow)+1):
            if regions.has_key(str(irow)):
                ax = theplotter._plotter.subplots[irow - int(strow)]['axes']
                mlist = regions.pop(str(irow))
                # WORKAROUND for the issue axvspan started to reset xlim.
                axlimx = ax.get_xlim()
                for i in range(len(mlist)):
                    self._polygons.append(ax.axvspan(mlist[i][0],mlist[i][1],
                                                     facecolor='0.7'))
                ax.set_xlim(axlimx)
                del ax,mlist,axlimx
            if irow in panels:
                ax = theplotter._plotter.subplots[irow - int(strow)]['axes']
                shadow = Rectangle((0,0),1,1,facecolor='0.7',
                                   transform=ax.transAxes,visible=True)
                self._polygons.append(ax.add_patch(shadow))
                del ax,shadow
        theplotter._plotter.canvas.draw()
        del regions,panels,strow,enrow
Пример #28
0
def calfs(scantab,
          scannos=[],
          smooth=1,
          tsysval=0.0,
          tauval=0.0,
          tcalval=0.0,
          verify=False):
    """
    Calibrate GBT frequency switched data.
    Adopted from GBTIDL getfs.
    Currently calfs identify the scans as frequency switched data if source
    type enum is fson and fsoff. The data must contains 'CAL' signal
    on/off in each integration. To identify 'CAL' on state, the source type 
    enum of foncal and foffcal need to be present.

    Parameters:
        scantab:       scantable
        scannos:       list of scan numbers
        smooth:        optional box smoothing order for the reference
                       (default is 1 = no smoothing)
        tsysval:       optional user specified Tsys (default is 0.0,
                       use Tsys in the data)
        tauval:        optional user specified Tau
        verify:        Verify calibration if true
    """
    varlist = vars()
    from asap._asap import stmath
    from asap._asap import srctype
    stm = stmath()
    stm._setinsitu(False)

    #    check = scantab.get_scan('*_fs*')
    #    if check is None:
    #        msg = "The input data appear to contain no Nod observing mode data."
    #        raise TypeError(msg)
    s = scantab.get_scan(scannos)
    del scantab

    resspec = scantable(stm._dofs(s, scannos, smooth, tsysval, tauval,
                                  tcalval))
    ###
    if verify:
        # get data
        ssub = s.get_scan(scannos)
        #ssubon = ssub.get_scan('*calon')
        #ssuboff = ssub.get_scan('*[^calon]')
        sel = selector()
        sel.set_types([srctype.foncal, srctype.foffcal])
        ssub.set_selection(sel)
        ssubon = ssub.copy()
        ssub.set_selection()
        sel.reset()
        sel.set_types([srctype.fson, srctype.fsoff])
        ssub.set_selection(sel)
        ssuboff = ssub.copy()
        ssub.set_selection()
        sel.reset()
        import numpy
        precal = {}
        postcal = []
        keys = ['fs', 'fs_calon', 'fsr', 'fsr_calon']
        types = [srctype.fson, srctype.foncal, srctype.fsoff, srctype.foffcal]
        ifnos = list(ssub.getifnos())
        polnos = list(ssub.getpolnos())
        for i in range(2):
            #ss=ssuboff.get_scan('*'+keys[2*i])
            ll = []
            for j in range(len(ifnos)):
                for k in range(len(polnos)):
                    sel.set_ifs(ifnos[j])
                    sel.set_polarizations(polnos[k])
                    sel.set_types(types[2 * i])
                    try:
                        #ss.set_selection(sel)
                        ssuboff.set_selection(sel)
                    except:
                        continue
                    ll.append(numpy.array(ss._getspectrum(0)))
                    sel.reset()
                    #ss.set_selection()
                    ssuboff.set_selection()
            precal[keys[2 * i]] = ll
            #del ss
            #ss=ssubon.get_scan('*'+keys[2*i+1])
            ll = []
            for j in range(len(ifnos)):
                for k in range(len(polnos)):
                    sel.set_ifs(ifnos[j])
                    sel.set_polarizations(polnos[k])
                    sel.set_types(types[2 * i + 1])
                    try:
                        #ss.set_selection(sel)
                        ssubon.set_selection(sel)
                    except:
                        continue
                    ll.append(numpy.array(ss._getspectrum(0)))
                    sel.reset()
                    #ss.set_selection()
                    ssubon.set_selection()
            precal[keys[2 * i + 1]] = ll
            #del ss
        #sig=resspec.get_scan('*_fs')
        #ref=resspec.get_scan('*_fsr')
        sel.set_types(srctype.fson)
        resspec.set_selection(sel)
        sig = resspec.copy()
        resspec.set_selection()
        sel.reset()
        sel.set_type(srctype.fsoff)
        resspec.set_selection(sel)
        ref = resspec.copy()
        resspec.set_selection()
        sel.reset()
        for k in range(len(polnos)):
            for j in range(len(ifnos)):
                sel.set_ifs(ifnos[j])
                sel.set_polarizations(polnos[k])
                try:
                    sig.set_selection(sel)
                    postcal.append(numpy.array(sig._getspectrum(0)))
                except:
                    ref.set_selection(sel)
                    postcal.append(numpy.array(ref._getspectrum(0)))
                sel.reset()
                resspec.set_selection()
        del sel
        # plot
        asaplog.post()
        asaplog.push(
            'Plot only first spectrum for each [if,pol] pairs to verify calibration.'
        )
        asaplog.post('WARN')
        p = new_asaplot()
        rcp('lines', linewidth=1)
        #nr=min(6,len(ifnos)*len(polnos))
        nr = len(ifnos) / 2 * len(polnos)
        titles = []
        btics = []
        if nr > 3:
            asaplog.post()
            asaplog.push('Only first 3 [if,pol] pairs are plotted.')
            asaplog.post('WARN')
            nr = 3
        p.set_panels(rows=nr, cols=3, nplots=3 * nr, ganged=False)
        for i in range(3 * nr):
            b = False
            if i >= 3 * nr - 3:
                b = True
            btics.append(b)
        for i in range(nr):
            p.subplot(3 * i)
            p.color = 0
            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)])
            titles.append(title)
            #p.set_axes('title',title,fontsize=40)
            ymin = 1.0e100
            ymax = -1.0e100
            nchan = s.nchan(ifnos[2 * int(i / len(polnos))])
            edge = int(nchan * 0.01)
            for j in range(4):
                spmin = min(precal[keys[j]][i][edge:nchan - edge])
                spmax = max(precal[keys[j]][i][edge:nchan - edge])
                ymin = min(ymin, spmin)
                ymax = max(ymax, spmax)
            for j in range(4):
                if i == 0:
                    p.set_line(label=keys[j])
                else:
                    p.legend()
                p.plot(precal[keys[j]][i])
            p.axes.set_ylim(ymin - 0.1 * abs(ymin), ymax + 0.1 * abs(ymax))
            if not btics[3 * i]:
                p.axes.set_xticks([])
            p.subplot(3 * i + 1)
            p.color = 0
            title = 'sig data IF%s POL%s' % (ifnos[2 * int(i / len(polnos))],
                                             polnos[i % len(polnos)])
            titles.append(title)
            #p.set_axes('title',title)
            p.legend()
            ymin = postcal[2 * i][edge:nchan - edge].min()
            ymax = postcal[2 * i][edge:nchan - edge].max()
            p.plot(postcal[2 * i])
            p.axes.set_ylim(ymin - 0.1 * abs(ymin), ymax + 0.1 * abs(ymax))
            if not btics[3 * i + 1]:
                p.axes.set_xticks([])
            p.subplot(3 * i + 2)
            p.color = 0
            title = 'ref data IF%s POL%s' % (ifnos[2 * int(i / len(polnos)) +
                                                   1], polnos[i % len(polnos)])
            titles.append(title)
            #p.set_axes('title',title)
            p.legend()
            ymin = postcal[2 * i + 1][edge:nchan - edge].min()
            ymax = postcal[2 * i + 1][edge:nchan - edge].max()
            p.plot(postcal[2 * i + 1])
            p.axes.set_ylim(ymin - 0.1 * abs(ymin), ymax + 0.1 * abs(ymax))
            if not btics[3 * i + 2]:
                p.axes.set_xticks([])
        for i in range(3 * nr):
            p.subplot(i)
            p.set_axes('title', titles[i], fontsize='medium')
        x = raw_input('Accept calibration ([y]/n): ')
        if x.upper() == 'N':
            p.quit()
            del p
            return scantab
        p.quit()
        del p
    ###
    resspec._add_history("calfs", varlist)
    return resspec
Пример #29
0
     precal[keys[2 * i + 1]] = ll
     #del ss
 for j in range(len(ifnos)):
     for k in range(len(polnos)):
         sel.set_ifs(ifnos[j])
         sel.set_polarizations(polnos[k])
         try:
             ress.set_selection(sel)
         except:
             continue
         postcal.append(numpy.array(ress._getspectrum(0)))
         sel.reset()
         ress.set_selection()
 del sel
 # plot
 asaplog.post()
 asaplog.push(
     'Plot only first spectrum for each [if,pol] pairs to verify calibration.'
 )
 asaplog.post('WARN')
 p = new_asaplot()
 rcp('lines', linewidth=1)
 #nr=min(6,len(ifnos)*len(polnos))
 nr = len(ifnos) * len(polnos)
 titles = []
 btics = []
 if nr < 4:
     p.set_panels(rows=nr, cols=2, nplots=2 * nr, ganged=False)
     for i in range(2 * nr):
         b = False
         if i >= 2 * nr - 2:
Пример #30
0
 def set_range(self,xstart=None,xend=None,ystart=None,yend=None,refresh=False, offset=None):
     """ This function is not available for the class flagplotter """
     msg = "Plot range setting is not allowed in 'flagplotter'"
     asaplog.push(msg)
     asaplog.post('ERROR')
     self._panelling = 'r'
Пример #31
0
def calfs(scantab, scannos=[], smooth=1, tsysval=0.0, tauval=0.0, tcalval=0.0, verify=False):
    """
    Calibrate GBT frequency switched data.
    Adopted from GBTIDL getfs.
    Currently calfs identify the scans as frequency switched data if source
    type enum is fson and fsoff. The data must contains 'CAL' signal
    on/off in each integration. To identify 'CAL' on state, the source type 
    enum of foncal and foffcal need to be present.

    Parameters:
        scantab:       scantable
        scannos:       list of scan numbers
        smooth:        optional box smoothing order for the reference
                       (default is 1 = no smoothing)
        tsysval:       optional user specified Tsys (default is 0.0,
                       use Tsys in the data)
        tauval:        optional user specified Tau
        verify:        Verify calibration if true
    """
    varlist = vars()
    from asap._asap import stmath
    from asap._asap import srctype
    stm = stmath()
    stm._setinsitu(False)

#    check = scantab.get_scan('*_fs*')
#    if check is None:
#        msg = "The input data appear to contain no Nod observing mode data."
#        raise TypeError(msg)
    s = scantab.get_scan(scannos)
    del scantab

    resspec = scantable(stm._dofs(s, scannos, smooth, tsysval,tauval,tcalval))
    ###
    if verify:
        # get data
        ssub = s.get_scan(scannos)
        #ssubon = ssub.get_scan('*calon')
        #ssuboff = ssub.get_scan('*[^calon]')
        sel = selector()
        sel.set_types( [srctype.foncal,srctype.foffcal] )
        ssub.set_selection( sel )
        ssubon = ssub.copy()
        ssub.set_selection()
        sel.reset()
        sel.set_types( [srctype.fson,srctype.fsoff] )
        ssub.set_selection( sel )
        ssuboff = ssub.copy()
        ssub.set_selection()
        sel.reset()
        import numpy
        precal={}
        postcal=[]
        keys=['fs','fs_calon','fsr','fsr_calon']
        types=[srctype.fson,srctype.foncal,srctype.fsoff,srctype.foffcal]
        ifnos=list(ssub.getifnos())
        polnos=list(ssub.getpolnos())
        for i in range(2):
            #ss=ssuboff.get_scan('*'+keys[2*i])
            ll=[]
            for j in range(len(ifnos)):
                for k in range(len(polnos)):
                    sel.set_ifs(ifnos[j])
                    sel.set_polarizations(polnos[k])
                    sel.set_types(types[2*i])
                    try:
                        #ss.set_selection(sel)
                        ssuboff.set_selection(sel)
                    except:
                        continue
                    ll.append(numpy.array(ss._getspectrum(0)))
                    sel.reset()
                    #ss.set_selection()
                    ssuboff.set_selection()
            precal[keys[2*i]]=ll
            #del ss
            #ss=ssubon.get_scan('*'+keys[2*i+1])
            ll=[]
            for j in range(len(ifnos)):
                for k in range(len(polnos)):
                    sel.set_ifs(ifnos[j])
                    sel.set_polarizations(polnos[k])
                    sel.set_types(types[2*i+1])
                    try:
                        #ss.set_selection(sel)
                        ssubon.set_selection(sel)
                    except:
                        continue
                    ll.append(numpy.array(ss._getspectrum(0)))
                    sel.reset()
                    #ss.set_selection()
                    ssubon.set_selection()
            precal[keys[2*i+1]]=ll
            #del ss
        #sig=resspec.get_scan('*_fs')
        #ref=resspec.get_scan('*_fsr')
        sel.set_types( srctype.fson )
        resspec.set_selection( sel )
        sig=resspec.copy()
        resspec.set_selection()
        sel.reset()
        sel.set_type( srctype.fsoff )
        resspec.set_selection( sel )
        ref=resspec.copy()
        resspec.set_selection()
        sel.reset()
        for k in range(len(polnos)):
            for j in range(len(ifnos)):
                sel.set_ifs(ifnos[j])
                sel.set_polarizations(polnos[k])
                try:
                    sig.set_selection(sel)
                    postcal.append(numpy.array(sig._getspectrum(0)))
                except:
                    ref.set_selection(sel)
                    postcal.append(numpy.array(ref._getspectrum(0)))
                sel.reset()
                resspec.set_selection()
        del sel
        # plot
        asaplog.post()
        asaplog.push('Plot only first spectrum for each [if,pol] pairs to verify calibration.')
        asaplog.post('WARN')
        p=new_asaplot()
        rcp('lines', linewidth=1)
        #nr=min(6,len(ifnos)*len(polnos))
        nr=len(ifnos)/2*len(polnos)
        titles=[]
        btics=[]
        if nr>3:
            asaplog.post()
            asaplog.push('Only first 3 [if,pol] pairs are plotted.')
            asaplog.post('WARN')
            nr=3
        p.set_panels(rows=nr,cols=3,nplots=3*nr,ganged=False)
        for i in range(3*nr):
            b=False
            if i >= 3*nr-3:
                b=True
            btics.append(b)
        for i in range(nr):
            p.subplot(3*i)
            p.color=0
            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)])
            titles.append(title)
            #p.set_axes('title',title,fontsize=40)
            ymin=1.0e100
            ymax=-1.0e100
            nchan=s.nchan(ifnos[2*int(i/len(polnos))])
            edge=int(nchan*0.01)
            for j in range(4):
                spmin=min(precal[keys[j]][i][edge:nchan-edge])
                spmax=max(precal[keys[j]][i][edge:nchan-edge])
                ymin=min(ymin,spmin)
                ymax=max(ymax,spmax)
            for j in range(4):
                if i==0:
                    p.set_line(label=keys[j])
                else:
                    p.legend()
                p.plot(precal[keys[j]][i])
            p.axes.set_ylim(ymin-0.1*abs(ymin),ymax+0.1*abs(ymax))
            if not btics[3*i]:
                p.axes.set_xticks([])
            p.subplot(3*i+1)
            p.color=0
            title='sig data IF%s POL%s' % (ifnos[2*int(i/len(polnos))],polnos[i%len(polnos)])
            titles.append(title)
            #p.set_axes('title',title)
            p.legend()
            ymin=postcal[2*i][edge:nchan-edge].min()
            ymax=postcal[2*i][edge:nchan-edge].max()
            p.plot(postcal[2*i])
            p.axes.set_ylim(ymin-0.1*abs(ymin),ymax+0.1*abs(ymax))
            if not btics[3*i+1]:
                p.axes.set_xticks([])
            p.subplot(3*i+2)
            p.color=0
            title='ref data IF%s POL%s' % (ifnos[2*int(i/len(polnos))+1],polnos[i%len(polnos)])
            titles.append(title)
            #p.set_axes('title',title)
            p.legend()
            ymin=postcal[2*i+1][edge:nchan-edge].min()
            ymax=postcal[2*i+1][edge:nchan-edge].max()
            p.plot(postcal[2*i+1])
            p.axes.set_ylim(ymin-0.1*abs(ymin),ymax+0.1*abs(ymax))
            if not btics[3*i+2]:
                p.axes.set_xticks([])
        for i in range(3*nr):
            p.subplot(i)
            p.set_axes('title',titles[i],fontsize='medium')
        x=raw_input('Accept calibration ([y]/n): ' )
        if x.upper() == 'N':
            p.quit()
            del p
            return scantab
        p.quit()
        del p
    ###
    resspec._add_history("calfs",varlist)
    return resspec
Пример #32
0
    def select_mask(self,once=False,showmask=True):
        """
        Do interactive mask selection.
        Modify masks interactively by adding/deleting regions with
        mouse drawing.(left-button: mask; right-button: UNmask)
        Note that the interactive region selection is available only
        when GUI plotter is active.

        Parameters:
            once:     If specified as True, you can modify masks only
                      once. Else if False, you can modify them repeatedly.
            showmask: If specified as True, the masked regions are plotted
                      on the plotter.
                  Note this parameter is valid only when once=True.
                  Otherwise, maskes are forced to be plotted for reference.
        """
        # Return if GUI is not active
        if not rcParams['plotter.gui']:
            msg = 'GUI plotter is disabled.\n'
            msg += 'Exit interactive mode.'
            asaplog.push(msg)
            asaplog.post("ERROR")
            return

        self.once = once
        if self.once:
            self.showmask = showmask
        else:
            if not showmask:
                asaplog.post()
                asaplog.push('showmask spcification is ignored. Mask regions are plotted anyway.')
                asaplog.post("WARN")
            self.showmask = True

        if not self.p:
            asaplog.push('A new ASAP plotter will be loaded')
            asaplog.post()
            from asap.asapplotter import asapplotter
            self.p = asapplotter()
            self.newplot = True
        self.p._assert_plotter(action='reload')
        from matplotlib import rc as rcp
        rcp('lines', linewidth=1)
        
        # Plot selected spectra if needed
        if self.scan != self.p._data:
            if len(self.scan.getifnos()) > 16:
                asaplog.post()
                asaplog.push("Number of panels > 16. Plotting the first 16...")
                asaplog.post("WARN")
            # Need replot
            self.p._legendloc = 1
            self.p.plot(self.scan)
            # disable casa toolbar
            if self.p._plotter.figmgr.casabar:
                self.p._plotter.figmgr.casabar.disable_button()
                self.p._plotter.figmgr.casabar.disable_prev()
                self.p._plotter.figmgr.casabar.disable_next()
            for panel in self.p._plotter.subplots:
                xmin, xmax = panel['axes'].get_xlim()
                marg = 0.05*abs(xmax-xmin)
                panel['axes'].set_xlim(xmin-marg, xmax+marg)
                if rcParams['plotter.ganged']: break
            self.p._plotter.show()

        # Plot initial mask region
        #if self.showmask or not self.once:
        if self.showmask:
            self._plot_mask()
            print ''
            print 'Selected regions are shaded with yellow. (gray: projections)'
            print 'Now you can modify the selection.'
            print 'Draw rectangles with Left-mouse to add the regions,'
            print 'or with Right-mouse to exclude the regions.'


        if self.event != None:
            self._region_start(self.event)
        else:
            self.p._plotter.register('button_press',None)
            self.p._plotter.register('button_press',self._region_start)
Пример #33
0
from matplotlib import _pylab_helpers

from asap.parameters import rcParams as asaprcParams
from asap.logging import asaplog

# API change in mpl >= 0.98
try:
    from matplotlib.transforms import blended_transform_factory
except ImportError:
    from matplotlib.transforms import blend_xy_sep_transform as blended_transform_factory

mvers = matplotlib.__version__.split(".")
if int(mvers[0]) == 0 and int(mvers[1]) < 99:
    #print "Warning: matplotlib version < 0.87. This might cause errors. Please upgrade."
    asaplog.push( "matplotlib version < 0.99. This might cause errors. Please upgrade." )
    asaplog.post( 'WARN' )

class asaplotbase:
    """
    ASAP plotting base class based on matplotlib.
    """

    def __init__(self, rows=1, cols=0, title='', size=None, buffering=False):
        """
        Create a new instance of the ASAPlot plotting class.

        If rows < 1 then a separate call to set_panels() is required to define
        the panel layout; refer to the doctext for set_panels().
        """
        self.is_dead = False
        self.figure = Figure(figsize=size, facecolor='#ddddee')
Пример #34
0
    def fit(self, row=0, estimate=False):
        """
        Execute the actual fitting process. All the state has to be set.
        Parameters:
            row:        specify the row in the scantable
            estimate:   auto-compute an initial parameter set (default False)
                        This can be used to compute estimates even if fit was
                        called before.
        Example:
            s = scantable('myscan.asap')
            s.set_cursor(thepol=1)        # select second pol
            f = fitter()
            f.set_scan(s)
            f.set_function(poly=0)
            f.fit(row=0)                  # fit first row
        """
        if ((self.x is None or self.y is None) and self.data is None) or self.fitfunc is None:
            msg = "Fitter not yet initialised. Please set data & fit function"
            raise RuntimeError(msg)

        if self.data is not None:
            if self.data._getflagrow(row):
                raise RuntimeError, "Can not fit flagged row."
            self.x = self.data._getabcissa(row)
            self.y = self.data._getspectrum(row)
            # self.mask = mask_and(self.mask, self.data._getmask(row))
            if len(self.x) == len(self.mask):
                self.mask = mask_and(self.mask, self.data._getmask(row))
            else:
                asaplog.push("lengths of data and mask are not the same. " "preset mask will be ignored")
                asaplog.post("WARN", "asapfit.fit")
                self.mask = self.data._getmask(row)
            asaplog.push("Fitting:")
            i = row
            out = "Scan[%d] Beam[%d] IF[%d] Pol[%d] Cycle[%d]" % (
                self.data.getscan(i),
                self.data.getbeam(i),
                self.data.getif(i),
                self.data.getpol(i),
                self.data.getcycle(i),
            )

            asaplog.push(out, False)

        self.fitter.setdata(self.x, self.y, self.mask)
        if self.fitfunc == "gauss" or self.fitfunc == "lorentz":
            ps = self.fitter.getparameters()
            if len(ps) == 0 or estimate:
                self.fitter.estimate()
        fxdpar = list(self.fitter.getfixedparameters())
        if len(fxdpar) and fxdpar.count(0) == 0:
            raise RuntimeError, "No point fitting, if all parameters are fixed."
        if self._constraints:
            for c in self._constraints:
                self.fitter.addconstraint(c[0] + [c[-1]])
        if self.uselinear:
            converged = self.fitter.lfit()
        else:
            converged = self.fitter.fit()
        if not converged:
            raise RuntimeError, "Fit didn't converge."
        self._fittedrow = row
        self.fitted = True
        return
Пример #35
0
    def fit(self, row=0, estimate=False):
        """
        Execute the actual fitting process. All the state has to be set.
        Parameters:
            row:        specify the row in the scantable
            estimate:   auto-compute an initial parameter set (default False)
                        This can be used to compute estimates even if fit was
                        called before.
        Example:
            s = scantable('myscan.asap')
            s.set_cursor(thepol=1)        # select second pol
            f = fitter()
            f.set_scan(s)
            f.set_function(poly=0)
            f.fit(row=0)                  # fit first row
        """
        if ((self.x is None or self.y is None) and self.data is None) \
               or self.fitfunc is None:
            msg = "Fitter not yet initialised. Please set data & fit function"
            raise RuntimeError(msg)

        if self.data is not None:
            if self.data._getflagrow(row):
                raise RuntimeError, "Can not fit flagged row."
            self.x = self.data._getabcissa(row)
            self.y = self.data._getspectrum(row)
            #self.mask = mask_and(self.mask, self.data._getmask(row))
            if len(self.x) == len(self.mask):
                self.mask = mask_and(self.mask, self.data._getmask(row))
            else:
                asaplog.push('lengths of data and mask are not the same. '
                             'preset mask will be ignored')
                asaplog.post('WARN', 'asapfit.fit')
                self.mask = self.data._getmask(row)
            asaplog.push("Fitting:")
            i = row
            out = "Scan[%d] Beam[%d] IF[%d] Pol[%d] Cycle[%d]" % (
                self.data.getscan(i), self.data.getbeam(i), self.data.getif(i),
                self.data.getpol(i), self.data.getcycle(i))

            asaplog.push(out, False)

        self.fitter.setdata(self.x, self.y, self.mask)
        if self.fitfunc == 'gauss' or self.fitfunc == 'lorentz':
            ps = self.fitter.getparameters()
            if len(ps) == 0 or estimate:
                self.fitter.estimate()
        fxdpar = list(self.fitter.getfixedparameters())
        if len(fxdpar) and fxdpar.count(0) == 0:
            raise RuntimeError, "No point fitting, if all parameters are fixed."
        if self._constraints:
            for c in self._constraints:
                self.fitter.addconstraint(c[0] + [c[-1]])
        if self.uselinear:
            converged = self.fitter.lfit()
        else:
            converged = self.fitter.fit()
        if not converged:
            raise RuntimeError, "Fit didn't converge."
        self._fittedrow = row
        self.fitted = True
        return
Пример #36
0
 def _print_stats(self,scan,row,stats,statstr=None,mask=None):
     if not isinstance(scan, scantable):
         asaplog.post()
         asaplog.push("Invalid scantable")
         asaplog.post("ERROR")
     if row < 0 or row > scan.nrow():
         asaplog.post()
         asaplog.push("Invalid row number")
         asaplog.post("ERROR")
     if not isinstance(stats,dict) or len(stats) == 0:
         asaplog.post()
         asaplog.push("Invalid statistic value")
         asaplog.post("ERROR")
     maskstr = "All"
     if mask:
         maskstr = str(mask)
     ssep = "-"*70+"\n"
     sout = ssep
     sout += ("Row=%d  Scan=%d  IF=%d  Pol=%d  Time=%s  mask=%s" % \
              (row, scan.getscan(row), scan.getif(row), scan.getpol(row), scan.get_time(row),maskstr))
     sout += "\n"
     statvals = []
     if not len(statstr):
         statstr = stats.keys()
     for key in statstr:
         sout += key.ljust(10)
         statvals.append(stats.pop(key))
     sout += "\n"
     sout += ("%f "*len(statstr) % tuple(statvals))
     sout += "\n"+ssep
     asaplog.push(sout)
     del sout, ssep, maskstr, statvals, key, scan, row, stats, statstr, mask