source: trunk/python/scantable.py@ 1072

Last change on this file since 1072 was 1070, checked in by mar637, 18 years ago

enhancement ticket #35. median scantable; also added get_column

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