source: trunk/python/scantable.py@ 1117

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

added patch from Tak, so the constructor works with ms directories.

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