source: trunk/python/scantable.py@ 118

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

Added SDFITS writing.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 13.8 KB
RevLine 
[102]1from asap._asap import sdtable
2from numarray import ones
3import sys
4
5class scantable(sdtable):
6 """
7 The ASAP container for scans
8 """
[113]9
[102]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 """
[113]18 self._vb = True
19 self._p = None
[102]20 sdtable.__init__(self, filename)
21
[116]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
[113]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
[102]54 def copy(self):
55 """
56 Return a copy of this scantable.
57 Parameters:
[113]58 none
[102]59 Example:
60 copiedscan = scan.copy()
61 """
[113]62 sd = scantable(sdtable._copy(self))
63 return sd
64
[102]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:
[113]72 scan.get_scan('323p459')
[102]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:
[113]79 s = sdtable._getsource(self,scanid)
[102]80 return scantable(s)
81 elif type(scanid) is int:
[113]82 s = sdtable._getscan(self,scanid)
[102]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):
[113]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 """
[102]129 i = self.getbeam()
130 j = self.getif()
131 k = self.getpol()
[113]132 if self._vb:
133 out = 'Beam=%d IF=%d Pol=%d '% (i,j,k)
134 print out
[102]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:
[113]149 scan.set_unit('channel')
[102]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)
[113]168 if self._vb:
169 print out
[102]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)
[113]178 if self._vb:
179 print out
[102]180 return rmsval
181
182 def get_tsys(self, all=True):
[113]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 """
[102]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)
[113]202 ts = self._gettsys()
[102]203 tmp.append(ts)
204 out += 'TSys: Beam[%d], IF[%d], Pol[%d] = %3.3f\n' % (i,j,k,ts)
[113]205 if self._vb:
206 print out
[102]207 return tmp
208 else:
209 i = self.getbeam()
210 j = self.getif()
211 k = self.getpol()
[113]212 ts = self._gettsys()
[102]213 out = 'TSys: Beam[%d], IF[%d], Pol[%d] = %3.3f' % (i,j,k,ts)
[113]214 if self._vb:
215 print out
[102]216 return ts
[113]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
[102]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'
[113]237 one of '*Hz','km/s','channel', ''
[102]238 """
[113]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)
[102]261 else:
[113]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
[102]275
[113]276 def get_abscissa(self, rowno=0):
[102]277 """
[113]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 """
[102]291 Compute and return a mask based on [min,max] windows.
[113]292 The specified windows are to be EXCLUDED, when the mask is
293 applied.
[102]294 Parameters:
295 [min,max],[min2,max2],...
296 Pairs of start/end points specifying the regions
297 to be masked
[113]298 invert: return an inverted mask, i.e. the regions
299 specified are not masked (INCLUDED)
[102]300 Example:
[113]301 scan.set_unit('channel')
302
303 a)
[102]304 msk = scan.set_mask([400,500],[800,900])
[113]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
[102]313 """
[113]314 u = self._getcoordinfo()[0]
315 if self._vb:
316 if u == "": u = "channel"
317 print "The current mask window unit is", u
[102]318 n = self.nchan()
[113]319 data = self.getabscissa()
[102]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):
[113]326 if data[i] >= window[0] and data[i] < window[1]:
[102]327 msk[i] = 0
[113]328 if kwargs.has_key('invert'):
329 if kwargs.get('invert'):
330 from numarray import logical_not
331 msk = logical_not(msk)
[102]332 return msk
[113]333
334 def set_restfreqs(self, freqs, unit='Hz'):
[102]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:
[113]341 scan.set_restfreqs([1000000000.0])
[102]342 """
[113]343 if type(freqs) is float or int:
344 freqs = (freqs)
345 sdtable._setrestfreqs(self,freqs, unit)
[102]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
[113]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 validyax = ['spectrum','tsys']
380 if not self._p:
381 from asap.asaplot import ASAPlot
382 self._p = ASAPlot()
383# print "Plotting not enabled"
384# return
385 npan = 1
386 x = None
387 if what == 'tsys':
388 n = self.nrow()
389 if n < 2:
390 print "Only one integration. Can't plot."
391 return
392 if panel == 'Time':
393 npan = self.nrow()
394 self._p.hold()
395 self._p.clear()
396 xlab,ylab,tlab = None,None,None
397 vb = self._verbose
398 self._verbose(False)
399 sel = self.get_selection()
400 for i in range(npan):
401 for j in range(validcol[col]):
402 x = None
403 y = None
404 m = None
405 tlab = self._getsourcename(i)
406 if col == 'Beam':
407 self.setbeam(j)
408 elif col == 'IF':
409 self.setif(j)
410 elif col == 'Pol':
411 self.setpol(j)
412 if what == 'tsys':
413 x = range(self.nrow())
414 xlab = 'Time [pixel]'
415 m = list(ones(len(x)))
416 y = []
417 ylab = r'$T_{sys}$'
418 for k in range(len(x)):
419 y.append(self._gettsys(k))
420 else:
421 x,xlab = self.get_abscissa(i)
422 y = self.getspectrum(i)
423 ylab = r'Flux'
424 m = self.getmask(i)
425 llab = col+' '+str(j)
426 self._p.set_line(label=llab)
427 self._p.plot(x,y,m)
428 self._p.set_axes('xlabel',xlab)
429 self._p.set_axes('ylabel',ylab)
430 self._p.set_axes('title',tlab)
431 self._p.release()
432 self.set_selection(sel[0],sel[1],sel[2])
433 self._verbose(vb)
434 return
Note: See TracBrowser for help on using the repository browser.