source: trunk/python/scantable.py@ 1133

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

fixes for pylint reported violations

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