source: trunk/python/asapmath.py@ 2854

Last change on this file since 2854 was 2845, checked in by Takeshi Nakazato, 11 years ago

New Development: No

JIRA Issue: No

Ready for Test: Yes

Interface Changes: No

What Interface Changed: Please list interface changes

Test Programs: List test programs

Put in Release Notes: No

Module(s): sd

Description: Describe your changes here...

Fixed typo.


  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 37.2 KB
RevLine 
[1918]1from asap.scantable import scantable
[1827]2from asap.parameters import rcParams
[1862]3from asap.logging import asaplog, asaplog_post_dec
[1826]4from asap.selector import selector
[2150]5from asap.asapplotter import new_asaplot
[2538]6from matplotlib import rc as rcp
[101]7
[1862]8@asaplog_post_dec
[143]9def average_time(*args, **kwargs):
[101]10 """
[113]11 Return the (time) average of a scan or list of scans. [in channels only]
[305]12 The cursor of the output scan is set to 0
[113]13 Parameters:
[1361]14 one scan or comma separated scans or a list of scans
[143]15 mask: an optional mask (only used for 'var' and 'tsys' weighting)
[558]16 scanav: True averages each scan separately.
17 False (default) averages all scans together,
[1232]18 weight: Weighting scheme.
19 'none' (mean no weight)
20 'var' (1/var(spec) weighted)
21 'tsys' (1/Tsys**2 weighted)
22 'tint' (integration time weighted)
23 'tintsys' (Tint/Tsys**2)
24 'median' ( median averaging)
[930]25 align: align the spectra in velocity before averaging. It takes
26 the time of the first spectrum in the first scantable
27 as reference time.
[2472]28 compel: True forces to average overwrapped IFs.
[113]29 Example:
30 # return a time averaged scan from scana and scanb
31 # without using a mask
[129]32 scanav = average_time(scana,scanb)
[1589]33 # or equivalent
34 # scanav = average_time([scana, scanb])
[113]35 # return the (time) averaged scan, i.e. the average of
36 # all correlator cycles
[558]37 scanav = average_time(scan, scanav=True)
[101]38 """
[930]39 scanav = False
[143]40 if kwargs.has_key('scanav'):
[930]41 scanav = kwargs.get('scanav')
[524]42 weight = 'tint'
[143]43 if kwargs.has_key('weight'):
44 weight = kwargs.get('weight')
45 mask = ()
46 if kwargs.has_key('mask'):
47 mask = kwargs.get('mask')
[930]48 align = False
49 if kwargs.has_key('align'):
50 align = kwargs.get('align')
[1819]51 compel = False
52 if kwargs.has_key('compel'):
53 compel = kwargs.get('compel')
[489]54 varlist = vars()
[665]55 if isinstance(args[0],list):
[981]56 lst = args[0]
[665]57 elif isinstance(args[0],tuple):
[981]58 lst = list(args[0])
[665]59 else:
[981]60 lst = list(args)
[720]61
[489]62 del varlist["kwargs"]
63 varlist["args"] = "%d scantables" % len(lst)
[981]64 # need special formatting here for history...
[720]65
[876]66 from asap._asap import stmath
67 stm = stmath()
[113]68 for s in lst:
[101]69 if not isinstance(s,scantable):
[720]70 msg = "Please give a list of scantables"
[1859]71 raise TypeError(msg)
[945]72 if scanav: scanav = "SCAN"
73 else: scanav = "NONE"
[981]74 alignedlst = []
75 if align:
76 refepoch = lst[0].get_time(0)
77 for scan in lst:
78 alignedlst.append(scan.freq_align(refepoch,insitu=False))
79 else:
[1059]80 alignedlst = lst
[1232]81 if weight.upper() == 'MEDIAN':
82 # median doesn't support list of scantables - merge first
83 merged = None
84 if len(alignedlst) > 1:
85 merged = merge(alignedlst)
86 else:
87 merged = alignedlst[0]
88 s = scantable(stm._averagechannel(merged, 'MEDIAN', scanav))
89 del merged
90 else:
[1819]91 #s = scantable(stm._average(alignedlst, mask, weight.upper(), scanav))
[2818]92 s = scantable(stm._new_average(alignedlst, compel, mask,
93 weight.upper(), scanav))
[489]94 s._add_history("average_time",varlist)
[1859]95
[489]96 return s
[101]97
[1862]98@asaplog_post_dec
[1074]99def quotient(source, reference, preserve=True):
100 """
101 Return the quotient of a 'source' (signal) scan and a 'reference' scan.
102 The reference can have just one scan, even if the signal has many. Otherwise
103 they must have the same number of scans.
104 The cursor of the output scan is set to 0
105 Parameters:
106 source: the 'on' scan
107 reference: the 'off' scan
108 preserve: you can preserve (default) the continuum or
109 remove it. The equations used are
110 preserve: Output = Toff * (on/off) - Toff
111 remove: Output = Toff * (on/off) - Ton
112 """
113 varlist = vars()
114 from asap._asap import stmath
115 stm = stmath()
116 stm._setinsitu(False)
117 s = scantable(stm._quotient(source, reference, preserve))
118 s._add_history("quotient",varlist)
119 return s
[101]120
[1862]121@asaplog_post_dec
[1391]122def dototalpower(calon, caloff, tcalval=0.0):
123 """
124 Do calibration for CAL on,off signals.
125 Adopted from GBTIDL dototalpower
126 Parameters:
127 calon: the 'cal on' subintegration
128 caloff: the 'cal off' subintegration
129 tcalval: user supplied Tcal value
130 """
131 varlist = vars()
132 from asap._asap import stmath
133 stm = stmath()
134 stm._setinsitu(False)
135 s = scantable(stm._dototalpower(calon, caloff, tcalval))
136 s._add_history("dototalpower",varlist)
137 return s
138
[1862]139@asaplog_post_dec
[1391]140def dosigref(sig, ref, smooth, tsysval=0.0, tauval=0.0):
141 """
142 Calculate a quotient (sig-ref/ref * Tsys)
143 Adopted from GBTIDL dosigref
144 Parameters:
145 sig: on source data
146 ref: reference data
147 smooth: width of box car smoothing for reference
148 tsysval: user specified Tsys (scalar only)
149 tauval: user specified Tau (required if tsysval is set)
150 """
151 varlist = vars()
152 from asap._asap import stmath
153 stm = stmath()
154 stm._setinsitu(False)
155 s = scantable(stm._dosigref(sig, ref, smooth, tsysval, tauval))
156 s._add_history("dosigref",varlist)
157 return s
158
[1862]159@asaplog_post_dec
[1819]160def calps(scantab, scannos, smooth=1, tsysval=0.0, tauval=0.0, tcalval=0.0, verify=False):
[1391]161 """
162 Calibrate GBT position switched data
163 Adopted from GBTIDL getps
[1920]164 Currently calps identify the scans as position switched data if source
165 type enum is pson or psoff. The data must contains 'CAL' signal
166 on/off in each integration. To identify 'CAL' on state, the source type
[2472]167 enum of poncal and poffcal need to be present.
[1391]168
169 Parameters:
170 scantab: scantable
171 scannos: list of scan numbers
172 smooth: optional box smoothing order for the reference
173 (default is 1 = no smoothing)
174 tsysval: optional user specified Tsys (default is 0.0,
175 use Tsys in the data)
176 tauval: optional user specified Tau
177 tcalval: optional user specified Tcal (default is 0.0,
178 use Tcal value in the data)
[1920]179 verify: Verify calibration if true
[1391]180 """
181 varlist = vars()
182 # check for the appropriate data
[1819]183## s = scantab.get_scan('*_ps*')
184## if s is None:
185## msg = "The input data appear to contain no position-switch mode data."
[1859]186## raise TypeError(msg)
[1819]187 s = scantab.copy()
188 from asap._asap import srctype
189 sel = selector()
190 sel.set_types( srctype.pson )
191 try:
192 scantab.set_selection( sel )
193 except Exception, e:
[1391]194 msg = "The input data appear to contain no position-switch mode data."
[1859]195 raise TypeError(msg)
[1819]196 s.set_selection()
197 sel.reset()
[1391]198 ssub = s.get_scan(scannos)
199 if ssub is None:
200 msg = "No data was found with given scan numbers!"
[1859]201 raise TypeError(msg)
[1819]202 #ssubon = ssub.get_scan('*calon')
203 #ssuboff = ssub.get_scan('*[^calon]')
204 sel.set_types( [srctype.poncal,srctype.poffcal] )
205 ssub.set_selection( sel )
206 ssubon = ssub.copy()
207 ssub.set_selection()
208 sel.reset()
209 sel.set_types( [srctype.pson,srctype.psoff] )
210 ssub.set_selection( sel )
211 ssuboff = ssub.copy()
212 ssub.set_selection()
213 sel.reset()
[1391]214 if ssubon.nrow() != ssuboff.nrow():
215 msg = "mismatch in numbers of CAL on/off scans. Cannot calibrate. Check the scan numbers."
[1859]216 raise TypeError(msg)
[1391]217 cals = dototalpower(ssubon, ssuboff, tcalval)
[1819]218 #sig = cals.get_scan('*ps')
219 #ref = cals.get_scan('*psr')
220 sel.set_types( srctype.pson )
221 cals.set_selection( sel )
222 sig = cals.copy()
223 cals.set_selection()
224 sel.reset()
225 sel.set_types( srctype.psoff )
226 cals.set_selection( sel )
227 ref = cals.copy()
228 cals.set_selection()
229 sel.reset()
[1391]230 if sig.nscan() != ref.nscan():
231 msg = "mismatch in numbers of on/off scans. Cannot calibrate. Check the scan numbers."
[1859]232 raise TypeError(msg)
[1391]233
234 #for user supplied Tsys
235 if tsysval>0.0:
236 if tauval<=0.0:
237 msg = "Need to supply a valid tau to use the supplied Tsys"
[1859]238 raise TypeError(msg)
[1391]239 else:
240 sig.recalc_azel()
241 ref.recalc_azel()
242 #msg = "Use of user specified Tsys is not fully implemented yet."
[1859]243 #raise TypeError(msg)
[1391]244 # use get_elevation to get elevation and
245 # calculate a scaling factor using the formula
246 # -> tsys use to dosigref
247
248 #ress = dosigref(sig, ref, smooth, tsysval)
249 ress = dosigref(sig, ref, smooth, tsysval, tauval)
[1819]250 ###
251 if verify:
252 # get data
253 import numpy
254 precal={}
255 postcal=[]
256 keys=['ps','ps_calon','psr','psr_calon']
257 types=[srctype.pson,srctype.poncal,srctype.psoff,srctype.poffcal]
258 ifnos=list(ssub.getifnos())
259 polnos=list(ssub.getpolnos())
260 sel=selector()
261 for i in range(2):
262 #ss=ssuboff.get_scan('*'+keys[2*i])
263 ll=[]
264 for j in range(len(ifnos)):
265 for k in range(len(polnos)):
266 sel.set_ifs(ifnos[j])
267 sel.set_polarizations(polnos[k])
268 sel.set_types(types[2*i])
269 try:
270 #ss.set_selection(sel)
271 ssuboff.set_selection(sel)
272 except:
273 continue
274 #ll.append(numpy.array(ss._getspectrum(0)))
275 ll.append(numpy.array(ssuboff._getspectrum(0)))
276 sel.reset()
277 ssuboff.set_selection()
278 precal[keys[2*i]]=ll
279 #del ss
280 #ss=ssubon.get_scan('*'+keys[2*i+1])
281 ll=[]
282 for j in range(len(ifnos)):
283 for k in range(len(polnos)):
284 sel.set_ifs(ifnos[j])
285 sel.set_polarizations(polnos[k])
286 sel.set_types(types[2*i+1])
287 try:
288 #ss.set_selection(sel)
289 ssubon.set_selection(sel)
290 except:
291 continue
292 #ll.append(numpy.array(ss._getspectrum(0)))
293 ll.append(numpy.array(ssubon._getspectrum(0)))
294 sel.reset()
295 ssubon.set_selection()
296 precal[keys[2*i+1]]=ll
297 #del ss
298 for j in range(len(ifnos)):
299 for k in range(len(polnos)):
300 sel.set_ifs(ifnos[j])
301 sel.set_polarizations(polnos[k])
302 try:
303 ress.set_selection(sel)
304 except:
305 continue
306 postcal.append(numpy.array(ress._getspectrum(0)))
307 sel.reset()
308 ress.set_selection()
309 del sel
310 # plot
[1861]311 asaplog.post()
[1819]312 asaplog.push('Plot only first spectrum for each [if,pol] pairs to verify calibration.')
[1861]313 asaplog.post('WARN')
[2150]314 p=new_asaplot()
[2535]315 rcp('lines', linewidth=1)
[1819]316 #nr=min(6,len(ifnos)*len(polnos))
317 nr=len(ifnos)*len(polnos)
318 titles=[]
319 btics=[]
320 if nr<4:
321 p.set_panels(rows=nr,cols=2,nplots=2*nr,ganged=False)
322 for i in range(2*nr):
323 b=False
324 if i >= 2*nr-2:
325 b=True
326 btics.append(b)
327 elif nr==4:
328 p.set_panels(rows=2,cols=4,nplots=8,ganged=False)
329 for i in range(2*nr):
330 b=False
331 if i >= 2*nr-4:
332 b=True
333 btics.append(b)
334 elif nr<7:
335 p.set_panels(rows=3,cols=4,nplots=2*nr,ganged=False)
336 for i in range(2*nr):
337 if i >= 2*nr-4:
338 b=True
339 btics.append(b)
340 else:
[1861]341 asaplog.post()
[1819]342 asaplog.push('Only first 6 [if,pol] pairs are plotted.')
[1861]343 asaplog.post('WARN')
[1819]344 nr=6
345 for i in range(2*nr):
346 b=False
347 if i >= 2*nr-4:
348 b=True
349 btics.append(b)
350 p.set_panels(rows=3,cols=4,nplots=2*nr,ganged=False)
351 for i in range(nr):
352 p.subplot(2*i)
353 p.color=0
354 title='raw data IF%s POL%s' % (ifnos[int(i/len(polnos))],polnos[i%len(polnos)])
355 titles.append(title)
356 #p.set_axes('title',title,fontsize=40)
357 ymin=1.0e100
358 ymax=-1.0e100
[2348]359 nchan=s.nchan(ifnos[int(i/len(polnos))])
[1819]360 edge=int(nchan*0.01)
361 for j in range(4):
362 spmin=min(precal[keys[j]][i][edge:nchan-edge])
363 spmax=max(precal[keys[j]][i][edge:nchan-edge])
364 ymin=min(ymin,spmin)
365 ymax=max(ymax,spmax)
366 for j in range(4):
367 if i==0:
368 p.set_line(label=keys[j])
369 else:
370 p.legend()
371 p.plot(precal[keys[j]][i])
372 p.axes.set_ylim(ymin-0.1*abs(ymin),ymax+0.1*abs(ymax))
373 if not btics[2*i]:
374 p.axes.set_xticks([])
375 p.subplot(2*i+1)
376 p.color=0
377 title='cal data IF%s POL%s' % (ifnos[int(i/len(polnos))],polnos[i%len(polnos)])
378 titles.append(title)
379 #p.set_axes('title',title)
380 p.legend()
381 ymin=postcal[i][edge:nchan-edge].min()
382 ymax=postcal[i][edge:nchan-edge].max()
383 p.plot(postcal[i])
384 p.axes.set_ylim(ymin-0.1*abs(ymin),ymax+0.1*abs(ymax))
385 if not btics[2*i+1]:
386 p.axes.set_xticks([])
387 for i in range(2*nr):
388 p.subplot(i)
389 p.set_axes('title',titles[i],fontsize='medium')
390 x=raw_input('Accept calibration ([y]/n): ' )
391 if x.upper() == 'N':
[2150]392 p.quit()
[1819]393 del p
[2845]394 return scantab
[2150]395 p.quit()
[1819]396 del p
397 ###
[1391]398 ress._add_history("calps", varlist)
399 return ress
400
[1862]401@asaplog_post_dec
[1819]402def calnod(scantab, scannos=[], smooth=1, tsysval=0.0, tauval=0.0, tcalval=0.0, verify=False):
[1391]403 """
404 Do full (but a pair of scans at time) processing of GBT Nod data
405 calibration.
406 Adopted from GBTIDL's getnod
407 Parameters:
408 scantab: scantable
409 scannos: a pair of scan numbers, or the first scan number of the pair
410 smooth: box car smoothing order
411 tsysval: optional user specified Tsys value
412 tauval: optional user specified tau value (not implemented yet)
413 tcalval: optional user specified Tcal value
[1920]414 verify: Verify calibration if true
[1391]415 """
416 varlist = vars()
417 from asap._asap import stmath
[1819]418 from asap._asap import srctype
[1391]419 stm = stmath()
420 stm._setinsitu(False)
421
422 # check for the appropriate data
[1819]423## s = scantab.get_scan('*_nod*')
424## if s is None:
425## msg = "The input data appear to contain no Nod observing mode data."
[1859]426## raise TypeError(msg)
[1819]427 s = scantab.copy()
428 sel = selector()
429 sel.set_types( srctype.nod )
430 try:
431 s.set_selection( sel )
432 except Exception, e:
[1391]433 msg = "The input data appear to contain no Nod observing mode data."
[1859]434 raise TypeError(msg)
[1819]435 sel.reset()
436 del sel
437 del s
[1391]438
439 # need check correspondance of each beam with sig-ref ...
440 # check for timestamps, scan numbers, subscan id (not available in
441 # ASAP data format...). Assume 1st scan of the pair (beam 0 - sig
442 # and beam 1 - ref...)
443 # First scan number of paired scans or list of pairs of
444 # scan numbers (has to have even number of pairs.)
445
446 #data splitting
447 scan1no = scan2no = 0
448
449 if len(scannos)==1:
450 scan1no = scannos[0]
451 scan2no = scannos[0]+1
452 pairScans = [scan1no, scan2no]
453 else:
454 #if len(scannos)>2:
455 # msg = "calnod can only process a pair of nod scans at time."
[1859]456 # raise TypeError(msg)
[1391]457 #
458 #if len(scannos)==2:
459 # scan1no = scannos[0]
460 # scan2no = scannos[1]
461 pairScans = list(scannos)
462
463 if tsysval>0.0:
464 if tauval<=0.0:
465 msg = "Need to supply a valid tau to use the supplied Tsys"
[1859]466 raise TypeError(msg)
[1391]467 else:
468 scantab.recalc_azel()
469 resspec = scantable(stm._donod(scantab, pairScans, smooth, tsysval,tauval,tcalval))
[1819]470 ###
471 if verify:
472 # get data
473 import numpy
474 precal={}
475 postcal=[]
476 keys=['','_calon']
477 types=[srctype.nod,srctype.nodcal]
478 ifnos=list(scantab.getifnos())
479 polnos=list(scantab.getpolnos())
480 sel=selector()
481 ss = scantab.copy()
482 for i in range(2):
483 #ss=scantab.get_scan('*'+keys[i])
484 ll=[]
485 ll2=[]
486 for j in range(len(ifnos)):
487 for k in range(len(polnos)):
488 sel.set_ifs(ifnos[j])
489 sel.set_polarizations(polnos[k])
490 sel.set_scans(pairScans[0])
491 sel.set_types(types[i])
492 try:
493 ss.set_selection(sel)
494 except:
495 continue
496 ll.append(numpy.array(ss._getspectrum(0)))
497 sel.reset()
498 ss.set_selection()
499 sel.set_ifs(ifnos[j])
500 sel.set_polarizations(polnos[k])
501 sel.set_scans(pairScans[1])
502 sel.set_types(types[i])
503 try:
504 ss.set_selection(sel)
505 except:
506 ll.pop()
507 continue
508 ll2.append(numpy.array(ss._getspectrum(0)))
509 sel.reset()
510 ss.set_selection()
511 key='%s%s' %(pairScans[0],keys[i])
512 precal[key]=ll
513 key='%s%s' %(pairScans[1],keys[i])
514 precal[key]=ll2
515 #del ss
516 keys=precal.keys()
517 for j in range(len(ifnos)):
518 for k in range(len(polnos)):
519 sel.set_ifs(ifnos[j])
520 sel.set_polarizations(polnos[k])
521 sel.set_scans(pairScans[0])
522 try:
523 resspec.set_selection(sel)
524 except:
525 continue
526 postcal.append(numpy.array(resspec._getspectrum(0)))
527 sel.reset()
528 resspec.set_selection()
529 del sel
530 # plot
[1861]531 asaplog.post()
[1819]532 asaplog.push('Plot only first spectrum for each [if,pol] pairs to verify calibration.')
[1861]533 asaplog.post('WARN')
[2150]534 p=new_asaplot()
[2535]535 rcp('lines', linewidth=1)
[1819]536 #nr=min(6,len(ifnos)*len(polnos))
537 nr=len(ifnos)*len(polnos)
538 titles=[]
539 btics=[]
540 if nr<4:
541 p.set_panels(rows=nr,cols=2,nplots=2*nr,ganged=False)
542 for i in range(2*nr):
543 b=False
544 if i >= 2*nr-2:
545 b=True
546 btics.append(b)
547 elif nr==4:
548 p.set_panels(rows=2,cols=4,nplots=8,ganged=False)
549 for i in range(2*nr):
550 b=False
551 if i >= 2*nr-4:
552 b=True
553 btics.append(b)
554 elif nr<7:
555 p.set_panels(rows=3,cols=4,nplots=2*nr,ganged=False)
556 for i in range(2*nr):
557 if i >= 2*nr-4:
558 b=True
559 btics.append(b)
560 else:
[1861]561 asaplog.post()
[1819]562 asaplog.push('Only first 6 [if,pol] pairs are plotted.')
[1861]563 asaplog.post('WARN')
[1819]564 nr=6
565 for i in range(2*nr):
566 b=False
567 if i >= 2*nr-4:
568 b=True
569 btics.append(b)
570 p.set_panels(rows=3,cols=4,nplots=2*nr,ganged=False)
571 for i in range(nr):
572 p.subplot(2*i)
573 p.color=0
574 title='raw data IF%s POL%s' % (ifnos[int(i/len(polnos))],polnos[i%len(polnos)])
575 titles.append(title)
576 #p.set_axes('title',title,fontsize=40)
577 ymin=1.0e100
578 ymax=-1.0e100
[2348]579 nchan=scantab.nchan(ifnos[int(i/len(polnos))])
[1819]580 edge=int(nchan*0.01)
581 for j in range(4):
582 spmin=min(precal[keys[j]][i][edge:nchan-edge])
583 spmax=max(precal[keys[j]][i][edge:nchan-edge])
584 ymin=min(ymin,spmin)
585 ymax=max(ymax,spmax)
586 for j in range(4):
587 if i==0:
588 p.set_line(label=keys[j])
589 else:
590 p.legend()
591 p.plot(precal[keys[j]][i])
592 p.axes.set_ylim(ymin-0.1*abs(ymin),ymax+0.1*abs(ymax))
593 if not btics[2*i]:
594 p.axes.set_xticks([])
595 p.subplot(2*i+1)
596 p.color=0
597 title='cal data IF%s POL%s' % (ifnos[int(i/len(polnos))],polnos[i%len(polnos)])
598 titles.append(title)
599 #p.set_axes('title',title)
600 p.legend()
601 ymin=postcal[i][edge:nchan-edge].min()
602 ymax=postcal[i][edge:nchan-edge].max()
603 p.plot(postcal[i])
604 p.axes.set_ylim(ymin-0.1*abs(ymin),ymax+0.1*abs(ymax))
605 if not btics[2*i+1]:
606 p.axes.set_xticks([])
607 for i in range(2*nr):
608 p.subplot(i)
609 p.set_axes('title',titles[i],fontsize='medium')
610 x=raw_input('Accept calibration ([y]/n): ' )
611 if x.upper() == 'N':
[2150]612 p.quit()
[1819]613 del p
[2845]614 return scantab
[2150]615 p.quit()
[1819]616 del p
617 ###
[1391]618 resspec._add_history("calnod",varlist)
619 return resspec
620
[1862]621@asaplog_post_dec
[1819]622def calfs(scantab, scannos=[], smooth=1, tsysval=0.0, tauval=0.0, tcalval=0.0, verify=False):
[1391]623 """
624 Calibrate GBT frequency switched data.
625 Adopted from GBTIDL getfs.
[1920]626 Currently calfs identify the scans as frequency switched data if source
627 type enum is fson and fsoff. The data must contains 'CAL' signal
628 on/off in each integration. To identify 'CAL' on state, the source type
[2472]629 enum of foncal and foffcal need to be present.
[1391]630
631 Parameters:
632 scantab: scantable
633 scannos: list of scan numbers
634 smooth: optional box smoothing order for the reference
635 (default is 1 = no smoothing)
636 tsysval: optional user specified Tsys (default is 0.0,
637 use Tsys in the data)
638 tauval: optional user specified Tau
[1920]639 verify: Verify calibration if true
[1391]640 """
641 varlist = vars()
642 from asap._asap import stmath
[1819]643 from asap._asap import srctype
[1391]644 stm = stmath()
645 stm._setinsitu(False)
646
647# check = scantab.get_scan('*_fs*')
648# if check is None:
649# msg = "The input data appear to contain no Nod observing mode data."
[1859]650# raise TypeError(msg)
[1391]651 s = scantab.get_scan(scannos)
652 del scantab
653
654 resspec = scantable(stm._dofs(s, scannos, smooth, tsysval,tauval,tcalval))
[1819]655 ###
656 if verify:
657 # get data
658 ssub = s.get_scan(scannos)
659 #ssubon = ssub.get_scan('*calon')
660 #ssuboff = ssub.get_scan('*[^calon]')
661 sel = selector()
662 sel.set_types( [srctype.foncal,srctype.foffcal] )
663 ssub.set_selection( sel )
664 ssubon = ssub.copy()
665 ssub.set_selection()
666 sel.reset()
667 sel.set_types( [srctype.fson,srctype.fsoff] )
668 ssub.set_selection( sel )
669 ssuboff = ssub.copy()
670 ssub.set_selection()
671 sel.reset()
672 import numpy
673 precal={}
674 postcal=[]
675 keys=['fs','fs_calon','fsr','fsr_calon']
676 types=[srctype.fson,srctype.foncal,srctype.fsoff,srctype.foffcal]
677 ifnos=list(ssub.getifnos())
678 polnos=list(ssub.getpolnos())
679 for i in range(2):
680 #ss=ssuboff.get_scan('*'+keys[2*i])
681 ll=[]
682 for j in range(len(ifnos)):
683 for k in range(len(polnos)):
684 sel.set_ifs(ifnos[j])
685 sel.set_polarizations(polnos[k])
686 sel.set_types(types[2*i])
687 try:
688 #ss.set_selection(sel)
689 ssuboff.set_selection(sel)
690 except:
691 continue
692 ll.append(numpy.array(ss._getspectrum(0)))
693 sel.reset()
694 #ss.set_selection()
695 ssuboff.set_selection()
696 precal[keys[2*i]]=ll
697 #del ss
698 #ss=ssubon.get_scan('*'+keys[2*i+1])
699 ll=[]
700 for j in range(len(ifnos)):
701 for k in range(len(polnos)):
702 sel.set_ifs(ifnos[j])
703 sel.set_polarizations(polnos[k])
704 sel.set_types(types[2*i+1])
705 try:
706 #ss.set_selection(sel)
707 ssubon.set_selection(sel)
708 except:
709 continue
710 ll.append(numpy.array(ss._getspectrum(0)))
711 sel.reset()
712 #ss.set_selection()
713 ssubon.set_selection()
714 precal[keys[2*i+1]]=ll
715 #del ss
716 #sig=resspec.get_scan('*_fs')
717 #ref=resspec.get_scan('*_fsr')
718 sel.set_types( srctype.fson )
719 resspec.set_selection( sel )
720 sig=resspec.copy()
721 resspec.set_selection()
722 sel.reset()
723 sel.set_type( srctype.fsoff )
724 resspec.set_selection( sel )
725 ref=resspec.copy()
726 resspec.set_selection()
727 sel.reset()
728 for k in range(len(polnos)):
729 for j in range(len(ifnos)):
730 sel.set_ifs(ifnos[j])
731 sel.set_polarizations(polnos[k])
732 try:
733 sig.set_selection(sel)
734 postcal.append(numpy.array(sig._getspectrum(0)))
735 except:
736 ref.set_selection(sel)
737 postcal.append(numpy.array(ref._getspectrum(0)))
738 sel.reset()
739 resspec.set_selection()
740 del sel
741 # plot
[1861]742 asaplog.post()
[1819]743 asaplog.push('Plot only first spectrum for each [if,pol] pairs to verify calibration.')
[1861]744 asaplog.post('WARN')
[2150]745 p=new_asaplot()
[2535]746 rcp('lines', linewidth=1)
[1819]747 #nr=min(6,len(ifnos)*len(polnos))
748 nr=len(ifnos)/2*len(polnos)
749 titles=[]
750 btics=[]
751 if nr>3:
[1861]752 asaplog.post()
[1819]753 asaplog.push('Only first 3 [if,pol] pairs are plotted.')
[1861]754 asaplog.post('WARN')
[1819]755 nr=3
756 p.set_panels(rows=nr,cols=3,nplots=3*nr,ganged=False)
757 for i in range(3*nr):
758 b=False
759 if i >= 3*nr-3:
760 b=True
761 btics.append(b)
762 for i in range(nr):
763 p.subplot(3*i)
764 p.color=0
765 title='raw data IF%s,%s POL%s' % (ifnos[2*int(i/len(polnos))],ifnos[2*int(i/len(polnos))+1],polnos[i%len(polnos)])
766 titles.append(title)
767 #p.set_axes('title',title,fontsize=40)
768 ymin=1.0e100
769 ymax=-1.0e100
[2348]770 nchan=s.nchan(ifnos[2*int(i/len(polnos))])
[1819]771 edge=int(nchan*0.01)
772 for j in range(4):
773 spmin=min(precal[keys[j]][i][edge:nchan-edge])
774 spmax=max(precal[keys[j]][i][edge:nchan-edge])
775 ymin=min(ymin,spmin)
776 ymax=max(ymax,spmax)
777 for j in range(4):
778 if i==0:
779 p.set_line(label=keys[j])
780 else:
781 p.legend()
782 p.plot(precal[keys[j]][i])
783 p.axes.set_ylim(ymin-0.1*abs(ymin),ymax+0.1*abs(ymax))
784 if not btics[3*i]:
785 p.axes.set_xticks([])
786 p.subplot(3*i+1)
787 p.color=0
788 title='sig data IF%s POL%s' % (ifnos[2*int(i/len(polnos))],polnos[i%len(polnos)])
789 titles.append(title)
790 #p.set_axes('title',title)
791 p.legend()
792 ymin=postcal[2*i][edge:nchan-edge].min()
793 ymax=postcal[2*i][edge:nchan-edge].max()
794 p.plot(postcal[2*i])
795 p.axes.set_ylim(ymin-0.1*abs(ymin),ymax+0.1*abs(ymax))
796 if not btics[3*i+1]:
797 p.axes.set_xticks([])
798 p.subplot(3*i+2)
799 p.color=0
800 title='ref data IF%s POL%s' % (ifnos[2*int(i/len(polnos))+1],polnos[i%len(polnos)])
801 titles.append(title)
802 #p.set_axes('title',title)
803 p.legend()
804 ymin=postcal[2*i+1][edge:nchan-edge].min()
805 ymax=postcal[2*i+1][edge:nchan-edge].max()
806 p.plot(postcal[2*i+1])
807 p.axes.set_ylim(ymin-0.1*abs(ymin),ymax+0.1*abs(ymax))
808 if not btics[3*i+2]:
809 p.axes.set_xticks([])
810 for i in range(3*nr):
811 p.subplot(i)
812 p.set_axes('title',titles[i],fontsize='medium')
813 x=raw_input('Accept calibration ([y]/n): ' )
814 if x.upper() == 'N':
[2150]815 p.quit()
[1819]816 del p
[2845]817 return scantab
[2150]818 p.quit()
[1819]819 del p
820 ###
[1391]821 resspec._add_history("calfs",varlist)
822 return resspec
823
[1862]824@asaplog_post_dec
[918]825def merge(*args):
[945]826 """
[1362]827 Merge a list of scanatables, or comma-sperated scantables into one
828 scnatble.
829 Parameters:
830 A list [scan1, scan2] or scan1, scan2.
831 Example:
832 myscans = [scan1, scan2]
[1589]833 allscans = merge(myscans)
834 # or equivalent
835 sameallscans = merge(scan1, scan2)
[945]836 """
[918]837 varlist = vars()
838 if isinstance(args[0],list):
839 lst = tuple(args[0])
840 elif isinstance(args[0],tuple):
841 lst = args[0]
842 else:
843 lst = tuple(args)
844 varlist["args"] = "%d scantables" % len(lst)
845 # need special formatting her for history...
846 from asap._asap import stmath
847 stm = stmath()
848 for s in lst:
849 if not isinstance(s,scantable):
850 msg = "Please give a list of scantables"
[1859]851 raise TypeError(msg)
[918]852 s = scantable(stm._merge(lst))
853 s._add_history("merge", varlist)
854 return s
[1819]855
[1862]856@asaplog_post_dec
[1819]857def calibrate( scantab, scannos=[], calmode='none', verify=None ):
858 """
859 Calibrate data.
[1826]860
[1819]861 Parameters:
862 scantab: scantable
863 scannos: list of scan number
864 calmode: calibration mode
[1826]865 verify: verify calibration
[1819]866 """
[2102]867 import re
[1819]868 antname = scantab.get_antennaname()
869 if ( calmode == 'nod' ):
870 asaplog.push( 'Calibrating nod data.' )
871 scal = calnod( scantab, scannos=scannos, verify=verify )
872 elif ( calmode == 'quotient' ):
873 asaplog.push( 'Calibrating using quotient.' )
874 scal = scantab.auto_quotient( verify=verify )
875 elif ( calmode == 'ps' ):
876 asaplog.push( 'Calibrating %s position-switched data.' % antname )
877 if ( antname.find( 'APEX' ) != -1 ):
878 scal = apexcal( scantab, scannos, calmode, verify )
[2102]879 elif ( antname.find( 'ALMA' ) != -1 or antname.find( 'OSF' ) != -1
880 or re.match('DV[0-9][0-9]$',antname) is not None
881 or re.match('PM[0-9][0-9]$',antname) is not None
882 or re.match('CM[0-9][0-9]$',antname) is not None
883 or re.match('DA[0-9][0-9]$',antname) is not None ):
[1819]884 scal = almacal( scantab, scannos, calmode, verify )
885 else:
886 scal = calps( scantab, scannos=scannos, verify=verify )
887 elif ( calmode == 'fs' or calmode == 'fsotf' ):
888 asaplog.push( 'Calibrating %s frequency-switched data.' % antname )
889 if ( antname.find( 'APEX' ) != -1 ):
890 scal = apexcal( scantab, scannos, calmode, verify )
891 elif ( antname.find( 'ALMA' ) != -1 or antname.find( 'OSF' ) != -1 ):
892 scal = almacal( scantab, scannos, calmode, verify )
893 else:
894 scal = calfs( scantab, scannos=scannos, verify=verify )
895 elif ( calmode == 'otf' ):
896 asaplog.push( 'Calibrating %s On-The-Fly data.' % antname )
897 scal = almacal( scantab, scannos, calmode, verify )
898 else:
899 asaplog.push( 'No calibration.' )
900 scal = scantab.copy()
901
[1826]902 return scal
[1819]903
904def apexcal( scantab, scannos=[], calmode='none', verify=False ):
905 """
906 Calibrate APEX data
907
908 Parameters:
909 scantab: scantable
910 scannos: list of scan number
911 calmode: calibration mode
912
[1826]913 verify: verify calibration
[1819]914 """
915 from asap._asap import stmath
916 stm = stmath()
917 antname = scantab.get_antennaname()
[2580]918 selection=selector()
919 selection.set_scans(scannos)
920 orig = scantab.get_selection()
921 scantab.set_selection(orig+selection)
922## ssub = scantab.get_scan( scannos )
923## scal = scantable( stm.cwcal( ssub, calmode, antname ) )
924 scal = scantable( stm.cwcal( scantab, calmode, antname ) )
925 scantab.set_selection(orig)
[1819]926 return scal
927
928def almacal( scantab, scannos=[], calmode='none', verify=False ):
929 """
930 Calibrate ALMA data
931
932 Parameters:
933 scantab: scantable
934 scannos: list of scan number
935 calmode: calibration mode
936
[1826]937 verify: verify calibration
[1819]938 """
939 from asap._asap import stmath
940 stm = stmath()
[2580]941 selection=selector()
942 selection.set_scans(scannos)
943 orig = scantab.get_selection()
944 scantab.set_selection(orig+selection)
945## ssub = scantab.get_scan( scannos )
946## scal = scantable( stm.almacal( ssub, calmode ) )
947 scal = scantable( stm.almacal( scantab, calmode ) )
948 scantab.set_selection(orig)
[1819]949 return scal
950
[1862]951@asaplog_post_dec
[2843]952def splitant(filename, outprefix='',overwrite=False, getpt=True):
[1819]953 """
954 Split Measurement set by antenna name, save data as a scantables,
[2843]955 and return a list of filename. Note that frequency reference frame
956 is imported as it is in Measurement set.
[1826]957 Notice this method can only be available from CASA.
[1819]958 Prameter
[1826]959 filename: the name of Measurement set to be read.
[1819]960 outprefix: the prefix of output scantable name.
961 the names of output scantable will be
962 outprefix.antenna1, outprefix.antenna2, ....
963 If not specified, outprefix = filename is assumed.
964 overwrite If the file should be overwritten if it exists.
965 The default False is to return with warning
966 without writing the output. USE WITH CARE.
[2754]967 getpt Whether to import direction from MS/POINTING
968 table or not. Default is True (import direction).
[1819]969 """
970 # Import the table toolkit from CASA
[2843]971 from taskinit import gentools
[1918]972 from asap.scantable import is_ms
[2843]973 tb = gentools(['tb'])[0]
[1819]974 # Check the input filename
975 if isinstance(filename, str):
976 import os.path
977 filename = os.path.expandvars(filename)
978 filename = os.path.expanduser(filename)
979 if not os.path.exists(filename):
980 s = "File '%s' not found." % (filename)
981 raise IOError(s)
982 # check if input file is MS
[1883]983 if not is_ms(filename):
[1819]984 s = "File '%s' is not a Measurement set." % (filename)
985 raise IOError(s)
986 else:
987 s = "The filename should be string. "
988 raise TypeError(s)
989 # Check out put file name
990 outname=''
991 if len(outprefix) > 0: prefix=outprefix+'.'
992 else:
993 prefix=filename.rstrip('/')
994 # Now do the actual splitting.
995 outfiles=[]
[2034]996 tb.open(tablename=filename,nomodify=True)
997 ant1=tb.getcol('ANTENNA1',0,-1,1)
[2366]998 anttab=tb.getkeyword('ANTENNA').lstrip('Table: ')
[2034]999 tb.close()
1000 tb.open(tablename=anttab,nomodify=True)
[1819]1001 nant=tb.nrows()
1002 antnames=tb.getcol('NAME',0,nant,1)
1003 tb.close()
1004 for antid in set(ant1):
[2843]1005 scan=scantable(filename,average=False,antenna=int(antid),getpt=getpt)
[1918]1006 outname=prefix+antnames[antid]+'.asap'
1007 scan.save(outname,format='ASAP',overwrite=overwrite)
[1819]1008 del scan
1009 outfiles.append(outname)
1010 return outfiles
1011
[1862]1012@asaplog_post_dec
[2320]1013def _array2dOp( scan, value, mode="ADD", tsys=False, insitu=None):
[1819]1014 """
1015 This function is workaround on the basic operation of scantable
1016 with 2 dimensional float list.
1017
1018 scan: scantable operand
1019 value: float list operand
1020 mode: operation mode (ADD, SUB, MUL, DIV)
[1826]1021 tsys: if True, operate tsys as well
[2336]1022 insitu: if False, a new scantable is returned.
1023 Otherwise, the array operation is done in-sitsu.
[1819]1024 """
[2574]1025 if insitu is None: insitu = rcParams['insitu']
[1819]1026 nrow = scan.nrow()
1027 s = None
[2320]1028 from asap._asap import stmath
1029 stm = stmath()
1030 stm._setinsitu(insitu)
[1819]1031 if len( value ) == 1:
[2320]1032 s = scantable( stm._arrayop( scan, value[0], mode, tsys ) )
[1819]1033 elif len( value ) != nrow:
[1859]1034 raise ValueError( 'len(value) must be 1 or conform to scan.nrow()' )
[1819]1035 else:
1036 from asap._asap import stmath
[2320]1037 if not insitu:
1038 s = scan.copy()
1039 else:
1040 s = scan
1041 # insitu must be True as we go row by row on the same data
[1819]1042 stm._setinsitu( True )
[2320]1043 basesel = s.get_selection()
[2341]1044 # generate a new selector object based on basesel
1045 sel = selector(basesel)
[1819]1046 for irow in range( nrow ):
1047 sel.set_rows( irow )
1048 s.set_selection( sel )
1049 if len( value[irow] ) == 1:
1050 stm._unaryop( s, value[irow][0], mode, tsys )
1051 else:
[2139]1052 #stm._arrayop( s, value[irow], mode, tsys, 'channel' )
1053 stm._arrayop( s, value[irow], mode, tsys )
[2320]1054 s.set_selection(basesel)
[1819]1055 return s
Note: See TracBrowser for help on using the repository browser.