source: trunk/python/scantable.py@ 1004

Last change on this file since 1004 was 1003, checked in by mar637, 19 years ago

added column_names()

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