source: trunk/python/scantable.py@ 124

Last change on this file since 124 was 124, checked in by mar637, 20 years ago

added subplotting to plot(). Fixed verbose.

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