source: trunk/python/scantable.py@ 1142

Last change on this file since 1142 was 1141, checked in by mar637, 18 years ago

added stub for mx_quotient

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