source: trunk/python/scantable.py@ 756

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

removed old fitter._verbose call

  • 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 from asap import asaplog
261 out = "--------------------------------------------------\n"
262 out += " Cursor position\n"
263 out += "--------------------------------------------------\n"
264 out += 'Beam=%d IF=%d Pol=%d ' % (i,j,k)
265 asaplog.push(out)
266 print_log()
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.set_scan(self, mask)
1078 f.set_function(poly=order)
1079 sf = f.auto_fit(insitu)
1080 if insitu:
1081 self._add_history("poly_baseline", varlist)
1082 print_log()
1083 return
1084 else:
1085 sf._add_history("poly_baseline", varlist)
1086 print_log()
1087 return sf
1088
1089 def auto_poly_baseline(self, mask=None, edge=(0,0), order=0,
1090 threshold=3,insitu=None):
1091 """
1092 Return a scan which has been baselined (all rows) by a polynomial.
1093 Spectral lines are detected first using linefinder and masked out
1094 to avoid them affecting the baseline solution.
1095
1096 Parameters:
1097 mask: an optional mask retreived from scantable
1098 edge: an optional number of channel to drop at
1099 the edge of spectrum. If only one value is
1100 specified, the same number will be dropped from
1101 both sides of the spectrum. Default is to keep
1102 all channels
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
1120 if not _is_valid(edge, int):
1121
1122 raise RuntimeError, "Parameter 'edge' has to be an integer or a \
1123 pair of integers specified as a tuple"
1124
1125 # setup fitter
1126 f = fitter()
1127 f.set_function(poly=order)
1128
1129 # setup line finder
1130 fl=linefinder()
1131 fl.set_options(threshold=threshold)
1132
1133 if not insitu:
1134 workscan=self.copy()
1135 else:
1136 workscan=self
1137
1138 sel=workscan.get_cursor()
1139 rows=range(workscan.nrow())
1140 from asap import asaplog
1141 for i in range(workscan.nbeam()):
1142 workscan.setbeam(i)
1143 for j in range(workscan.nif()):
1144 workscan.setif(j)
1145 for k in range(workscan.npol()):
1146 workscan.setpol(k)
1147 asaplog.push("Processing:")
1148 msg = 'Beam[%d], IF[%d], Pol[%d]' % (i,j,k)
1149 asaplog.push(msg)
1150 for iRow in rows:
1151 fl.set_scan(workscan,mask,edge)
1152 fl.find_lines(iRow)
1153 f.set_scan(workscan, fl.get_mask())
1154 f.x=workscan._getabcissa(iRow)
1155 f.y=workscan._getspectrum(iRow)
1156 f.data=None
1157 f.fit()
1158 x=f.get_parameters()
1159 workscan._setspectrum(f.fitter.getresidual(),iRow)
1160 workscan.set_cursor(sel[0],sel[1],sel[2])
1161 if not insitu:
1162 return workscan
1163
1164 def rotate_linpolphase(self, angle, allaxes=None):
1165 """
1166 Rotate the phase of the complex polarization O=Q+iU correlation.
1167 This is always done in situ in the raw data. So if you call this
1168 function more than once then each call rotates the phase further.
1169 Parameters:
1170 angle: The angle (degrees) to rotate (add) by.
1171 allaxes: If True apply to all spectra. Otherwise
1172 apply only to the selected (beam/pol/if)spectra only.
1173 The default is taken from .asaprc (True if none)
1174 Examples:
1175 scan.rotate_linpolphase(2.3)
1176 """
1177 if allaxes is None: allaxes = rcParams['scantable.allaxes']
1178 varlist = vars()
1179 from asap._asap import _rotate_linpolphase as _rotate
1180 _rotate(self, angle, allaxes)
1181 self._add_history("rotate_linpolphase", varlist)
1182 print_log()
1183 return
1184
1185
1186 def rotate_xyphase(self, angle, allaxes=None):
1187 """
1188 Rotate the phase of the XY correlation. This is always done in situ
1189 in the data. So if you call this function more than once
1190 then each call rotates the phase further.
1191 Parameters:
1192 angle: The angle (degrees) to rotate (add) by.
1193 allaxes: If True apply to all spectra. Otherwise
1194 apply only to the selected (beam/pol/if)spectra only.
1195 The default is taken from .asaprc (True if none)
1196 Examples:
1197 scan.rotate_xyphase(2.3)
1198 """
1199 if allaxes is None: allaxes = rcParams['scantable.allaxes']
1200 varlist = vars()
1201 from asap._asap import _rotate_xyphase
1202 _rotate_xyphase(self, angle, allaxes)
1203 self._add_history("rotate_xyphase", varlist)
1204 print_log()
1205 return
1206
1207
1208 def add(self, offset, insitu=None, allaxes=None):
1209 """
1210 Return a scan where all spectra have the offset added
1211 Parameters:
1212 offset: the offset
1213 insitu: if False a new scantable is returned.
1214 Otherwise, the scaling is done in-situ
1215 The default is taken from .asaprc (False)
1216 allaxes: if True apply to all spectra. Otherwise
1217 apply only to the selected (beam/pol/if)spectra only
1218 The default is taken from .asaprc (True if none)
1219 """
1220 if allaxes is None: allaxes = rcParams['scantable.allaxes']
1221 if insitu is None: insitu = rcParams['insitu']
1222 varlist = vars()
1223 if not insitu:
1224 from asap._asap import add as _add
1225 s = scantable(_add(self, offset, allaxes))
1226 s._add_history("add",varlist)
1227 print_log()
1228 return s
1229 else:
1230 from asap._asap import add_insitu as _add
1231 _add(self, offset, allaxes)
1232 self._add_history("add",varlist)
1233 print_log()
1234 return
1235
1236 def scale(self, factor, insitu=None, allaxes=None, tsys=True):
1237 """
1238 Return a scan where all spectra are scaled by the give 'factor'
1239 Parameters:
1240 factor: the scaling factor
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 allaxes: if True apply to all spectra. Otherwise
1245 apply only to the selected (beam/pol/if)spectra only.
1246 The default is taken from .asaprc (True if none)
1247 tsys: if True (default) then apply the operation to Tsys
1248 as well as the data
1249 """
1250 if allaxes is None: allaxes = rcParams['scantable.allaxes']
1251 if insitu is None: insitu = rcParams['insitu']
1252 varlist = vars()
1253 if not insitu:
1254 from asap._asap import scale as _scale
1255 s = scantable(_scale(self, factor, allaxes, tsys))
1256 s._add_history("scale",varlist)
1257 print_log()
1258 return s
1259 else:
1260 from asap._asap import scale_insitu as _scale
1261 _scale(self, factor, allaxes, tsys)
1262 self._add_history("scale",varlist)
1263 print_log()
1264 return
1265
1266 def auto_quotient(self, mode='suffix', preserve=True):
1267 """
1268 This function allows to build quotients automatically.
1269 It assumes the observation to have the same numer of
1270 "ons" and "offs"
1271 It will support "closest off in time" in the future
1272 Parameters:
1273 mode: the on/off detection mode; 'suffix' (default)
1274 'suffix' identifies 'off' scans by the
1275 trailing '_R' (Mopra/Parkes) or
1276 '_e'/'_w' (Tid)
1277 preserve: you can preserve (default) the continuum or
1278 remove it. The equations used are
1279 preserve: Output = Toff * (on/off) - Toff
1280 remove: Output = Tref * (on/off) - Ton
1281 """
1282 modes = ["suffix","time"]
1283 if not mode in modes:
1284 print "please provide valid mode. Valid modes are %s" % (modes)
1285 return None
1286 from asap._asap import quotient as _quot
1287 if mode == "suffix":
1288 srcs = self.get_scan("*[^_ewR]")
1289 refs = self.get_scan("*[_ewR]")
1290 if isinstance(srcs,scantable) and isinstance(refs,scantable):
1291 ns,nr = srcs.nrow(),refs.nrow()
1292 if nr > ns:
1293 refs = refs.get_scan(range(ns))
1294 print_log()
1295 return scantable(_quot(srcs,refs, preserve))
1296 else:
1297 msg = "Couldn't find any on/off pairs"
1298 if rcParams['verbose']:
1299 print msg
1300 return
1301 else:
1302 raise RuntimeError()
1303 else:
1304 if rcParams['verbose']: print "not yet implemented"
1305 return None
1306
1307 def quotient(self, other, isreference=True, preserve=True):
1308 """
1309 Return the quotient of a 'source' (on) scan and a 'reference' (off)
1310 scan.
1311 The reference can have just one row, even if the signal has many.
1312 Otherwise they must have the same number of rows.
1313 The cursor of the output scan is set to 0
1314 Parameters:
1315 other: the 'other' scan
1316 isreference: if the 'other' scan is the reference (default)
1317 or source
1318 preserve: you can preserve (default) the continuum or
1319 remove it. The equations used are
1320 preserve: Output = Toff * (on/off) - Toff
1321 remove: Output = Tref * (on/off) - Ton
1322 Example:
1323 # src is a scantable for an 'on' scan, ref for an 'off' scantable
1324 q1 = src.quotient(ref)
1325 q2 = ref.quotient(src, isreference=False)
1326 # gives the same result
1327 """
1328 from asap._asap import quotient as _quot
1329 try:
1330 s = None
1331 if isreference:
1332 s = scantable(_quot(self, other, preserve))
1333 else:
1334 s = scantable(_quot(other, self, preserve))
1335 print_log()
1336 return s
1337 except RuntimeError,e:
1338 if rcParams['verbose']:
1339 print e
1340 return
1341 else: raise
1342
1343 def freq_switch(self, insitu=None):
1344 """
1345 Apply frequency switching to the data.
1346 Parameters:
1347 insitu: if False a new scantable is returned.
1348 Otherwise, the swictching is done in-situ
1349 The default is taken from .asaprc (False)
1350 Example:
1351 none
1352 """
1353 if insitu is None: insitu = rcParams['insitu']
1354 varlist = vars()
1355 try:
1356 if insitu:
1357 from asap._asap import _frequency_switch_insitu
1358 _frequency_switch_insitu(self)
1359 self._add_history("freq_switch", varlist)
1360 print_log()
1361 return
1362 else:
1363 from asap._asap import _frequency_switch
1364 sf = scantable(_frequency_switch(self))
1365 sf._add_history("freq_switch", varlist)
1366 print_log()
1367 return sf
1368 except RuntimeError,e:
1369 if rcParams['verbose']: print e
1370 else: raise
1371
1372 def __add__(self, other):
1373 varlist = vars()
1374 s = None
1375 if isinstance(other, scantable):
1376 from asap._asap import b_operate as _bop
1377 s = scantable(_bop(self, other, 'add', True))
1378 elif isinstance(other, float):
1379 from asap._asap import add as _add
1380 s = scantable(_add(self, other, True))
1381 else:
1382 raise TypeError("Other input is not a scantable or float value")
1383 s._add_history("operator +", varlist)
1384 print_log()
1385 return s
1386
1387
1388 def __sub__(self, other):
1389 """
1390 implicit on all axes and on Tsys
1391 """
1392 varlist = vars()
1393 s = None
1394 if isinstance(other, scantable):
1395 from asap._asap import b_operate as _bop
1396 s = scantable(_bop(self, other, 'sub', True))
1397 elif isinstance(other, float):
1398 from asap._asap import add as _add
1399 s = scantable(_add(self, -other, True))
1400 else:
1401 raise TypeError("Other input is not a scantable or float value")
1402 s._add_history("operator -", varlist)
1403 print_log()
1404 return s
1405
1406 def __mul__(self, other):
1407 """
1408 implicit on all axes and on Tsys
1409 """
1410 varlist = vars()
1411 s = None
1412 if isinstance(other, scantable):
1413 from asap._asap import b_operate as _bop
1414 s = scantable(_bop(self, other, 'mul', True))
1415 elif isinstance(other, float):
1416 if other == 0.0:
1417 raise ZeroDivisionError("Dividing by zero is not recommended")
1418 from asap._asap import scale as _sca
1419 s = scantable(_sca(self, other, True))
1420 else:
1421 raise TypeError("Other input is not a scantable or float value")
1422 s._add_history("operator *", varlist)
1423 print_log()
1424 return s
1425
1426
1427 def __div__(self, other):
1428 """
1429 implicit on all axes and on Tsys
1430 """
1431 varlist = vars()
1432 s = None
1433 if isinstance(other, scantable):
1434 from asap._asap import b_operate as _bop
1435 s = scantable(_bop(self, other, 'div', True))
1436 elif isinstance(other, float):
1437 if other == 0.0:
1438 raise ZeroDivisionError("Dividing by zero is not recommended")
1439 from asap._asap import scale as _sca
1440 s = scantable(_sca(self, 1.0/other, True))
1441 else:
1442 raise TypeError("Other input is not a scantable or float value")
1443 s._add_history("operator /", varlist)
1444 print_log()
1445 return s
1446
1447 def get_fit(self, row=0):
1448 """
1449 Print or return the stored fits for a row in the scantable
1450 Parameters:
1451 row: the row which the fit has been applied to.
1452 """
1453 if row > self.nrow():
1454 return
1455 from asap import asapfit
1456 fit = asapfit(self._getfit(row))
1457 if rcParams['verbose']:
1458 print fit
1459 return
1460 else:
1461 return fit.as_dict()
1462
1463 def _add_history(self, funcname, parameters):
1464 # create date
1465 sep = "##"
1466 from datetime import datetime
1467 dstr = datetime.now().strftime('%Y/%m/%d %H:%M:%S')
1468 hist = dstr+sep
1469 hist += funcname+sep#cdate+sep
1470 if parameters.has_key('self'): del parameters['self']
1471 for k,v in parameters.iteritems():
1472 if type(v) is dict:
1473 for k2,v2 in v.iteritems():
1474 hist += k2
1475 hist += "="
1476 if isinstance(v2,scantable):
1477 hist += 'scantable'
1478 elif k2 == 'mask':
1479 if isinstance(v2,list) or isinstance(v2,tuple):
1480 hist += str(self._zip_mask(v2))
1481 else:
1482 hist += str(v2)
1483 else:
1484 hist += str(v2)
1485 else:
1486 hist += k
1487 hist += "="
1488 if isinstance(v,scantable):
1489 hist += 'scantable'
1490 elif k == 'mask':
1491 if isinstance(v,list) or isinstance(v,tuple):
1492 hist += str(self._zip_mask(v))
1493 else:
1494 hist += str(v)
1495 else:
1496 hist += str(v)
1497 hist += sep
1498 hist = hist[:-2] # remove trailing '##'
1499 self._addhistory(hist)
1500
1501
1502 def _zip_mask(self, mask):
1503 mask = list(mask)
1504 i = 0
1505 segments = []
1506 while mask[i:].count(1):
1507 i += mask[i:].index(1)
1508 if mask[i:].count(0):
1509 j = i + mask[i:].index(0)
1510 else:
1511 j = len(mask)
1512 segments.append([i,j])
1513 i = j
1514 return segments
1515
1516 def _get_ordinate_label(self):
1517 fu = "("+self.get_fluxunit()+")"
1518 import re
1519 lbl = "Intensity"
1520 if re.match(".K.",fu):
1521 lbl = "Brightness Temperature "+ fu
1522 elif re.match(".Jy.",fu):
1523 lbl = "Flux density "+ fu
1524 return lbl
1525
Note: See TracBrowser for help on using the repository browser.