source: trunk/python/scantable.py@ 718

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

more asaplog migration

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