source: trunk/python/scantable.py @ 1079

Last change on this file since 1079 was 1079, checked in by mar637, 18 years ago

make storage rcparam casa-insensitive

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 56.9 KB
Line 
1from asap._asap import Scantable
2from asap import rcParams
3from asap import print_log, asaplog
4from asap import selector
5from numarray import ones,zeros
6import sys
7
8class scantable(Scantable):
9    """
10        The ASAP container for scans
11    """
12
13    def __init__(self, filename, average=None, unit=None):
14        """
15        Create a scantable from a saved one or make a reference
16        Parameters:
17            filename:    the name of an asap table on disk
18                         or
19                         the name of a rpfits/sdfits/ms file
20                         (integrations within scans are auto averaged
21                         and the whole file is read)
22                         or
23                         [advanced] a reference to an existing
24                         scantable
25            average:     average all integrations withinb a scan on read.
26                         The default (True) is taken from .asaprc.
27            unit:         brightness unit; must be consistent with K or Jy.
28                         Over-rides the default selected by the reader
29                         (input rpfits/sdfits/ms) or replaces the value
30                         in existing scantables
31        """
32        if average is None:
33            average = rcParams['scantable.autoaverage']
34        varlist = vars()
35        from asap._asap import stmath
36        self._math = stmath()
37        if isinstance(filename, Scantable):
38            Scantable.__init__(self, filename)
39        else:
40            if isinstance(filename,str):
41                import os.path
42                filename = os.path.expandvars(filename)
43                filename = os.path.expanduser(filename)
44                if not os.path.exists(filename):
45                    s = "File '%s' not found." % (filename)
46                    if rcParams['verbose']:
47                        asaplog.push(s)
48                        print asaplog.pop().strip()
49                        return
50                    raise IOError(s)
51                if os.path.isdir(filename):
52                    # crude check if asap table
53                    if os.path.exists(filename+'/table.info'):
54                        Scantable.__init__(self, filename, rcParams['scantable.storage']=='disk')
55                        if unit is not None:
56                            self.set_fluxunit(unit)
57                        self.set_freqframe(rcParams['scantable.freqframe'])
58                    else:
59                        msg = "The given file '%s'is not a valid asap table." % (filename)
60                        if rcParams['verbose']:
61                            print msg
62                            return
63                        else:
64                            raise IOError(msg)
65                else:
66                    self._fill([filename],unit, average)
67            elif (isinstance(filename,list) or isinstance(filename,tuple)) \
68                  and isinstance(filename[-1], str):
69                self._fill(filename, unit, average)
70        print_log()
71
72    def save(self, name=None, format=None, overwrite=False):
73        """
74        Store the scantable on disk. This can be an asap (aips++) Table, SDFITS,
75        Image FITS or MS2 format.
76        Parameters:
77            name:        the name of the outputfile. For format="FITS" this
78                         is the directory file name into which all the files
79                         will be written (default is 'asap_FITS'). For format
80                         "ASCII" this is the root file name (data in 'name'.txt
81                         and header in 'name'_header.txt)
82            format:      an optional file format. Default is ASAP.
83                         Allowed are - 'ASAP' (save as ASAP [aips++] Table),
84                                       'SDFITS' (save as SDFITS file)
85                                       'FITS' (saves each row as a FITS Image)
86                                       'ASCII' (saves as ascii text file)
87                                       'MS2' (saves as an aips++
88                                              MeasurementSet V2)
89            overwrite:   If the file should be overwritten if it exists.
90                         The default False is to return with warning
91                         without writing the output. USE WITH CARE.
92        Example:
93            scan.save('myscan.asap')
94            scan.save('myscan.sdfits','SDFITS')
95        """
96        from os import path
97        if format is None: format = rcParams['scantable.save']
98        suffix = '.'+format.lower()
99        if name is None or name =="":
100            name = 'scantable'+suffix
101            from asap import asaplog
102            msg = "No filename given. Using default name %s..." % name
103            asaplog.push(msg)
104        name = path.expandvars(name)
105        if path.isfile(name) or path.isdir(name):
106            if not overwrite:
107                msg = "File %s exists." % name
108                if rcParams['verbose']:
109                    print msg
110                    return
111                else:
112                    raise IOError(msg)
113        format2 = format.upper()
114        if format2 == 'ASAP':
115            self._save(name)
116        else:
117            from asap._asap import stwriter as stw
118            w = stw(format2)
119            w.write(self, name)
120        print_log()
121        return
122
123    def copy(self):
124        """
125        Return a copy of this scantable.
126        Parameters:
127            none
128        Example:
129            copiedscan = scan.copy()
130        """
131        sd = scantable(Scantable._copy(self))
132        return sd
133
134    def get_scan(self, scanid=None):
135        """
136        Return a specific scan (by scanno) or collection of scans (by
137        source name) in a new scantable.
138        Parameters:
139            scanid:    a (list of) scanno or a source name, unix-style
140                       patterns are accepted for source name matching, e.g.
141                       '*_R' gets all 'ref scans
142        Example:
143            # get all scans containing the source '323p459'
144            newscan = scan.get_scan('323p459')
145            # get all 'off' scans
146            refscans = scan.get_scan('*_R')
147            # get a susbset of scans by scanno (as listed in scan.summary())
148            newscan = scan.get_scan([0,2,7,10])
149        """
150        if scanid is None:
151            if rcParams['verbose']:
152                print "Please specify a scan no or name to retrieve from the scantable"
153                return
154            else:
155                raise RuntimeError("No scan given")
156
157        try:
158            bsel = self.get_selection()
159            sel = selector()
160            if type(scanid) is str:
161                sel.set_name(scanid)
162                self.set_selection(bsel+sel)
163                scopy = self._copy()
164                self.set_selection(bsel)
165                return scantable(scopy)
166            elif type(scanid) is int:
167                sel.set_scans([scanid])
168                self.set_selection(bsel+sel)
169                scopy = self._copy()
170                self.set_selection(bsel)
171                return scantable(scopy)
172            elif type(scanid) is list:
173                sel.set_scans(scanid)
174                self.set_selection(sel)
175                scopy = self._copy()
176                self.set_selection(bsel)
177                return scantable(scopy)
178            else:
179                msg = "Illegal scanid type, use 'int' or 'list' if ints."
180                if rcParams['verbose']:
181                    print msg
182                else:
183                    raise TypeError(msg)
184        except RuntimeError:
185            if rcParams['verbose']: print "Couldn't find any match."
186            else: raise
187
188    def __str__(self):
189        return Scantable._summary(self,True)
190
191    def summary(self, filename=None):
192        """
193        Print a summary of the contents of this scantable.
194        Parameters:
195            filename:    the name of a file to write the putput to
196                         Default - no file output
197            verbose:     print extra info such as the frequency table
198                         The default (False) is taken from .asaprc
199        """
200        info = Scantable._summary(self, True)
201        #if verbose is None: verbose = rcParams['scantable.verbosesummary']
202        if filename is not None:
203            if filename is "":
204                filename = 'scantable_summary.txt'
205            from os.path import expandvars, isdir
206            filename = expandvars(filename)
207            if not isdir(filename):
208                data = open(filename, 'w')
209                data.write(info)
210                data.close()
211            else:
212                msg = "Illegal file name '%s'." % (filename)
213                if rcParams['verbose']:
214                    print msg
215                else:
216                    raise IOError(msg)
217        if rcParams['verbose']:
218            try:
219                from IPython.genutils import page as pager
220            except ImportError:
221                from pydoc import pager
222            pager(info)
223        else:
224            return info
225
226
227    def get_selection(self):
228        """
229        Get the selection object currently set on this scantable.
230        Parameters:
231            none
232        Example:
233            sel = scan.get_selection()
234            sel.set_ifs(0)              # select IF 0
235            scan.set_selection(sel)     # apply modified selection
236        """
237        return selector(self._getselection())
238
239    def set_selection(self, selection=selector()):
240        """
241        Select a subset of the data. All following operations on this scantable
242        are only applied to thi selection.
243        Parameters:
244            selection:    a selector object (default unset the selection)
245        Examples:
246            sel = selector()         # create a selection object
247            self.set_scans([0,3])    # select SCANNO 0 and 3
248            scan.set_selection(sel)  # set the selection
249            scan.summary()           # will only print summary of scanno 0 an 3
250            scan.set_selection()     # unset the selection
251        """
252        self._setselection(selection)
253
254    def set_cursor(self, beam=0, IF=0, pol=0):
255        print "DEPRECATED - use set_selection"
256
257    def get_cursor(self):
258        print "DEPRECATED - use get_selection"
259
260    def stats(self, stat='stddev', mask=None):
261        """
262        Determine the specified statistic of the current beam/if/pol
263        Takes a 'mask' as an optional parameter to specify which
264        channels should be excluded.
265        Parameters:
266            stat:    'min', 'max', 'sumsq', 'sum', 'mean'
267                     'var', 'stddev', 'avdev', 'rms', 'median'
268            mask:    an optional mask specifying where the statistic
269                     should be determined.
270        Example:
271            scan.set_unit('channel')
272            msk = scan.create_mask([100,200],[500,600])
273            scan.stats(stat='mean', mask=m)
274        """
275        from numarray import array,zeros,Float
276        if mask == None:
277            mask = []
278        axes = ['Beam','IF','Pol','Time']
279        if not self._check_ifs():
280             raise ValueError("Cannot apply mask as the IFs have different number of channels"
281                              "Please use setselection() to select individual IFs")
282
283        statvals = self._math._stats(self, mask, stat)
284        out = ''
285        axes = []
286        for i in range(self.nrow()):
287            axis = []
288            axis.append(self.getscan(i))
289            axis.append(self.getbeam(i))
290            axis.append(self.getif(i))
291            axis.append(self.getpol(i))
292            axis.append(self.getcycle(i))
293            axes.append(axis)
294            tm = self._gettime(i)
295            src = self._getsourcename(i)
296            out += 'Scan[%d] (%s) ' % (axis[0], src)
297            out += 'Time[%s]:\n' % (tm)
298            if self.nbeam(-1) > 1: out +=  ' Beam[%d] ' % (axis[1])
299            if self.nif(-1) > 1: out +=  ' IF[%d] ' % (axis[2])
300            if self.npol(-1) > 1: out +=  ' Pol[%d] ' % (axis[3])
301            out += '= %3.3f\n' % (statvals[i])
302            out +=  "--------------------------------------------------\n"
303
304        if rcParams['verbose']:
305            print "--------------------------------------------------"
306            print " ",stat
307            print "--------------------------------------------------"
308            print out
309        retval = { 'axesnames': ['scanno','beamno','ifno','polno','cycleno'],
310                   'axes' : axes,
311                   'data': statvals}
312        return retval
313
314    def stddev(self,mask=None):
315        """
316        Determine the standard deviation of the current beam/if/pol
317        Takes a 'mask' as an optional parameter to specify which
318        channels should be excluded.
319        Parameters:
320            mask:    an optional mask specifying where the standard
321                     deviation should be determined.
322
323        Example:
324            scan.set_unit('channel')
325            msk = scan.create_mask([100,200],[500,600])
326            scan.stddev(mask=m)
327        """
328        return self.stats(stat='stddev',mask=mask);
329
330
331    def column_names(self):
332        """
333        Return a  list of column names, which can be used for selection.
334        """
335        return list(Scantable.column_names(self))
336
337    def get_tsys(self):
338        """
339        Return the System temperatures.
340        Parameters:
341
342        Returns:
343            a list of Tsys values for the current selection
344        """
345
346        return self._row_callback(self._gettsys, "Tsys")
347
348    def _row_callback(self, callback, label):
349        axes = []
350        axesnames = ['scanno','beamno','ifno','polno','cycleno']
351        out = ""
352        outvec =[]
353        for i in range(self.nrow()):
354            axis = []
355            axis.append(self.getscan(i))
356            axis.append(self.getbeam(i))
357            axis.append(self.getif(i))
358            axis.append(self.getpol(i))
359            axis.append(self.getcycle(i))
360            axes.append(axis)
361            tm = self._gettime(i)
362            src = self._getsourcename(i)
363            out += 'Scan[%d] (%s) ' % (axis[0], src)
364            out += 'Time[%s]:\n' % (tm)
365            if self.nbeam(-1) > 1: out +=  ' Beam[%d] ' % (axis[1])
366            if self.nif(-1) > 1: out +=  ' IF[%d] ' % (axis[2])
367            if self.npol(-1) > 1: out +=  ' Pol[%d] ' % (axis[3])
368            outvec.append(callback(i))
369            out += '= %3.3f\n' % (outvec[i])
370            out +=  "--------------------------------------------------\n"
371        if rcParams['verbose']:
372            print "--------------------------------------------------"
373            print " %s" % (label)
374            print "--------------------------------------------------"
375            print out
376        retval = {'axesnames': axesnames, 'axes': axes, 'data': outvec}
377        return retval
378
379    def _get_column(self, callback, row=-1):
380        """
381        """
382        if row == -1:
383            return [callback(i) for i in range(self.nrow())]
384        else:
385            if  0 <= row < self.nrow():
386                return callback(row)
387
388
389    def get_time(self, row=-1):
390        """
391        Get a list of time stamps for the observations.
392        Return a string for each integration in the scantable.
393        Parameters:
394            row:    row no of integration. Default -1 return all rows
395        Example:
396            none
397        """
398        return self._get_column(self._gettime, row)
399
400    def get_sourcename(self, row=-1):
401        """
402        Get a list source names for the observations.
403        Return a string for each integration in the scantable.
404        Parameters:
405            row:    row no of integration. Default -1 return all rows
406        Example:
407            none
408        """
409        return self._get_column(self._getsourcename, row)
410
411    def get_elevation(self, row=-1):
412        """
413        Get a list of elevations for the observations.
414        Return a float for each integration in the scantable.
415        Parameters:
416            row:    row no of integration. Default -1 return all rows
417        Example:
418            none
419        """
420        return self._get_column(self._getelevation, row)
421
422    def get_azimuth(self, row=-1):
423        """
424        Get a list of azimuths for the observations.
425        Return a float for each integration in the scantable.
426        Parameters:
427            row:    row no of integration. Default -1 return all rows
428        Example:
429            none
430        """
431        return self._get_column(self._getazimuth, row)
432
433    def get_parangle(self, row=-1):
434        """
435        Get a list of parallactic angles for the observations.
436        Return a float for each integration in the scantable.
437        Parameters:
438            row:    row no of integration. Default -1 return all rows
439        Example:
440            none
441        """
442        return self._get_column(self._getparangle, row)
443
444    def get_direction(self, row=-1):
445        """
446        Get a list of Positions on the sky (direction) for the observations.
447        Return a float for each integration in the scantable.
448        Parameters:
449            row:    row no of integration. Default -1 return all rows
450        Example:
451            none
452        """
453        return self._get_column(self._getdirection, row)
454
455    def set_unit(self, unit='channel'):
456        """
457        Set the unit for all following operations on this scantable
458        Parameters:
459            unit:    optional unit, default is 'channel'
460                     one of '*Hz','km/s','channel', ''
461        """
462        varlist = vars()
463        if unit in ['','pixel', 'channel']:
464            unit = ''
465        inf = list(self._getcoordinfo())
466        inf[0] = unit
467        self._setcoordinfo(inf)
468        self._add_history("set_unit",varlist)
469
470    def set_instrument(self, instr):
471        """
472        Set the instrument for subsequent processing
473        Parameters:
474            instr:    Select from 'ATPKSMB', 'ATPKSHOH', 'ATMOPRA',
475                      'DSS-43' (Tid), 'CEDUNA', and 'HOBART'
476        """
477        self._setInstrument(instr)
478        self._add_history("set_instument",vars())
479        print_log()
480
481    def set_doppler(self, doppler='RADIO'):
482        """
483        Set the doppler for all following operations on this scantable.
484        Parameters:
485            doppler:    One of 'RADIO', 'OPTICAL', 'Z', 'BETA', 'GAMMA'
486        """
487        varlist = vars()
488        inf = list(self._getcoordinfo())
489        inf[2] = doppler
490        self._setcoordinfo(inf)
491        self._add_history("set_doppler",vars())
492        print_log()
493
494    def set_freqframe(self, frame=None):
495        """
496        Set the frame type of the Spectral Axis.
497        Parameters:
498            frame:   an optional frame type, default 'LSRK'. Valid frames are:
499                     'REST','TOPO','LSRD','LSRK','BARY',
500                     'GEO','GALACTO','LGROUP','CMB'
501        Examples:
502            scan.set_freqframe('BARY')
503        """
504        if frame is None: frame = rcParams['scantable.freqframe']
505        varlist = vars()
506        valid = ['REST','TOPO','LSRD','LSRK','BARY', \
507                   'GEO','GALACTO','LGROUP','CMB']
508
509        if frame in valid:
510            inf = list(self._getcoordinfo())
511            inf[1] = frame
512            self._setcoordinfo(inf)
513            self._add_history("set_freqframe",varlist)
514        else:
515            msg  = "Please specify a valid freq type. Valid types are:\n",valid
516            if rcParams['verbose']:
517                print msg
518            else:
519                raise TypeError(msg)
520        print_log()
521
522    def set_dirframe(self, frame=""):
523        """
524        Set the frame type of the Direction on the sky.
525        Parameters:
526            frame:   an optional frame type, default ''. Valid frames are:
527                     'J2000', 'B1950', 'GALACTIC'
528        Examples:
529            scan.set_dirframe('GALACTIC')
530        """
531        varlist = vars()
532        try:
533            Scantable.set_dirframe(self, frame)
534        except RuntimeError,msg:
535            if rcParams['verbose']:
536                print msg
537            else:
538                raise
539        self._add_history("set_dirframe",varlist)
540
541    def get_unit(self):
542        """
543        Get the default unit set in this scantable
544        Parameters:
545        Returns:
546            A unit string
547        """
548        inf = self._getcoordinfo()
549        unit = inf[0]
550        if unit == '': unit = 'channel'
551        return unit
552
553    def get_abcissa(self, rowno=0):
554        """
555        Get the abcissa in the current coordinate setup for the currently
556        selected Beam/IF/Pol
557        Parameters:
558            rowno:    an optional row number in the scantable. Default is the
559                      first row, i.e. rowno=0
560        Returns:
561            The abcissa values and it's format string (as a dictionary)
562        """
563        abc = self._getabcissa(rowno)
564        lbl = self._getabcissalabel(rowno)
565        print_log()
566        return abc, lbl
567
568    def flag(self, mask=[]):
569        """
570        Flag the selected data using an optional channel mask.
571        Parameters:
572            mask:   an optional channel mask, created with create_mask. Default
573                    (no mask) is all channels.
574        """
575        varlist = vars()
576        try:
577            self._flag(mask)
578        except RuntimeError,msg:
579            if rcParams['verbose']:
580                print msg
581                return
582            else: raise
583        self._add_history("flag", varlist)
584
585
586    def create_mask(self, *args, **kwargs):
587        """
588        Compute and return a mask based on [min,max] windows.
589        The specified windows are to be INCLUDED, when the mask is
590        applied.
591        Parameters:
592            [min,max],[min2,max2],...
593                Pairs of start/end points (inclusive)specifying the regions
594                to be masked
595            invert:     optional argument. If specified as True,
596                        return an inverted mask, i.e. the regions
597                        specified are EXCLUDED
598            row:        create the mask using the specified row for
599                        unit conversions, default is row=0
600                        only necessary if frequency varies over rows.
601        Example:
602            scan.set_unit('channel')
603            a)
604            msk = scan.create_mask([400,500],[800,900])
605            # masks everything outside 400 and 500
606            # and 800 and 900 in the unit 'channel'
607
608            b)
609            msk = scan.create_mask([400,500],[800,900], invert=True)
610            # masks the regions between 400 and 500
611            # and 800 and 900 in the unit 'channel'
612            c)
613            mask only channel 400
614            msk =  scan.create_mask([400,400])
615        """
616        row = 0
617        if kwargs.has_key("row"):
618            row = kwargs.get("row")
619        data = self._getabcissa(row)
620        u = self._getcoordinfo()[0]
621        if rcParams['verbose']:
622            if u == "": u = "channel"
623            from asap import asaplog
624            msg = "The current mask window unit is %s" % u
625            if not self._check_ifs():
626                msg += "\nThis mask is only valid for IF=%d" % (self.getif(i))
627            asaplog.push(msg)
628        n = self.nchan()
629        msk = zeros(n)
630        # test if args is a 'list' or a 'normal *args - UGLY!!!
631
632        ws = (isinstance(args[-1][-1],int) or isinstance(args[-1][-1],float)) and args or args[0]
633        for window in ws:
634            if (len(window) != 2 or window[0] > window[1] ):
635                raise TypeError("A window needs to be defined as [min,max]")
636            for i in range(n):
637                if data[i] >= window[0] and data[i] <= window[1]:
638                    msk[i] = 1
639        if kwargs.has_key('invert'):
640            if kwargs.get('invert'):
641                from numarray import logical_not
642                msk = logical_not(msk)
643        print_log()
644        return msk
645
646    def get_restfreqs(self):
647        """
648        Get the restfrequency(s) stored in this scantable.
649        The return value(s) are always of unit 'Hz'
650        Parameters:
651            none
652        Returns:
653            a list of doubles
654        """
655        return list(self._getrestfreqs())
656
657
658    def set_restfreqs(self, freqs=None, unit='Hz'):
659        """
660        Set or replace the restfrequency specified and
661        If the 'freqs' argument holds a scalar,
662        then that rest frequency will be applied to all the selected
663        data.  If the 'freqs' argument holds
664        a vector, then it MUST be of equal or smaller length than
665        the number of IFs (and the available restfrequencies will be
666        replaced by this vector).  In this case, *all* data have
667        the restfrequency set per IF according
668        to the corresponding value you give in the 'freqs' vector.
669        E.g. 'freqs=[1e9,2e9]'  would mean IF 0 gets restfreq 1e9 and
670        IF 1 gets restfreq 2e9.
671        You can also specify the frequencies via known line names
672        from the built-in Lovas table.
673        Parameters:
674            freqs:   list of rest frequency values or string idenitfiers
675            unit:    unit for rest frequency (default 'Hz')
676
677        Example:
678            # set the given restfrequency for the whole table
679            scan.set_restfreqs(freqs=1.4e9)
680            # If thee number of IFs in the data is >= 2 the IF0 gets the first
681            # value IF1 the second...
682            scan.set_restfreqs(freqs=[1.4e9,1.67e9])
683            #set the given restfrequency for the whole table (by name)
684            scan.set_restfreqs(freqs="OH1667")
685
686        Note:
687            To do more sophisticate Restfrequency setting, e.g. on a
688            source and IF basis, use scantable.set_selection() before using
689            this function.
690            # provide your scantable is call scan
691            selection = selector()
692            selection.set_name("ORION*")
693            selection.set_ifs([1])
694            scan.set_selection(selection)
695            scan.set_restfreqs(freqs=86.6e9)
696
697        """
698        varlist = vars()
699
700        t = type(freqs)
701        if isinstance(freqs, int) or isinstance(freqs,float):
702           self._setrestfreqs(freqs, unit)
703        elif isinstance(freqs, list) or isinstance(freqs,tuple):
704            if isinstance(freqs[-1], int) or isinstance(freqs[-1],float):
705                sel = selector()
706                savesel = self._getselection()
707                for i in xrange(len(freqs)):
708                    sel.set_ifs([i])
709                    self._setselection(sel)
710                    self._setrestfreqs(freqs[i], unit)
711                self._setselection(savesel)
712            elif isinstance(freqs[-1], str):
713                # not yet implemented
714                pass
715        else:
716            return
717        self._add_history("set_restfreqs", varlist)
718
719
720
721    def history(self):
722        hist = list(self._gethistory())
723        out = "-"*80
724        for h in hist:
725            if h.startswith("---"):
726                out += "\n"+h
727            else:
728                items = h.split("##")
729                date = items[0]
730                func = items[1]
731                items = items[2:]
732                out += "\n"+date+"\n"
733                out += "Function: %s\n  Parameters:" % (func)
734                for i in items:
735                    s = i.split("=")
736                    out += "\n   %s = %s" % (s[0],s[1])
737                out += "\n"+"-"*80
738        try:
739            from IPython.genutils import page as pager
740        except ImportError:
741            from pydoc import pager
742        pager(out)
743        return
744
745    #
746    # Maths business
747    #
748
749    def average_time(self, mask=None, scanav=False, weight='tint', align=False):
750        """
751        Return the (time) weighted average of a scan.
752        Note:
753            in channels only - align if necessary
754        Parameters:
755            one scan or comma separated  scans
756            mask:     an optional mask (only used for 'var' and 'tsys'
757                      weighting)
758            scanav:   True averages each scan separately
759                      False (default) averages all scans together,
760            weight:   Weighting scheme. 'none', 'var' (1/var(spec)
761                      weighted), 'tsys' (1/Tsys**2 weighted), 'tint'
762                      (integration time weighted) or 'tintsys' (Tint/Tsys**2).
763                      The default is 'tint'
764            align:    align the spectra in velocity before averaging. It takes
765                      the time of the first spectrum as reference time.
766        Example:
767            # time average the scantable without using a mask
768            newscan = scan.average_time()
769        """
770        varlist = vars()
771        if weight is None: weight = 'TINT'
772        if mask is None: mask = ()
773        if scanav:
774            scanav = "SCAN"
775        else:
776            scanav = "NONE"
777        scan = (self,)
778        try:
779          if align:
780              scan = (self.freq_align(insitu=False),)
781          s = scantable(self._math._average(scan, mask, weight.upper(),
782                        scanav))
783        except RuntimeError,msg:
784            if rcParams['verbose']:
785                print msg
786                return
787            else: raise
788        s._add_history("average_time",varlist)
789        print_log()
790        return s
791
792    def average_channel(self, mode="MEDIAN", scanav=False, align=False):
793        """
794        Return the (median) average of a scan.
795        Note:
796            in channels only - align if necessary
797            the median Tsys is computed.
798        Parameters:
799            one scan or comma separated  scans
800            mode:     type of average, default "MEDIAN"
801            scanav:   True averages each scan separately
802                      False (default) averages all scans together,
803            align:    align the spectra in velocity before averaging. It takes
804                      the time of the first spectrum as reference time.
805        Example:
806            # median average the scan
807            newscan = scan.average_channel()
808        """
809        varlist = vars()
810        if mode is None: mode = 'MEDIAN'
811        scanav = "NONE"
812        if scanav: scanav = "SCAN"
813        scan = self
814        try:
815          if align:
816              scan = self.freq_align(insitu=False)
817          s = scantable(self._math._averagechannel(scan, mode, scanav))
818        except RuntimeError,msg:
819            if rcParams['verbose']:
820                print msg
821                return
822            else: raise
823        s._add_history("average_channel",varlist)
824        print_log()
825        return s
826
827    def convert_flux(self, jyperk=None, eta=None, d=None, insitu=None):
828        """
829        Return a scan where all spectra are converted to either
830        Jansky or Kelvin depending upon the flux units of the scan table.
831        By default the function tries to look the values up internally.
832        If it can't find them (or if you want to over-ride), you must
833        specify EITHER jyperk OR eta (and D which it will try to look up
834        also if you don't set it). jyperk takes precedence if you set both.
835        Parameters:
836            jyperk:      the Jy / K conversion factor
837            eta:         the aperture efficiency
838            d:           the geomtric diameter (metres)
839            insitu:      if False a new scantable is returned.
840                         Otherwise, the scaling is done in-situ
841                         The default is taken from .asaprc (False)
842            allaxes:         if True apply to all spectra. Otherwise
843                         apply only to the selected (beam/pol/if)spectra only
844                         The default is taken from .asaprc (True if none)
845        """
846        if insitu is None: insitu = rcParams['insitu']
847        self._math._setinsitu(insitu)
848        varlist = vars()
849        if jyperk is None: jyperk = -1.0
850        if d is None: d = -1.0
851        if eta is None: eta = -1.0
852        s = scantable(self._math._convertflux(self, d, eta, jyperk))
853        s._add_history("convert_flux", varlist)
854        print_log()
855        if insitu: self._assign(s)
856        else: return s
857
858    def gain_el(self, poly=None, filename="", method="linear", insitu=None):
859        """
860        Return a scan after applying a gain-elevation correction.
861        The correction can be made via either a polynomial or a
862        table-based interpolation (and extrapolation if necessary).
863        You specify polynomial coefficients, an ascii table or neither.
864        If you specify neither, then a polynomial correction will be made
865        with built in coefficients known for certain telescopes (an error
866        will occur if the instrument is not known).
867        The data and Tsys are *divided* by the scaling factors.
868        Parameters:
869            poly:        Polynomial coefficients (default None) to compute a
870                         gain-elevation correction as a function of
871                         elevation (in degrees).
872            filename:    The name of an ascii file holding correction factors.
873                         The first row of the ascii file must give the column
874                         names and these MUST include columns
875                         "ELEVATION" (degrees) and "FACTOR" (multiply data
876                         by this) somewhere.
877                         The second row must give the data type of the
878                         column. Use 'R' for Real and 'I' for Integer.
879                         An example file would be
880                         (actual factors are arbitrary) :
881
882                         TIME ELEVATION FACTOR
883                         R R R
884                         0.1 0 0.8
885                         0.2 20 0.85
886                         0.3 40 0.9
887                         0.4 60 0.85
888                         0.5 80 0.8
889                         0.6 90 0.75
890            method:      Interpolation method when correcting from a table.
891                         Values are  "nearest", "linear" (default), "cubic"
892                         and "spline"
893            insitu:      if False a new scantable is returned.
894                         Otherwise, the scaling is done in-situ
895                         The default is taken from .asaprc (False)
896        """
897
898        if insitu is None: insitu = rcParams['insitu']
899        self._math._setinsitu(insitu)
900        varlist = vars()
901        if poly is None:
902           poly = ()
903        from os.path import expandvars
904        filename = expandvars(filename)
905        s = scantable(self._math._gainel(self, poly, filename, method))
906        s._add_history("gain_el", varlist)
907        print_log()
908        if insitu: self._assign(s)
909        else: return s
910
911    def freq_align(self, reftime=None, method='cubic', insitu=None):
912        """
913        Return a scan where all rows have been aligned in frequency/velocity.
914        The alignment frequency frame (e.g. LSRK) is that set by function
915        set_freqframe.
916        Parameters:
917            reftime:     reference time to align at. By default, the time of
918                         the first row of data is used.
919            method:      Interpolation method for regridding the spectra.
920                         Choose from "nearest", "linear", "cubic" (default)
921                         and "spline"
922            insitu:      if False a new scantable is returned.
923                         Otherwise, the scaling is done in-situ
924                         The default is taken from .asaprc (False)
925        """
926        if insitu is None: insitu = rcParams["insitu"]
927        self._math._setinsitu(insitu)
928        varlist = vars()
929        if reftime is None: reftime = ""
930        s = scantable(self._math._freq_align(self, reftime, method))
931        s._add_history("freq_align", varlist)
932        print_log()
933        if insitu: self._assign(s)
934        else: return s
935
936    def opacity(self, tau, insitu=None):
937        """
938        Apply an opacity correction. The data
939        and Tsys are multiplied by the correction factor.
940        Parameters:
941            tau:         Opacity from which the correction factor is
942                         exp(tau*ZD)
943                         where ZD is the zenith-distance
944            insitu:      if False a new scantable is returned.
945                         Otherwise, the scaling is done in-situ
946                         The default is taken from .asaprc (False)
947        """
948        if insitu is None: insitu = rcParams['insitu']
949        self._math._setinsitu(insitu)
950        varlist = vars()
951        s = scantable(self._math._opacity(self, tau))
952        s._add_history("opacity", varlist)
953        print_log()
954        if insitu: self._assign(s)
955        else: return s
956
957    def bin(self, width=5, insitu=None):
958        """
959        Return a scan where all spectra have been binned up.
960            width:       The bin width (default=5) in pixels
961            insitu:      if False a new scantable is returned.
962                         Otherwise, the scaling is done in-situ
963                         The default is taken from .asaprc (False)
964        """
965        if insitu is None: insitu = rcParams['insitu']
966        self._math._setinsitu(insitu)
967        varlist = vars()
968        s = scantable(self._math._bin(self, width))
969        s._add_history("bin",varlist)
970        print_log()
971        if insitu: self._assign(s)
972        else: return s
973
974
975    def resample(self, width=5, method='cubic', insitu=None):
976        """
977        Return a scan where all spectra have been binned up
978            width:       The bin width (default=5) in pixels
979            method:      Interpolation method when correcting from a table.
980                         Values are  "nearest", "linear", "cubic" (default)
981                         and "spline"
982            insitu:      if False a new scantable is returned.
983                         Otherwise, the scaling is done in-situ
984                         The default is taken from .asaprc (False)
985        """
986        if insitu is None: insitu = rcParams['insitu']
987        self._math._setinsitu(insitu)
988        varlist = vars()
989        s = scantable(self._math._resample(self, method, width))
990        s._add_history("resample",varlist)
991        print_log()
992        if insitu: self._assign(s)
993        else: return s
994
995
996    def average_pol(self, mask=None, weight='none'):
997        """
998        Average the Polarisations together.
999        Parameters:
1000            mask:        An optional mask defining the region, where the
1001                         averaging will be applied. The output will have all
1002                         specified points masked.
1003            weight:      Weighting scheme. 'none' (default), 'var' (1/var(spec)
1004                         weighted), or 'tsys' (1/Tsys**2 weighted)
1005        """
1006        varlist = vars()
1007        if mask is None:
1008            mask = ()
1009        s = scantable(self._math._averagepol(self, mask, weight.upper()))
1010        s._add_history("average_pol",varlist)
1011        print_log()
1012        return s
1013
1014    def convert_pol(self, poltype=None):
1015        """
1016        Convert the data to a different polarisation type.
1017        Parameters:
1018            poltype:    The new polarisation type. Valid types are:
1019                        "linear", "stokes" and "circular"
1020        """
1021        varlist = vars()
1022        try:
1023            s = scantable(self._math._convertpol(self, poltype))
1024        except RuntimeError,msg:
1025            if rcParams['verbose']:
1026              print msg
1027              return
1028            else:
1029                raise
1030        s._add_history("convert_pol",varlist)
1031        print_log()
1032        return s
1033
1034    def smooth(self, kernel="hanning", width=5.0, insitu=None):
1035        """
1036        Smooth the spectrum by the specified kernel (conserving flux).
1037        Parameters:
1038            scan:       The input scan
1039            kernel:     The type of smoothing kernel. Select from
1040                        'hanning' (default), 'gaussian' and 'boxcar'.
1041                        The first three characters are sufficient.
1042            width:      The width of the kernel in pixels. For hanning this is
1043                        ignored otherwise it defauls to 5 pixels.
1044                        For 'gaussian' it is the Full Width Half
1045                        Maximum. For 'boxcar' it is the full width.
1046            insitu:     if False a new scantable is returned.
1047                        Otherwise, the scaling is done in-situ
1048                        The default is taken from .asaprc (False)
1049        Example:
1050             none
1051        """
1052        if insitu is None: insitu = rcParams['insitu']
1053        self._math._setinsitu(insitu)
1054        varlist = vars()
1055        s = scantable(self._math._smooth(self,kernel.lower(),width))
1056        s._add_history("smooth", varlist)
1057        print_log()
1058        if insitu: self._assign(s)
1059        else: return s
1060
1061
1062    def poly_baseline(self, mask=None, order=0, plot=False, insitu=None):
1063        """
1064        Return a scan which has been baselined (all rows) by a polynomial.
1065        Parameters:
1066            scan:       a scantable
1067            mask:       an optional mask
1068            order:      the order of the polynomial (default is 0)
1069            plot:       plot the fit and the residual. In this each
1070                        indivual fit has to be approved, by typing 'y'
1071                        or 'n'
1072            insitu:     if False a new scantable is returned.
1073                        Otherwise, the scaling is done in-situ
1074                        The default is taken from .asaprc (False)
1075        Example:
1076            # return a scan baselined by a third order polynomial,
1077            # not using a mask
1078            bscan = scan.poly_baseline(order=3)
1079        """
1080        if insitu is None: insitu = rcParams['insitu']
1081        varlist = vars()
1082        if mask is None:
1083            from numarray import ones
1084            mask = list(ones(self.nchan(-1)))
1085        from asap.asapfitter import fitter
1086        f = fitter()
1087        f.set_scan(self, mask)
1088        f.set_function(poly=order)
1089        s = f.auto_fit(insitu, plot=plot)
1090        s._add_history("poly_baseline", varlist)
1091        print_log()
1092        if insitu: self._assign(s)
1093        else: return s
1094
1095    def auto_poly_baseline(self, mask=[], edge=(0,0), order=0,
1096                           threshold=3, plot=False, insitu=None):
1097        """
1098        Return a scan which has been baselined (all rows) by a polynomial.
1099        Spectral lines are detected first using linefinder and masked out
1100        to avoid them affecting the baseline solution.
1101
1102        Parameters:
1103            mask:       an optional mask retreived from scantable
1104            edge:       an optional number of channel to drop at
1105                        the edge of spectrum. If only one value is
1106                        specified, the same number will be dropped from
1107                        both sides of the spectrum. Default is to keep
1108                        all channels. Nested tuples represent individual
1109                        edge selection for different IFs (a number of spectral
1110                        channels can be different)
1111            order:      the order of the polynomial (default is 0)
1112            threshold:  the threshold used by line finder. It is better to
1113                        keep it large as only strong lines affect the
1114                        baseline solution.
1115            plot:       plot the fit and the residual. In this each
1116                        indivual fit has to be approved, by typing 'y'
1117                        or 'n'
1118            insitu:     if False a new scantable is returned.
1119                        Otherwise, the scaling is done in-situ
1120                        The default is taken from .asaprc (False)
1121
1122        Example:
1123            scan2=scan.auto_poly_baseline(order=7)
1124        """
1125        if insitu is None: insitu = rcParams['insitu']
1126        varlist = vars()
1127        from asap.asapfitter import fitter
1128        from asap.asaplinefind import linefinder
1129        from asap import _is_sequence_or_number as _is_valid
1130
1131        # check whether edge is set up for each IF individually
1132        individualEdge = False;
1133        if len(edge)>1:
1134           if isinstance(edge[0],list) or isinstance(edge[0],tuple):
1135               individualEdge = True;
1136
1137        if not _is_valid(edge, int) and not individualEdge:
1138            raise ValueError, "Parameter 'edge' has to be an integer or a \
1139            pair of integers specified as a tuple. Nested tuples are allowed \
1140            to make individual selection for different IFs."
1141
1142        curedge = (0,0)
1143        if individualEdge:
1144           for edge_par in edge:
1145               if not _is_valid(edge,int):
1146                  raise ValueError, "Each element of the 'edge' tuple has \
1147                  to be a pair of integers or an integer."
1148        else:
1149           curedge = edge;
1150
1151        # setup fitter
1152        f = fitter()
1153        f.set_function(poly=order)
1154
1155        # setup line finder
1156        fl=linefinder()
1157        fl.set_options(threshold=threshold)
1158
1159        if not insitu:
1160            workscan=self.copy()
1161        else:
1162            workscan=self
1163
1164        fl.set_scan(workscan)
1165
1166        rows=range(workscan.nrow())
1167        from asap import asaplog
1168        asaplog.push("Processing:")
1169        for r in rows:
1170            msg = " Scan[%d] Beam[%d] IF[%d] Pol[%d] Cycle[%d]" %        (workscan.getscan(r),workscan.getbeam(r),workscan.getif(r),workscan.getpol(r), workscan.getcycle(r))
1171            asaplog.push(msg, False)
1172
1173            # figure out edge parameter
1174            if individualEdge:
1175               if len(edge)>=workscan.getif(r):
1176                  raise RuntimeError, "Number of edge elements appear to be less than the number of IFs"
1177                  curedge = edge[workscan.getif(r)]
1178
1179            # setup line finder
1180            fl.find_lines(r,mask,curedge)
1181            f.set_scan(workscan, fl.get_mask())
1182            f.x = workscan._getabcissa(r)
1183            f.y = workscan._getspectrum(r)
1184            f.data = None
1185            f.fit()
1186            x = f.get_parameters()
1187            if plot:
1188                f.plot(residual=True)
1189                x = raw_input("Accept fit ( [y]/n ): ")
1190                if x.upper() == 'N':
1191                    continue
1192            workscan._setspectrum(f.fitter.getresidual(), r)
1193        if plot:
1194            f._p.unmap()
1195            f._p = None
1196        workscan._add_history("auto_poly_baseline", varlist)
1197        if insitu:
1198            self._assign(workscan)
1199        else:
1200            return workscan
1201
1202    def rotate_linpolphase(self, angle):
1203        """
1204        Rotate the phase of the complex polarization O=Q+iU correlation.
1205        This is always done in situ in the raw data.  So if you call this
1206        function more than once then each call rotates the phase further.
1207        Parameters:
1208            angle:   The angle (degrees) to rotate (add) by.
1209        Examples:
1210            scan.rotate_linpolphase(2.3)
1211        """
1212        varlist = vars()
1213        self._math._rotate_linpolphase(self, angle)
1214        self._add_history("rotate_linpolphase", varlist)
1215        print_log()
1216        return
1217
1218
1219    def rotate_xyphase(self, angle):
1220        """
1221        Rotate the phase of the XY correlation.  This is always done in situ
1222        in the data.  So if you call this function more than once
1223        then each call rotates the phase further.
1224        Parameters:
1225            angle:   The angle (degrees) to rotate (add) by.
1226        Examples:
1227            scan.rotate_xyphase(2.3)
1228        """
1229        varlist = vars()
1230        self._math._rotate_xyphase(self, angle)
1231        self._add_history("rotate_xyphase", varlist)
1232        print_log()
1233        return
1234
1235    def swap_linears(self):
1236        """
1237        Swap the linear polarisations XX and YY
1238        """
1239        varlist = vars()
1240        self._math._swap_linears(self)
1241        self._add_history("swap_linears", varlist)
1242        print_log()
1243        return
1244
1245    def invert_phase(self):
1246        """
1247        Invert the phase of the complex polarisation
1248        """
1249        varlist = vars()
1250        self._math._invert_phase(self)
1251        self._add_history("invert_phase", varlist)
1252        print_log()
1253        return
1254
1255    def add(self, offset, insitu=None):
1256        """
1257        Return a scan where all spectra have the offset added
1258        Parameters:
1259            offset:      the offset
1260            insitu:      if False a new scantable is returned.
1261                         Otherwise, the scaling is done in-situ
1262                         The default is taken from .asaprc (False)
1263        """
1264        if insitu is None: insitu = rcParams['insitu']
1265        self._math._setinsitu(insitu)
1266        varlist = vars()
1267        s = scantable(self._math._unaryop(self, offset, "ADD", False))
1268        s._add_history("add",varlist)
1269        print_log()
1270        if insitu:
1271            self._assign(s)
1272        else:
1273            return s
1274
1275    def scale(self, factor, tsys=True, insitu=None,):
1276        """
1277        Return a scan where all spectra are scaled by the give 'factor'
1278        Parameters:
1279            factor:      the scaling factor
1280            insitu:      if False a new scantable is returned.
1281                         Otherwise, the scaling is done in-situ
1282                         The default is taken from .asaprc (False)
1283            tsys:        if True (default) then apply the operation to Tsys
1284                         as well as the data
1285        """
1286        if insitu is None: insitu = rcParams['insitu']
1287        self._math._setinsitu(insitu)
1288        varlist = vars()
1289        s = scantable(self._math._unaryop(self, factor, "MUL", tsys))
1290        s._add_history("scale",varlist)
1291        print_log()
1292        if insitu:
1293            self._assign(s)
1294        else:
1295            return s
1296
1297    def auto_quotient(self, mode='time', preserve=True):
1298        """
1299        This function allows to build quotients automatically.
1300        It assumes the observation to have the same numer of
1301        "ons" and "offs"
1302        It will support "closest off in time" in the future
1303        Parameters:
1304            mode:           the on/off detection mode; 'suffix' (default)
1305                            'suffix' identifies 'off' scans by the
1306                            trailing '_R' (Mopra/Parkes) or
1307                            '_e'/'_w' (Tid)
1308            preserve:       you can preserve (default) the continuum or
1309                            remove it.  The equations used are
1310                            preserve: Output = Toff * (on/off) - Toff
1311                            remove:   Output = Toff * (on/off) - Ton
1312        """
1313        modes = ["time"]
1314        if not mode in modes:
1315            msg = "please provide valid mode. Valid modes are %s" % (modes)
1316            raise ValueError(msg)
1317        varlist = vars()
1318        s = scantable(self._math._auto_quotient(self, mode, preserve))
1319        s._add_history("auto_quotient",varlist)
1320        print_log()
1321        return s
1322
1323
1324
1325
1326    def freq_switch(self, insitu=None):
1327        """
1328        Apply frequency switching to the data.
1329        Parameters:
1330            insitu:      if False a new scantable is returned.
1331                         Otherwise, the swictching is done in-situ
1332                         The default is taken from .asaprc (False)
1333        Example:
1334            none
1335        """
1336        if insitu is None: insitu = rcParams['insitu']
1337        self._math._setinsitu(insitu)
1338        varlist = vars()
1339        s = scantable(self._math._freqswitch(self))
1340        s._add_history("freq_switch",varlist)
1341        print_log()
1342        if insitu: self._assign(s)
1343        else: return s
1344
1345    def recalc_azel(self):
1346        """
1347        Recalculate the azimuth and elevation for each position.
1348        Parameters:
1349            none
1350        Example:
1351        """
1352        varlist = vars()
1353        self._recalcazel()
1354        self._add_history("recalc_azel", varlist)
1355        print_log()
1356        return
1357
1358    def __add__(self, other):
1359        varlist = vars()
1360        s = None
1361        if isinstance(other, scantable):
1362            print "scantable + scantable NYI"
1363            return
1364        elif isinstance(other, float):
1365            s = scantable(self._math._unaryop(self, other, "ADD", False))
1366        else:
1367            raise TypeError("Other input is not a scantable or float value")
1368        s._add_history("operator +", varlist)
1369        print_log()
1370        return s
1371
1372    def __sub__(self, other):
1373        """
1374        implicit on all axes and on Tsys
1375        """
1376        varlist = vars()
1377        s = None
1378        if isinstance(other, scantable):
1379            print "scantable - scantable NYI"
1380            return
1381        elif isinstance(other, float):
1382            s = scantable(self._math._unaryop(self, other, "SUB", False))
1383        else:
1384            raise TypeError("Other input is not a scantable or float value")
1385        s._add_history("operator -", varlist)
1386        print_log()
1387        return s
1388
1389    def __mul__(self, other):
1390        """
1391        implicit on all axes and on Tsys
1392        """
1393        varlist = vars()
1394        s = None
1395        if isinstance(other, scantable):
1396            print "scantable * scantable NYI"
1397            return
1398        elif isinstance(other, float):
1399            s = scantable(self._math._unaryop(self, other, "MUL", False))
1400        else:
1401            raise TypeError("Other input is not a scantable or float value")
1402        s._add_history("operator *", varlist)
1403        print_log()
1404        return s
1405
1406
1407    def __div__(self, other):
1408        """
1409        implicit on all axes and on Tsys
1410        """
1411        varlist = vars()
1412        s = None
1413        if isinstance(other, scantable):
1414            print "scantable / scantable NYI"
1415            return
1416        elif isinstance(other, float):
1417            if other == 0.0:
1418                raise ZeroDivisionError("Dividing by zero is not recommended")
1419            s = scantable(self._math._unaryop(self, other, "DIV", False))
1420        else:
1421            raise TypeError("Other input is not a scantable or float value")
1422        s._add_history("operator /", varlist)
1423        print_log()
1424        return s
1425
1426    def get_fit(self, row=0):
1427        """
1428        Print or return the stored fits for a row in the scantable
1429        Parameters:
1430            row:    the row which the fit has been applied to.
1431        """
1432        if row > self.nrow():
1433            return
1434        from asap.asapfit import asapfit
1435        fit = asapfit(self._getfit(row))
1436        if rcParams['verbose']:
1437            print fit
1438            return
1439        else:
1440            return fit.as_dict()
1441
1442    def _add_history(self, funcname, parameters):
1443        # create date
1444        sep = "##"
1445        from datetime import datetime
1446        dstr = datetime.now().strftime('%Y/%m/%d %H:%M:%S')
1447        hist = dstr+sep
1448        hist += funcname+sep#cdate+sep
1449        if parameters.has_key('self'): del parameters['self']
1450        for k,v in parameters.iteritems():
1451            if type(v) is dict:
1452                for k2,v2 in v.iteritems():
1453                    hist += k2
1454                    hist += "="
1455                    if isinstance(v2,scantable):
1456                        hist += 'scantable'
1457                    elif k2 == 'mask':
1458                        if isinstance(v2,list) or isinstance(v2,tuple):
1459                            hist += str(self._zip_mask(v2))
1460                        else:
1461                            hist += str(v2)
1462                    else:
1463                        hist += str(v2)
1464            else:
1465                hist += k
1466                hist += "="
1467                if isinstance(v,scantable):
1468                    hist += 'scantable'
1469                elif k == 'mask':
1470                    if isinstance(v,list) or isinstance(v,tuple):
1471                        hist += str(self._zip_mask(v))
1472                    else:
1473                        hist += str(v)
1474                else:
1475                    hist += str(v)
1476            hist += sep
1477        hist = hist[:-2] # remove trailing '##'
1478        self._addhistory(hist)
1479
1480
1481    def _zip_mask(self, mask):
1482        mask = list(mask)
1483        i = 0
1484        segments = []
1485        while mask[i:].count(1):
1486            i += mask[i:].index(1)
1487            if mask[i:].count(0):
1488                j = i + mask[i:].index(0)
1489            else:
1490                j = len(mask)
1491            segments.append([i,j])
1492            i = j
1493        return segments
1494
1495    def _get_ordinate_label(self):
1496        fu = "("+self.get_fluxunit()+")"
1497        import re
1498        lbl = "Intensity"
1499        if re.match(".K.",fu):
1500            lbl = "Brightness Temperature "+ fu
1501        elif re.match(".Jy.",fu):
1502            lbl = "Flux density "+ fu
1503        return lbl
1504
1505    def _check_ifs(self):
1506        nchans = [self.nchan(i) for i in range(self.nif(-1))]
1507        nchans = filter(lambda t: t > 0, nchans)
1508        return (sum(nchans)/len(nchans) == nchans[0])
1509
1510    def _fill(self, names, unit, average):
1511        import os
1512        varlist = vars()
1513        from asap._asap import stfiller
1514        first = True
1515        fullnames = []
1516        for name in names:
1517            name = os.path.expandvars(name)
1518            name = os.path.expanduser(name)
1519            if not os.path.exists(name):
1520                msg = "File '%s' does not exists" % (name)
1521                if rcParams['verbose']:
1522                    asaplog.push(msg)
1523                    print asaplog.pop().strip()
1524                    return
1525                raise IOError(msg)
1526            fullnames.append(name)
1527        if average:
1528            asaplog.push('Auto averaging integrations')
1529        stype = int(rcParams['scantable.storage'].lower() == 'disk')
1530        for name in fullnames:
1531            tbl = Scantable(stype)
1532            r = stfiller(tbl)
1533            msg = "Importing %s..." % (name)
1534            asaplog.push(msg,False)
1535            print_log()
1536            r._open(name,-1,-1)
1537            r._read()
1538            #tbl = r._getdata()
1539            if average:
1540                tbl = self._math._average((tbl,),(),'NONE','SCAN')
1541                #tbl = tbl2
1542            if not first:
1543                tbl = self._math._merge([self, tbl])
1544                #tbl = tbl2
1545            Scantable.__init__(self, tbl)
1546            r._close()
1547            del r,tbl
1548            first = False
1549        if unit is not None:
1550            self.set_fluxunit(unit)
1551        self.set_freqframe(rcParams['scantable.freqframe'])
1552        #self._add_history("scantable", varlist)
1553
Note: See TracBrowser for help on using the repository browser.