source: branches/Release12/python/scantable.py@ 786

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

added allaxes arg to poly_baseline

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