source: branches/casa-prerelease/pre-asap/python/asapmath.py@ 2165

Last change on this file since 2165 was 2140, checked in by Takeshi Nakazato, 14 years ago

merge bug fix on trunk (r2139).

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