source: trunk/python/scantable.py @ 158

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

Correct spelling 'abscissa' -> 'abcissa'

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 14.8 KB
Line 
1from asap._asap import sdtable
2from numarray import ones
3import sys
4
5class scantable(sdtable):
6    """
7        The ASAP container for scans
8    """
9   
10    def __init__(self, filename):
11        """
12        Create a scantable from a saved one or make a reference
13        Parameters:
14            filename:    the name of an asap table on disk, or
15                         [advanced] a refernce to an existing
16                         scantable
17        """
18        self._vb = True
19        self._p = None
20        sdtable.__init__(self, filename)
21
22    def save(self, name, format='ASAP'):
23        """
24        Store the scantable on disk. This can be a asap file or SDFITS/MS2.
25        Parameters:
26            name:        the name of the outputfile
27            format:      an optional file format. Default is ASAP.
28                         Alllowed are 'ASAP', 'SDFITS' and 'MS2'
29        Example:
30            scan.save('myscan.asap')
31            scan.save('myscan.sdfits','SDFITS')
32        """
33        if format == 'ASAP':
34            self._save(name)
35        else:
36            from asap._asap import sdwriter as _sw
37            w = _sw()
38            if format == 'SDFITS':
39                w.write(self, name)
40        return
41
42    def _verbose(self, *args):
43        """
44        Set the verbose level True or False, to indicate if output
45        should be printed as well as returned.
46        """
47        if len(args) == 0:
48            return self._vb
49        elif type(args[0]) is bool:
50            self._vb = args[0]
51            return
52
53    def copy(self):
54        """
55        Return a copy of this scantable.
56        Parameters:
57            none
58        Example:
59            copiedscan = scan.copy()
60        """
61        sd = scantable(sdtable._copy(self))
62        return sd
63
64    def get_scan(self, scanid=None):
65        """
66        Return a specific scan (by scanno) or collection of scans (by
67        source name) in a new scantable.
68        Parameters:
69            scanid:    a scanno or a source name
70        Example:
71            scan.get_scan('323p459')
72            # gets all scans containing the source '323p459'
73        """
74        if scanid is None:
75            print "Please specify a scan no or name to retrieve from the scantable"
76        try:
77            if type(scanid) is str:
78                s = sdtable._getsource(self,scanid)
79                return scantable(s)
80            elif type(scanid) is int:
81                s = sdtable._getscan(self,scanid)
82                return scantable(s)
83        except RuntimeError:
84            print "Couldn't find any match."
85
86    def __str__(self):
87        return sdtable.summary(self)
88
89    def summary(self,filename=None):
90        """
91        Print a summary of the contents of this scantable.
92        Parameters:
93            filename:    the name of a file to write the putput to
94                         Default - no file output
95        """
96        info = sdtable.summary(self)
97        if filename is not None:
98            data = open(filename, 'w')
99            data.write(info)
100            data.close()
101        print info
102
103    def set_selection(self, thebeam=0,theif=0,thepol=0):
104        """
105        Set the spectrum for individual operations.
106        Parameters:
107            thebeam,theif,thepol:    a number
108        Example:
109            scan.set_selection(0,0,1)
110            pol1sig = scan.stats(all=False) # returns std dev for beam=0
111                                         # if=0, pol=1
112        """
113        self.setbeam(thebeam)
114        self.setpol(thepol)
115        self.setif(theif)
116        return
117
118    def get_selection(self):
119        """
120        Return/print a the current 'cursor' into the Beam/IF/Pol cube.
121        Parameters:
122            none
123        Returns:
124            a list of values (currentBeam,currentIF,currentPol)
125        Example:
126            none
127        """
128        i = self.getbeam()
129        j = self.getif()
130        k = self.getpol()
131        if self._vb:
132            out = 'Beam=%d IF=%d Pol=%d '% (i,j,k)
133            print out
134        return i,j,k
135
136    def stats(self, stat='stddev', mask=None, all=True):
137        """
138        Determine the specified statistic of the current beam/if/pol
139        Takes a 'mask' as an optional parameter to specify which
140        channels should be excluded.
141        Parameters:
142            stat:    'min', 'max', 'sumsq', 'sum', 'mean'
143                     'var', 'stddev', 'avdev', 'rms', 'median'
144            mask:    an optional mask specifying where the statistic
145                     should be determined.
146            all:     optional flag to show all (default) or a selected
147                     spectrum of Beam/IF/Pol
148
149        Example:
150            scan.set_unit('channel')
151            msk = scan.create_mask([100,200],[500,600])
152            scan.stats(stat='mean', mask=m)
153        """
154        from asap._asap import stats as _stats
155        if mask == None:
156            mask = ones(self.nchan())
157        if all:
158            out = ''
159            tmp = []
160            for i in range(self.nbeam()):
161                self.setbeam(i)
162                for j in range(self.nif()):
163                    self.setif(j)
164                    for k in range(self.npol()):
165                        self.setpol(k)
166                        statVal = _stats(self,mask,stat)
167                        tmp.append(statVal)
168#                        out += 'Beam[%d], IF[%d], Pol[%d] = %3.3f\n' % (i,j,k,statVal)
169#            if self._vb:
170#                print out
171            return tmp
172
173        else:
174            i = self.getbeam()
175            j = self.getif()
176            k = self.getpol()
177            statVal = _stats(self,mask,stat)
178#            out = 'Beam[%d], IF[%d], Pol[%d] = %3.3f' % (i,j,k,statVal)
179#            if self._vb:
180#                print out
181            return statVal
182
183    def stddev(self,mask=None, all=True):
184        """
185        Determine the standard deviation of the current beam/if/pol
186        Takes a 'mask' as an optional parameter to specify which
187        channels should be excluded.
188        Parameters:
189            mask:    an optional mask specifying where the standard
190                     deviation should be determined.
191            all:     optional flag to show all or a selected
192                     spectrum of Beam/IF/Pol
193
194        Example:
195            scan.set_unit('channel')
196            msk = scan.create_mask([100,200],[500,600])
197            scan.stddev(mask=m)
198        """
199        return self.stats(stat='stddev',mask=mask, all=all);
200
201    def get_tsys(self, all=True):
202        """
203        Return the System temperatures.
204        Parameters:
205            all:    optional parameter to get the Tsys values for all
206                    Beams/IFs/Pols (default) or just the one selected
207                    with scantable.set_selection()
208                    [True or False]
209        Returns:
210            a list of Tsys values.
211        """
212        if all:
213            tmp = []
214            out = ''
215            for i in range(self.nbeam()):
216                self.setbeam(i)
217                for j in range(self.nif()):
218                    self.setif(j)
219                    for k in range(self.npol()):
220                        self.setpol(k)
221                        ts = self._gettsys()
222                        tmp.append(ts)
223#                        out += 'TSys: Beam[%d], IF[%d], Pol[%d] = %3.3f\n' % (i,j,k,ts)
224#            if self._vb:
225#                print out
226            return tmp
227        else:
228            i = self.getbeam()
229            j = self.getif()
230            k = self.getpol()
231            ts = self._gettsys()
232#            out = 'TSys: Beam[%d], IF[%d], Pol[%d] = %3.3f' % (i,j,k,ts)
233#            if self._vb:
234#                print out
235            return ts
236       
237    def get_time(self):
238        """
239        Get a list of time stamps for the observations.
240        Return a string for each intergration in the scantable.
241        Parameters:
242            none
243        Example:
244            none
245        """
246        out = []
247        for i in range(self.nrow()):
248            out.append(self._gettime(i))
249        return out
250
251    def set_unit(self, unit='channel'):
252        """
253        Set the unit for all following operations on this scantable
254        Parameters:
255            unit:    optional unit, default is 'channel'
256                     one of '*Hz','km/s','channel', ''
257        """
258
259        if unit in ['','pixel', 'channel']:
260            unit = ''
261        inf = list(self._getcoordinfo())
262        inf[0] = unit
263        self._setcoordinfo(inf)
264        if self._p: self.plot()
265
266    def set_freqframe(self, frame='LSRK'):
267        """
268        Set the frame type of the Spectral Axis.
269        Parameters:
270            frame:   an optional frame type, default 'LSRK'.
271        Examples:
272            scan.set_freqframe('BARY')
273        """
274        valid = ['REST','TOPO','LSRD','LSRK','BARY', \
275                   'GEO','GALACTO','LGROUP','CMB']
276        if frame in valid:
277            inf = list(self._getcoordinfo())
278            inf[1] = frame
279            self._setcoordinfo(inf)
280        else:
281            print "Please specify a valid freq type. Valid types are:\n",valid
282           
283    def get_unit(self):
284        """
285        Get the default unit set in this scantable
286        Parameters:
287        Returns:
288            A unit string
289        """
290        inf = self._getcoordinfo()
291        unit = inf[0]
292        if unit == '': unit = 'channel'
293        return unit
294
295    def get_abcissa(self, rowno=0):
296        """
297        Get the abcissa in the current coordinate setup for the currently
298        selected Beam/IF/Pol
299        Parameters:
300            none
301        Returns:
302            The abcissa values and it's format string.
303        """
304        abc = self.getabcissa(rowno)
305        lbl = self.getabcissalabel(rowno)
306        return abc, lbl
307
308    def create_mask(self, *args, **kwargs):
309        """
310        Compute and return a mask based on [min,max] windows.
311        The specified windows are to be EXCLUDED, when the mask is
312        applied.
313        Parameters:
314            [min,max],[min2,max2],...
315                Pairs of start/end points specifying the regions
316                to be masked
317            invert:     return an inverted mask, i.e. the regions
318                        specified are not masked (INCLUDED)
319        Example:
320            scan.set_unit('channel')
321
322            a)
323            msk = scan.set_mask([400,500],[800,900])
324            # masks the regions between 400 and 500
325            # and 800 and 900 in the unit 'channel'
326
327            b)
328            msk = scan.set_mask([400,500],[800,900], invert=True)
329            # masks the regions outside 400 and 500
330            # and 800 and 900 in the unit 'channel'
331           
332        """
333        u = self._getcoordinfo()[0]
334        if self._vb:
335            if u == "": u = "channel"
336            print "The current mask window unit is", u
337        n = self.nchan()
338        data = self.getabcissa()
339        msk = ones(n)
340        for  window in args:
341            if (len(window) != 2 or window[0] > window[1] ):
342                print "A window needs to be defined as [min,max]"
343                return
344            for i in range(n):
345                if data[i] >= window[0] and data[i] < window[1]:
346                    msk[i] = 0
347        if kwargs.has_key('invert'):
348            if kwargs.get('invert'):
349                from numarray import logical_not
350                msk = logical_not(msk)
351        return msk
352   
353    def set_restfreqs(self, freqs, unit='Hz'):
354        """
355        Set the restfrequency(s) for this scantable.
356        Parameters:
357            freqs:    one or more frequencies
358            unit:     optional 'unit', default 'Hz'
359        Example:
360            scan.set_restfreqs([1000000000.0])
361        """
362        if type(freqs) is float or int:
363            freqs = (freqs)
364        sdtable._setrestfreqs(self,freqs, unit)
365        return
366
367    def flag_spectrum(self, thebeam, theif, thepol):
368        """
369        This flags a selected spectrum in the scan 'for good'.
370        USE WITH CARE - not reversible.
371        Use masks for non-permanent exclusion of channels.
372        Parameters:
373            thebeam,theif,thepol:    all have to be explicitly
374                                     specified
375        Example:
376            scan.flag_spectrum(0,0,1)
377            flags the spectrum for Beam=0, IF=0, Pol=1
378        """
379        if (thebeam < self.nbeam() and  theif < self.nif() and thepol < self.npol()):
380            stable.setbeam(thebeam)
381            stable.setif(theif)
382            stable.setpol(thepol)
383            stable._flag(self)
384        else:
385            print "Please specify a valid (Beam/IF/Pol)"
386        return
387
388    def plot(self, what='spectrum',col='Pol', panel=None):
389        """
390        Plot the spectra contained in the scan. Alternatively you can also
391        Plot Tsys vs Time
392        Parameters:
393            what:     a choice of 'spectrum' (default) or 'tsys'
394            col:      which out of Beams/IFs/Pols should be colour stacked
395            panel:    set up multiple panels, currently not working.
396        """
397        validcol = {'Beam':self.nbeam(),'IF':self.nif(),'Pol':self.npol()}
398
399        validyax = ['spectrum','tsys']
400        if not self._p:
401            from asap.asaplot import ASAPlot
402            self._p = ASAPlot()
403#            print "Plotting not enabled"
404#            return
405        npan = 1
406        x = None
407        if what == 'tsys':
408            n = self.nrow()
409            if n < 2:
410                print "Only one integration. Can't plot."
411                return
412        self._p.hold()
413        self._p.clear()
414        if panel == 'Time':
415            npan = self.nrow()
416            self._p.set_panels(rows=npan)
417        xlab,ylab,tlab = None,None,None
418        vb = self._verbose()
419        self._verbose(False)
420        sel = self.get_selection()
421        for i in range(npan):
422            self._p.subplot(i)
423            for j in range(validcol[col]):
424                x = None
425                y = None
426                m = None
427                tlab = self._getsourcename(i)
428                import re
429                tlab = re.sub('_S','',tlab)
430                if col == 'Beam':
431                    self.setbeam(j)
432                elif col == 'IF':
433                    self.setif(j)
434                elif col == 'Pol':
435                    self.setpol(j)
436                if what == 'tsys':
437                    x = range(self.nrow())
438                    xlab = 'Time [pixel]'
439                    m = list(ones(len(x)))
440                    y = []
441                    ylab = r'$T_{sys}$'
442                    for k in range(len(x)):
443                        y.append(self._gettsys(k))
444                else:
445                    x,xlab = self.get_abcissa(i)
446                    y = self.getspectrum(i)
447                    ylab = r'Flux'
448                    m = self.getmask(i)
449                llab = col+' '+str(j)
450                self._p.set_line(label=llab)
451                self._p.plot(x,y,m)
452            self._p.set_axes('xlabel',xlab)
453            self._p.set_axes('ylabel',ylab)
454            self._p.set_axes('title',tlab)
455        self._p.release()
456        self.set_selection(sel[0],sel[1],sel[2])
457        self._verbose(vb)
458        return
Note: See TracBrowser for help on using the repository browser.