source: trunk/python/scantable.py @ 497

Last change on this file since 497 was 497, checked in by kil064, 19 years ago

document ascii output format better

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 28.5 KB
RevLine 
[102]1from asap._asap import sdtable
[226]2from asap import rcParams
[189]3from numarray import ones,zeros
[102]4import sys
5
6class scantable(sdtable):
7    """
8        The ASAP container for scans
9    """
[113]10   
[484]11    def __init__(self, filename, average=None, unit=None):
[102]12        """
13        Create a scantable from a saved one or make a reference
14        Parameters:
[181]15            filename:    the name of an asap table on disk
16                         or
17                         the name of a rpfits/sdfits/ms file
18                         (integrations within scans are auto averaged
19                         and the whole file is read)
20                         or
21                         [advanced] a reference to an existing
[102]22                         scantable
[484]23            average:     average all integrations withinb a scan on read.
24                         The default (True) is taken from .asaprc.
25            unit:         brightness unit; must be consistent with K or Jy.
[340]26                         Over-rides the default selected by the reader
27                         (input rpfits/sdfits/ms) or replaces the value
28                         in existing scantables
[489]29        """       
30        if average is None or type(average) is not bool:
31            average = rcParams['scantable.autoaverage']           
32
[484]33        varlist = vars()
[226]34        self._vb = rcParams['verbose']
[113]35        self._p = None
[484]36
[181]37        if isinstance(filename,sdtable):
38            sdtable.__init__(self, filename)           
[340]39            if unit is not None:
[346]40                self.set_fluxunit(unit)                       
[181]41        else:
[411]42            import os.path
43            if not os.path.exists(filename):
44                print "File '%s' not found." % (filename)
[226]45                return
[411]46            filename = os.path.expandvars(filename)
47            if os.path.isdir(filename):
[181]48                # crude check if asap table
[411]49                if os.path.exists(filename+'/table.info'):
[181]50                    sdtable.__init__(self, filename)
[340]51                    if unit is not None:
52                        self.set_fluxunit(unit)                       
[181]53                else:
[411]54                    print "The given file '%s'is not a valid asap table." % (filename)
[226]55                    return
[484]56            else:           
[181]57                from asap._asap import sdreader
[340]58                ifSel = -1
59                beamSel = -1
[345]60                r = sdreader(filename,ifSel,beamSel)
[181]61                print 'Importing data...'
[411]62                r._read([-1])
63                tbl = r._getdata()
[346]64                if unit is not None:
65                    tbl.set_fluxunit(unit)
[489]66                if average:
67                    from asap._asap import average as _av
[226]68                    tmp = tuple([tbl])
69                    print 'Auto averaging integrations...'
[489]70                    tbl2 = _av(tmp,(),True,'none')
[226]71                    sdtable.__init__(self,tbl2)
72                    del r,tbl
73                else:
74                    sdtable.__init__(self,tbl)
[484]75                self._add_history("scantable", varlist)
[102]76
[451]77    def save(self, name=None, format=None, stokes=False, overwrite=False):
[116]78        """
[280]79        Store the scantable on disk. This can be an asap (aips++) Table, SDFITS,
80        Image FITS or MS2 format.
[116]81        Parameters:
[196]82            name:        the name of the outputfile. For format="FITS" this
[489]83                         is the directory file name into which all the files
[497]84                         will be written (default is 'asap_FITS'). For format
85                         "ASCII" this is the root file name (data in 'name'.txt
86                         and header in 'name'_header.txt)
[116]87            format:      an optional file format. Default is ASAP.
[280]88                         Allowed are - 'ASAP' (save as ASAP [aips++] Table),
[194]89                                       'SDFITS' (save as SDFITS file)
90                                       'FITS' (saves each row as a FITS Image)
[200]91                                       'ASCII' (saves as ascii text file)
[226]92                                       'MS2' (saves as an aips++
93                                              MeasurementSet V2)
[489]94            stokes:      Convert to Stokes parameters (only available
95                         currently with FITS and ASCII formats.
96                         Default is False.
[411]97            overwrite:   If the file should be overwritten if it exists.
[256]98                         The default False is to return with warning
[411]99                         without writing the output. USE WITH CARE.
[116]100        Example:
101            scan.save('myscan.asap')
102            scan.save('myscan.sdfits','SDFITS')
103        """
[411]104        from os import path
[226]105        if format is None: format = rcParams['scantable.save']
[256]106        suffix = '.'+format.lower()
107        if name is None or name =="":
108            name = 'scantable'+suffix
[283]109            print "No filename given. Using default name %s..." % name
[411]110        name = path.expandvars(name)
[256]111        if path.isfile(name) or path.isdir(name):
112            if not overwrite:
113                print "File %s already exists." % name
114                return
[451]115        format2 = format.upper()
116        if format2 == 'ASAP':
[116]117            self._save(name)
118        else:
119            from asap._asap import sdwriter as _sw
[451]120            w = _sw(format2)
[445]121            w.write(self, name, stokes)
[116]122        return
123
[102]124    def copy(self):
125        """
126        Return a copy of this scantable.
127        Parameters:
[113]128            none
[102]129        Example:
130            copiedscan = scan.copy()
131        """
[113]132        sd = scantable(sdtable._copy(self))
133        return sd
134
[102]135    def get_scan(self, scanid=None):
136        """
137        Return a specific scan (by scanno) or collection of scans (by
138        source name) in a new scantable.
139        Parameters:
140            scanid:    a scanno or a source name
141        Example:
[113]142            scan.get_scan('323p459')
[102]143            # gets all scans containing the source '323p459'
144        """
145        if scanid is None:
146            print "Please specify a scan no or name to retrieve from the scantable"
147        try:
148            if type(scanid) is str:
[113]149                s = sdtable._getsource(self,scanid)
[102]150                return scantable(s)
151            elif type(scanid) is int:
[381]152                s = sdtable._getscan(self,[scanid])
153                return scantable(s)
154            elif type(scanid) is list:
[113]155                s = sdtable._getscan(self,scanid)
[102]156                return scantable(s)
[381]157            else:
158                print "Illegal scanid type, use 'int' or 'list' if ints."
[102]159        except RuntimeError:
160            print "Couldn't find any match."
161
162    def __str__(self):
[381]163        return sdtable._summary(self,True)
[102]164
[381]165    def summary(self,filename=None, verbose=None):
[102]166        """
167        Print a summary of the contents of this scantable.
168        Parameters:
169            filename:    the name of a file to write the putput to
170                         Default - no file output
[381]171            verbose:     print extra info such as the frequency table
172                         The default (False) is taken from .asaprc
[102]173        """
[381]174        info = sdtable._summary(self, verbose)
175        if verbose is None: verbose = rcParams['scantable.verbosesummary']
[102]176        if filename is not None:
[256]177            if filename is "":
178                filename = 'scantable_summary.txt'
[415]179            from os.path import expandvars, isdir
[411]180            filename = expandvars(filename)
[415]181            if not isdir(filename):
[413]182                data = open(filename, 'w')
183                data.write(info)
184                data.close()
185            else:
186                print "Illegal file name '%s'." % (filename)
[102]187        print info
[484]188           
[256]189    def set_cursor(self, thebeam=0,theif=0,thepol=0):
[102]190        """
191        Set the spectrum for individual operations.
192        Parameters:
193            thebeam,theif,thepol:    a number
194        Example:
[256]195            scan.set_cursor(0,0,1)
[135]196            pol1sig = scan.stats(all=False) # returns std dev for beam=0
[181]197                                            # if=0, pol=1
[102]198        """
[484]199        varlist = vars()
[102]200        self.setbeam(thebeam)
201        self.setpol(thepol)
202        self.setif(theif)
[484]203        self._add_history("set_cursor",varlist)
[102]204        return
205
[256]206    def get_cursor(self):
[113]207        """
208        Return/print a the current 'cursor' into the Beam/IF/Pol cube.
209        Parameters:
210            none
211        Returns:
212            a list of values (currentBeam,currentIF,currentPol)
213        Example:
214            none
215        """
[102]216        i = self.getbeam()
217        j = self.getif()
218        k = self.getpol()
[113]219        if self._vb:
[181]220            print "--------------------------------------------------"
[256]221            print " Cursor position"
[181]222            print "--------------------------------------------------"
[226]223            out = 'Beam=%d IF=%d Pol=%d ' % (i,j,k)
[113]224            print out
[102]225        return i,j,k
226
[436]227    def stats(self, stat='stddev', mask=None, allaxes=None):
[102]228        """
[135]229        Determine the specified statistic of the current beam/if/pol
[102]230        Takes a 'mask' as an optional parameter to specify which
231        channels should be excluded.
232        Parameters:
[135]233            stat:    'min', 'max', 'sumsq', 'sum', 'mean'
234                     'var', 'stddev', 'avdev', 'rms', 'median'
235            mask:    an optional mask specifying where the statistic
[102]236                     should be determined.
[436]237            allaxes: if True apply to all spectra. Otherwise
238                     apply only to the selected (beam/pol/if)spectra only.
239                     The default is taken from .asaprc (True if none)
[102]240        Example:
[113]241            scan.set_unit('channel')
[102]242            msk = scan.create_mask([100,200],[500,600])
[135]243            scan.stats(stat='mean', mask=m)
[102]244        """
[436]245        if allaxes is None: allaxes = rcParams['scantable.allaxes']
[135]246        from asap._asap import stats as _stats
[256]247        from numarray import array,zeros,Float
[102]248        if mask == None:
249            mask = ones(self.nchan())
[256]250        axes = ['Beam','IF','Pol','Time']
251
[436]252        beamSel,IFSel,polSel = (self.getbeam(),self.getif(),self.getpol())
253        if allaxes:
[256]254            n = self.nbeam()*self.nif()*self.npol()*self.nrow()
255            shp = [self.nbeam(),self.nif(),self.npol(),self.nrow()]
256            arr = array(zeros(n),shape=shp,type=Float)
257
258            for i in range(self.nbeam()):
259                self.setbeam(i)
260                for j in range(self.nif()):
261                    self.setif(j)
262                    for k in range(self.npol()):
263                        self.setpol(k)
264                        arr[i,j,k,:] = _stats(self,mask,stat,-1)
265            retval = {'axes': axes, 'data': arr, 'cursor':None}
266            tm = [self._gettime(val) for val in range(self.nrow())]
[181]267            if self._vb:
[256]268                self._print_values(retval,stat,tm)
[436]269            self.setbeam(beamSel)
270            self.setif(IFSel)
271            self.setpol(polSel)
[256]272            return retval
[102]273
274        else:
[241]275            statval = _stats(self,mask,stat,-1)
[181]276            out = ''
277            for l in range(self.nrow()):
278                tm = self._gettime(l)
279                out += 'Time[%s]:\n' % (tm)
[436]280                if self.nbeam() > 1: out +=  ' Beam[%d] ' % (beamSel)
281                if self.nif() > 1: out +=  ' IF[%d] ' % (IFSel)
282                if self.npol() > 1: out +=  ' Pol[%d] ' % (polSel)
[181]283                out += '= %3.3f\n' % (statval[l])
284                out +=  "--------------------------------------------------\n"
[226]285
[181]286            if self._vb:
287                print "--------------------------------------------------"
288                print " ",stat
289                print "--------------------------------------------------"
290                print out
[256]291            retval = {'axes': axes, 'data': array(statval), 'cursor':(i,j,k)}
292            return retval
[102]293
[436]294    def stddev(self,mask=None, allaxes=None):
[135]295        """
296        Determine the standard deviation of the current beam/if/pol
297        Takes a 'mask' as an optional parameter to specify which
298        channels should be excluded.
299        Parameters:
300            mask:    an optional mask specifying where the standard
301                     deviation should be determined.
[436]302            allaxes: optional flag to show all or a cursor selected
[226]303                     spectrum of Beam/IF/Pol. Default is all or taken
304                     from .asaprc
[135]305
306        Example:
307            scan.set_unit('channel')
308            msk = scan.create_mask([100,200],[500,600])
309            scan.stddev(mask=m)
310        """
[436]311        if allaxes is None: allaxes = rcParams['scantable.allaxes']
312        return self.stats(stat='stddev',mask=mask, allaxes=allaxes);
[135]313
[436]314    def get_tsys(self, allaxes=None):
[113]315        """
316        Return the System temperatures.
317        Parameters:
[436]318           allaxes:     if True apply to all spectra. Otherwise
319                        apply only to the selected (beam/pol/if)spectra only.
320                        The default is taken from .asaprc (True if none)
[113]321        Returns:
322            a list of Tsys values.
323        """
[436]324        if allaxes is None: allaxes = rcParams['scantable.allaxes']
[256]325        from numarray import array,zeros,Float
326        axes = ['Beam','IF','Pol','Time']
327
[436]328        if allaxes:
[256]329            n = self.nbeam()*self.nif()*self.npol()*self.nrow()
330            shp = [self.nbeam(),self.nif(),self.npol(),self.nrow()]
331            arr = array(zeros(n),shape=shp,type=Float)
332
333            for i in range(self.nbeam()):
334                self.setbeam(i)
335                for j in range(self.nif()):
336                    self.setif(j)
337                    for k in range(self.npol()):
338                        self.setpol(k)
339                        arr[i,j,k,:] = self._gettsys()
340            retval = {'axes': axes, 'data': arr, 'cursor':None}
341            tm = [self._gettime(val) for val in range(self.nrow())]
[181]342            if self._vb:
[256]343                self._print_values(retval,'Tsys',tm)
344            return retval
345
[102]346        else:
[256]347            i,j,k = (self.getbeam(),self.getif(),self.getpol())
348            statval = self._gettsys()
[181]349            out = ''
350            for l in range(self.nrow()):
351                tm = self._gettime(l)
352                out += 'Time[%s]:\n' % (tm)
353                if self.nbeam() > 1: out +=  ' Beam[%d] ' % (i)
354                if self.nif() > 1: out +=  ' IF[%d] ' % (j)
355                if self.npol() > 1: out +=  ' Pol[%d] ' % (k)
[256]356                out += '= %3.3f\n' % (statval[l])
357                out +=  "--------------------------------------------------\n"
358
[181]359            if self._vb:
360                print "--------------------------------------------------"
[256]361                print " TSys"
[181]362                print "--------------------------------------------------"
363                print out
[256]364            retval = {'axes': axes, 'data': array(statval), 'cursor':(i,j,k)}
365            return retval
[113]366       
[407]367    def get_time(self, row=-1):
[113]368        """
369        Get a list of time stamps for the observations.
[181]370        Return a string for each integration in the scantable.
[113]371        Parameters:
[407]372            row:    row no of integration. Default -1 return all rows
[113]373        Example:
374            none
375        """
376        out = []
[407]377        if row == -1:
378            for i in range(self.nrow()):
379                out.append(self._gettime(i))
380            return out
381        else:
382            if row < self.nrow():
383                return self._gettime(row)
[102]384
385    def set_unit(self, unit='channel'):
386        """
387        Set the unit for all following operations on this scantable
388        Parameters:
389            unit:    optional unit, default is 'channel'
[113]390                     one of '*Hz','km/s','channel', ''
[102]391        """
[484]392        varlist = vars()
[113]393        if unit in ['','pixel', 'channel']:
394            unit = ''
395        inf = list(self._getcoordinfo())
396        inf[0] = unit
397        self._setcoordinfo(inf)
398        if self._p: self.plot()
[484]399        self._add_history("set_unit",varlist)
[113]400
[484]401    def set_instrument(self, instr):
[358]402        """
403        Set the instrument for subsequent processing
404        Parameters:
[407]405            instr:    Select from 'ATPKSMB', 'ATPKSHOH', 'ATMOPRA',
406                      'DSS-43' (Tid), 'CEDUNA', and 'HOBART'
[358]407        """
408        self._setInstrument(instr)
[484]409        self._add_history("set_instument",vars())
[358]410
[276]411    def set_doppler(self, doppler='RADIO'):
412        """
413        Set the doppler for all following operations on this scantable.
414        Parameters:
415            doppler:    One of 'RADIO', 'OPTICAL', 'Z', 'BETA', 'GAMMA'
416        """
[484]417        varlist = vars()
[276]418        inf = list(self._getcoordinfo())
419        inf[2] = doppler
420        self._setcoordinfo(inf)
421        if self._p: self.plot()
[484]422        self._add_history("set_doppler",vars())
[432]423 
[226]424    def set_freqframe(self, frame=None):
[113]425        """
426        Set the frame type of the Spectral Axis.
427        Parameters:
428            frame:   an optional frame type, default 'LSRK'.
429        Examples:
430            scan.set_freqframe('BARY')
431        """
[484]432        if frame is None: frame = rcParams['scantable.freqframe']
433        varlist = vars()
[113]434        valid = ['REST','TOPO','LSRD','LSRK','BARY', \
435                   'GEO','GALACTO','LGROUP','CMB']
436        if frame in valid:
437            inf = list(self._getcoordinfo())
438            inf[1] = frame
439            self._setcoordinfo(inf)
[484]440            self._add_history("set_freqframe",varlist)
[102]441        else:
[113]442            print "Please specify a valid freq type. Valid types are:\n",valid
443           
444    def get_unit(self):
445        """
446        Get the default unit set in this scantable
447        Parameters:
448        Returns:
449            A unit string
450        """
451        inf = self._getcoordinfo()
452        unit = inf[0]
453        if unit == '': unit = 'channel'
454        return unit
[102]455
[158]456    def get_abcissa(self, rowno=0):
[102]457        """
[158]458        Get the abcissa in the current coordinate setup for the currently
[113]459        selected Beam/IF/Pol
460        Parameters:
[226]461            rowno:    an optional row number in the scantable. Default is the
462                      first row, i.e. rowno=0
[113]463        Returns:
[407]464            The abcissa values and it's format string (as a dictionary)
[113]465        """
[256]466        abc = self._getabcissa(rowno)
[407]467        lbl = self._getabcissalabel(rowno)       
[158]468        return abc, lbl
[407]469        #return {'abcissa':abc,'label':lbl}
[113]470
471    def create_mask(self, *args, **kwargs):
472        """
[102]473        Compute and return a mask based on [min,max] windows.
[189]474        The specified windows are to be INCLUDED, when the mask is
[113]475        applied.
[102]476        Parameters:
477            [min,max],[min2,max2],...
478                Pairs of start/end points specifying the regions
479                to be masked
[189]480            invert:     optional argument. If specified as True,
481                        return an inverted mask, i.e. the regions
482                        specified are EXCLUDED
[102]483        Example:
[113]484            scan.set_unit('channel')
485
486            a)
[102]487            msk = scan.set_mask([400,500],[800,900])
[189]488            # masks everything outside 400 and 500
[113]489            # and 800 and 900 in the unit 'channel'
490
491            b)
492            msk = scan.set_mask([400,500],[800,900], invert=True)
[189]493            # masks the regions between 400 and 500
[113]494            # and 800 and 900 in the unit 'channel'
495           
[102]496        """
[484]497        varlist = vars()
[113]498        u = self._getcoordinfo()[0]
499        if self._vb:
500            if u == "": u = "channel"
501            print "The current mask window unit is", u
[102]502        n = self.nchan()
[256]503        data = self._getabcissa()
[189]504        msk = zeros(n)
[484]505        for window in args:
[102]506            if (len(window) != 2 or window[0] > window[1] ):
507                print "A window needs to be defined as [min,max]"
508                return
509            for i in range(n):
[113]510                if data[i] >= window[0] and data[i] < window[1]:
[189]511                    msk[i] = 1
[113]512        if kwargs.has_key('invert'):
513            if kwargs.get('invert'):
514                from numarray import logical_not
515                msk = logical_not(msk)
[484]516        self._add_history("create_mask", varlist)
[102]517        return msk
[113]518   
[256]519    def get_restfreqs(self):
520        """
521        Get the restfrequency(s) stored in this scantable.
522        The return value(s) are always of unit 'Hz'
523        Parameters:
524            none
525        Returns:
526            a list of doubles
527        """
528        return list(self._getrestfreqs())
[102]529
[402]530    def lines(self):
[391]531        """
[402]532        Print the list of known spectral lines
533        """
534        sdtable._lines(self)
535
[484]536    def set_restfreqs(self, freqs=None, unit='Hz', lines=None, source=None,
537                      theif=None):
[402]538        """
[393]539        Select the restfrequency for the specified source and IF OR
540        replace for all IFs.  If the 'freqs' argument holds a scalar,
541        then that rest frequency will be applied to the selected
542        data (and added to the list of available rest frequencies).
543        In this way, you can set a rest frequency for each
544        source and IF combination.   If the 'freqs' argument holds
545        a vector, then it MUST be of length the number of IFs
546        (and the available restfrequencies will be replaced by
547        this vector).  In this case, *all* data ('source' and
548        'theif' are ignored) have the restfrequency set per IF according
549        to the corresponding value you give in the 'freqs' vector. 
550        E.g. 'freqs=[1e9,2e9]'  would mean IF 0 gets restfreq 1e9 and
551        IF 1 gets restfreq 2e9.
[402]552
553        You can also specify the frequencies via known line names
554        in the argument 'lines'.  Use 'freqs' or 'lines'.  'freqs'
555        takes precedence. See the list of known names via function
556        scantable.lines()
[391]557        Parameters:
[402]558            freqs:   list of rest frequencies
[393]559            unit:    unit for rest frequency (default 'Hz')
[402]560            lines:   list of known spectral lines names (alternative to freqs).
561                     See possible list via scantable.lines()
[391]562            source:  Source name (blank means all)
563            theif:   IF (-1 means all)
564        Example:
[393]565            scan.set_restfreqs(freqs=1.4e9, source='NGC253', theif=2)
566            scan.set_restfreqs(freqs=[1.4e9,1.67e9])
[391]567        """
[484]568        varlist = vars()
[391]569        if source is None:
570            source = ""
571        if theif is None:
572            theif = -1
[393]573        t = type(freqs)
574        if t is int or t is float:
575           freqs = [freqs]
[402]576        if freqs is None:
577           freqs = []
578        t = type(lines)
579        if t is str:
580           lines = [lines]
581        if lines is None:
582           lines = []
583        sdtable._setrestfreqs(self, freqs, unit, lines, source, theif)
[484]584        self._add_history("set_restfreqs", varlist)
585       
[391]586
587
[102]588    def flag_spectrum(self, thebeam, theif, thepol):
589        """
590        This flags a selected spectrum in the scan 'for good'.
591        USE WITH CARE - not reversible.
592        Use masks for non-permanent exclusion of channels.
593        Parameters:
594            thebeam,theif,thepol:    all have to be explicitly
595                                     specified
596        Example:
597            scan.flag_spectrum(0,0,1)
598            flags the spectrum for Beam=0, IF=0, Pol=1
599        """
[407]600        if (thebeam < self.nbeam() and
601            theif < self.nif() and
602            thepol < self.npol()):
603            sdtable.setbeam(self, thebeam)
604            sdtable.setif(self, theif)
605            sdtable.setpol(self, thepol)
606            sdtable._flag(self)
[484]607            self._add_history("flag_spectrum", vars())
[102]608        else:
609            print "Please specify a valid (Beam/IF/Pol)"
610        return
[113]611
612    def plot(self, what='spectrum',col='Pol', panel=None):
613        """
614        Plot the spectra contained in the scan. Alternatively you can also
615        Plot Tsys vs Time
616        Parameters:
617            what:     a choice of 'spectrum' (default) or 'tsys'
[135]618            col:      which out of Beams/IFs/Pols should be colour stacked
[113]619            panel:    set up multiple panels, currently not working.
620        """
[283]621        print "Warning! Not fully functional. Use plotter.plot() instead"
622       
[113]623        validcol = {'Beam':self.nbeam(),'IF':self.nif(),'Pol':self.npol()}
[124]624
[113]625        validyax = ['spectrum','tsys']
[189]626        from asap.asaplot import ASAPlot
[113]627        if not self._p:
628            self._p = ASAPlot()
[189]629            #print "Plotting not enabled"
630            #return
631        if self._p.is_dead:
632            del self._p
633            self._p = ASAPlot()
[113]634        npan = 1
635        x = None
636        if what == 'tsys':
637            n = self.nrow()
638            if n < 2:
639                print "Only one integration. Can't plot."
640                return
[124]641        self._p.hold()
642        self._p.clear()
[113]643        if panel == 'Time':
644            npan = self.nrow()
[124]645            self._p.set_panels(rows=npan)
[113]646        xlab,ylab,tlab = None,None,None
[226]647        self._vb = False
[256]648        sel = self.get_cursor()       
[113]649        for i in range(npan):
[226]650            if npan > 1:
651                self._p.subplot(i)
[113]652            for j in range(validcol[col]):
653                x = None
654                y = None
655                m = None
656                tlab = self._getsourcename(i)
[124]657                import re
658                tlab = re.sub('_S','',tlab)
[113]659                if col == 'Beam':
660                    self.setbeam(j)
661                elif col == 'IF':
662                    self.setif(j)
663                elif col == 'Pol':
664                    self.setpol(j)
665                if what == 'tsys':
666                    x = range(self.nrow())
667                    xlab = 'Time [pixel]'
668                    m = list(ones(len(x)))
669                    y = []
670                    ylab = r'$T_{sys}$'
671                    for k in range(len(x)):
672                        y.append(self._gettsys(k))
673                else:
[158]674                    x,xlab = self.get_abcissa(i)
[256]675                    y = self._getspectrum(i)
[113]676                    ylab = r'Flux'
[256]677                    m = self._getmask(i)
[113]678                llab = col+' '+str(j)
679                self._p.set_line(label=llab)
680                self._p.plot(x,y,m)
[124]681            self._p.set_axes('xlabel',xlab)
682            self._p.set_axes('ylabel',ylab)
683            self._p.set_axes('title',tlab)
[113]684        self._p.release()
[256]685        self.set_cursor(sel[0],sel[1],sel[2])
[226]686        self._vb = rcParams['verbose']
[113]687        return
[256]688
689        print out
690
691    def _print_values(self, dat, label='', timestamps=[]):
692        d = dat['data']
693        a = dat['axes']
694        shp = d.getshape()
695        out = ''
696        for i in range(shp[3]):
697            out += '%s [%s]:\n' % (a[3],timestamps[i])
698            t = d[:,:,:,i]
699            for j in range(shp[0]):
700                if shp[0] > 1: out +=  ' %s[%d] ' % (a[0],j)
701                for k in range(shp[1]):
702                    if shp[1] > 1: out +=  ' %s[%d] ' % (a[1],k)
703                    for l in range(shp[2]):
704                        if shp[2] > 1: out +=  ' %s[%d] ' % (a[2],l)
705                        out += '= %3.3f\n' % (t[j,k,l])
[484]706            out += "-"*80
707            out += "\n"
708        print "-"*80
[256]709        print " ", label
[484]710        print "-"*80
[256]711        print out
[484]712
713    def history(self):
714        hist = list(self._gethistory())
715        print "-"*80
716        for h in hist:
[489]717            if h.startswith("---"):
718                print h
719            else:
720                items = h.split("##")
721                date = items[0]
722                func = items[1]
723                items = items[2:]
724                print date           
725                print "Function: %s\n  Parameters:" % (func)
726                for i in items:
727                    s = i.split("=")
728                    print "   %s = %s" % (s[0],s[1])
729                print "-"*80
[484]730        return
731
732    def _add_history(self, funcname, parameters):
733        # create date
734        sep = "##"
735        from datetime import datetime
736        dstr = datetime.now().strftime('%Y/%m/%d %H:%M:%S')
737        hist = dstr+sep
738        hist += funcname+sep#cdate+sep
739        if parameters.has_key('self'): del parameters['self']
740        for k,v in parameters.iteritems():
741            if type(v) is dict:
742                for k2,v2 in v.iteritems():
743                    hist += k2
744                    hist += "="
745                    if isinstance(v2,scantable):
746                        hist += 'scantable'
747                    elif k2 == 'mask':
748                        hist += str(self._zip_mask(v2))
749                    else:
750                        hist += str(v2)                   
751            else:
752                hist += k
753                hist += "="
754                if isinstance(v,scantable):
755                    hist += 'scantable'
756                elif k == 'mask':
757                    hist += str(self._zip_mask(v))
758                else:
759                    hist += str(v)
760            hist += sep
761        hist = hist[:-2] # remove trailing '##'
762        self._addhistory(hist)
763       
764
765    def _zip_mask(self, mask):
766        mask = list(mask)
767        i = 0
768        segments = []
769        while mask[i:].count(1):
770            i += mask[i:].index(1)
771            if mask[i:].count(0):
772                j = i + mask[i:].index(0)
773            else:
774                j = len(mask)               
775            segments.append([i,j])
776            i = j
777        return segments
Note: See TracBrowser for help on using the repository browser.