source: trunk/python/asapmath.py@ 2475

Last change on this file since 2475 was 2472, checked in by Takeshi Nakazato, 13 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: Yes/No

Module(s): Module Names change impacts.

Description: Describe your changes here...

Updated online help.


  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 36.9 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
5#from asap import asaplotgui
6from asap.asapplotter import new_asaplot
7
8@asaplog_post_dec
9def average_time(*args, **kwargs):
10 """
11 Return the (time) average of a scan or list of scans. [in channels only]
12 The cursor of the output scan is set to 0
13 Parameters:
14 one scan or comma separated scans or a list of scans
15 mask: an optional mask (only used for 'var' and 'tsys' weighting)
16 scanav: True averages each scan separately.
17 False (default) averages all scans together,
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)
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.
28 compel: True forces to average overwrapped IFs.
29 Example:
30 # return a time averaged scan from scana and scanb
31 # without using a mask
32 scanav = average_time(scana,scanb)
33 # or equivalent
34 # scanav = average_time([scana, scanb])
35 # return the (time) averaged scan, i.e. the average of
36 # all correlator cycles
37 scanav = average_time(scan, scanav=True)
38 """
39 scanav = False
40 if kwargs.has_key('scanav'):
41 scanav = kwargs.get('scanav')
42 weight = 'tint'
43 if kwargs.has_key('weight'):
44 weight = kwargs.get('weight')
45 mask = ()
46 if kwargs.has_key('mask'):
47 mask = kwargs.get('mask')
48 align = False
49 if kwargs.has_key('align'):
50 align = kwargs.get('align')
51 compel = False
52 if kwargs.has_key('compel'):
53 compel = kwargs.get('compel')
54 varlist = vars()
55 if isinstance(args[0],list):
56 lst = args[0]
57 elif isinstance(args[0],tuple):
58 lst = list(args[0])
59 else:
60 lst = list(args)
61
62 del varlist["kwargs"]
63 varlist["args"] = "%d scantables" % len(lst)
64 # need special formatting here for history...
65
66 from asap._asap import stmath
67 stm = stmath()
68 for s in lst:
69 if not isinstance(s,scantable):
70 msg = "Please give a list of scantables"
71 raise TypeError(msg)
72 if scanav: scanav = "SCAN"
73 else: scanav = "NONE"
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:
80 alignedlst = lst
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:
91 #s = scantable(stm._average(alignedlst, mask, weight.upper(), scanav))
92 s = scantable(stm._new_average(alignedlst, compel, mask, weight.upper(), scanav))
93 s._add_history("average_time",varlist)
94
95 return s
96
97@asaplog_post_dec
98def quotient(source, reference, preserve=True):
99 """
100 Return the quotient of a 'source' (signal) scan and a 'reference' scan.
101 The reference can have just one scan, even if the signal has many. Otherwise
102 they must have the same number of scans.
103 The cursor of the output scan is set to 0
104 Parameters:
105 source: the 'on' scan
106 reference: the 'off' scan
107 preserve: you can preserve (default) the continuum or
108 remove it. The equations used are
109 preserve: Output = Toff * (on/off) - Toff
110 remove: Output = Toff * (on/off) - Ton
111 """
112 varlist = vars()
113 from asap._asap import stmath
114 stm = stmath()
115 stm._setinsitu(False)
116 s = scantable(stm._quotient(source, reference, preserve))
117 s._add_history("quotient",varlist)
118 return s
119
120@asaplog_post_dec
121def dototalpower(calon, caloff, tcalval=0.0):
122 """
123 Do calibration for CAL on,off signals.
124 Adopted from GBTIDL dototalpower
125 Parameters:
126 calon: the 'cal on' subintegration
127 caloff: the 'cal off' subintegration
128 tcalval: user supplied Tcal value
129 """
130 varlist = vars()
131 from asap._asap import stmath
132 stm = stmath()
133 stm._setinsitu(False)
134 s = scantable(stm._dototalpower(calon, caloff, tcalval))
135 s._add_history("dototalpower",varlist)
136 return s
137
138@asaplog_post_dec
139def dosigref(sig, ref, smooth, tsysval=0.0, tauval=0.0):
140 """
141 Calculate a quotient (sig-ref/ref * Tsys)
142 Adopted from GBTIDL dosigref
143 Parameters:
144 sig: on source data
145 ref: reference data
146 smooth: width of box car smoothing for reference
147 tsysval: user specified Tsys (scalar only)
148 tauval: user specified Tau (required if tsysval is set)
149 """
150 varlist = vars()
151 from asap._asap import stmath
152 stm = stmath()
153 stm._setinsitu(False)
154 s = scantable(stm._dosigref(sig, ref, smooth, tsysval, tauval))
155 s._add_history("dosigref",varlist)
156 return s
157
158@asaplog_post_dec
159def calps(scantab, scannos, smooth=1, tsysval=0.0, tauval=0.0, tcalval=0.0, verify=False):
160 """
161 Calibrate GBT position switched data
162 Adopted from GBTIDL getps
163 Currently calps identify the scans as position switched data if source
164 type enum is pson or psoff. The data must contains 'CAL' signal
165 on/off in each integration. To identify 'CAL' on state, the source type
166 enum of poncal and poffcal need to be present.
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=new_asaplot()
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(ifnos[int(i/len(polnos))])
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.quit()
391 del p
392 return scabtab
393 p.quit()
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=new_asaplot()
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(ifnos[int(i/len(polnos))])
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.quit()
610 del p
611 return scabtab
612 p.quit()
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.
627
628 Parameters:
629 scantab: scantable
630 scannos: list of scan numbers
631 smooth: optional box smoothing order for the reference
632 (default is 1 = no smoothing)
633 tsysval: optional user specified Tsys (default is 0.0,
634 use Tsys in the data)
635 tauval: optional user specified Tau
636 verify: Verify calibration if true
637 """
638 varlist = vars()
639 from asap._asap import stmath
640 from asap._asap import srctype
641 stm = stmath()
642 stm._setinsitu(False)
643
644# check = scantab.get_scan('*_fs*')
645# if check is None:
646# msg = "The input data appear to contain no Nod observing mode data."
647# raise TypeError(msg)
648 s = scantab.get_scan(scannos)
649 del scantab
650
651 resspec = scantable(stm._dofs(s, scannos, smooth, tsysval,tauval,tcalval))
652 ###
653 if verify:
654 # get data
655 ssub = s.get_scan(scannos)
656 #ssubon = ssub.get_scan('*calon')
657 #ssuboff = ssub.get_scan('*[^calon]')
658 sel = selector()
659 sel.set_types( [srctype.foncal,srctype.foffcal] )
660 ssub.set_selection( sel )
661 ssubon = ssub.copy()
662 ssub.set_selection()
663 sel.reset()
664 sel.set_types( [srctype.fson,srctype.fsoff] )
665 ssub.set_selection( sel )
666 ssuboff = ssub.copy()
667 ssub.set_selection()
668 sel.reset()
669 import numpy
670 precal={}
671 postcal=[]
672 keys=['fs','fs_calon','fsr','fsr_calon']
673 types=[srctype.fson,srctype.foncal,srctype.fsoff,srctype.foffcal]
674 ifnos=list(ssub.getifnos())
675 polnos=list(ssub.getpolnos())
676 for i in range(2):
677 #ss=ssuboff.get_scan('*'+keys[2*i])
678 ll=[]
679 for j in range(len(ifnos)):
680 for k in range(len(polnos)):
681 sel.set_ifs(ifnos[j])
682 sel.set_polarizations(polnos[k])
683 sel.set_types(types[2*i])
684 try:
685 #ss.set_selection(sel)
686 ssuboff.set_selection(sel)
687 except:
688 continue
689 ll.append(numpy.array(ss._getspectrum(0)))
690 sel.reset()
691 #ss.set_selection()
692 ssuboff.set_selection()
693 precal[keys[2*i]]=ll
694 #del ss
695 #ss=ssubon.get_scan('*'+keys[2*i+1])
696 ll=[]
697 for j in range(len(ifnos)):
698 for k in range(len(polnos)):
699 sel.set_ifs(ifnos[j])
700 sel.set_polarizations(polnos[k])
701 sel.set_types(types[2*i+1])
702 try:
703 #ss.set_selection(sel)
704 ssubon.set_selection(sel)
705 except:
706 continue
707 ll.append(numpy.array(ss._getspectrum(0)))
708 sel.reset()
709 #ss.set_selection()
710 ssubon.set_selection()
711 precal[keys[2*i+1]]=ll
712 #del ss
713 #sig=resspec.get_scan('*_fs')
714 #ref=resspec.get_scan('*_fsr')
715 sel.set_types( srctype.fson )
716 resspec.set_selection( sel )
717 sig=resspec.copy()
718 resspec.set_selection()
719 sel.reset()
720 sel.set_type( srctype.fsoff )
721 resspec.set_selection( sel )
722 ref=resspec.copy()
723 resspec.set_selection()
724 sel.reset()
725 for k in range(len(polnos)):
726 for j in range(len(ifnos)):
727 sel.set_ifs(ifnos[j])
728 sel.set_polarizations(polnos[k])
729 try:
730 sig.set_selection(sel)
731 postcal.append(numpy.array(sig._getspectrum(0)))
732 except:
733 ref.set_selection(sel)
734 postcal.append(numpy.array(ref._getspectrum(0)))
735 sel.reset()
736 resspec.set_selection()
737 del sel
738 # plot
739 asaplog.post()
740 asaplog.push('Plot only first spectrum for each [if,pol] pairs to verify calibration.')
741 asaplog.post('WARN')
742 p=new_asaplot()
743 #nr=min(6,len(ifnos)*len(polnos))
744 nr=len(ifnos)/2*len(polnos)
745 titles=[]
746 btics=[]
747 if nr>3:
748 asaplog.post()
749 asaplog.push('Only first 3 [if,pol] pairs are plotted.')
750 asaplog.post('WARN')
751 nr=3
752 p.set_panels(rows=nr,cols=3,nplots=3*nr,ganged=False)
753 for i in range(3*nr):
754 b=False
755 if i >= 3*nr-3:
756 b=True
757 btics.append(b)
758 for i in range(nr):
759 p.subplot(3*i)
760 p.color=0
761 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)])
762 titles.append(title)
763 #p.set_axes('title',title,fontsize=40)
764 ymin=1.0e100
765 ymax=-1.0e100
766 nchan=s.nchan(ifnos[2*int(i/len(polnos))])
767 edge=int(nchan*0.01)
768 for j in range(4):
769 spmin=min(precal[keys[j]][i][edge:nchan-edge])
770 spmax=max(precal[keys[j]][i][edge:nchan-edge])
771 ymin=min(ymin,spmin)
772 ymax=max(ymax,spmax)
773 for j in range(4):
774 if i==0:
775 p.set_line(label=keys[j])
776 else:
777 p.legend()
778 p.plot(precal[keys[j]][i])
779 p.axes.set_ylim(ymin-0.1*abs(ymin),ymax+0.1*abs(ymax))
780 if not btics[3*i]:
781 p.axes.set_xticks([])
782 p.subplot(3*i+1)
783 p.color=0
784 title='sig data IF%s POL%s' % (ifnos[2*int(i/len(polnos))],polnos[i%len(polnos)])
785 titles.append(title)
786 #p.set_axes('title',title)
787 p.legend()
788 ymin=postcal[2*i][edge:nchan-edge].min()
789 ymax=postcal[2*i][edge:nchan-edge].max()
790 p.plot(postcal[2*i])
791 p.axes.set_ylim(ymin-0.1*abs(ymin),ymax+0.1*abs(ymax))
792 if not btics[3*i+1]:
793 p.axes.set_xticks([])
794 p.subplot(3*i+2)
795 p.color=0
796 title='ref data IF%s POL%s' % (ifnos[2*int(i/len(polnos))+1],polnos[i%len(polnos)])
797 titles.append(title)
798 #p.set_axes('title',title)
799 p.legend()
800 ymin=postcal[2*i+1][edge:nchan-edge].min()
801 ymax=postcal[2*i+1][edge:nchan-edge].max()
802 p.plot(postcal[2*i+1])
803 p.axes.set_ylim(ymin-0.1*abs(ymin),ymax+0.1*abs(ymax))
804 if not btics[3*i+2]:
805 p.axes.set_xticks([])
806 for i in range(3*nr):
807 p.subplot(i)
808 p.set_axes('title',titles[i],fontsize='medium')
809 x=raw_input('Accept calibration ([y]/n): ' )
810 if x.upper() == 'N':
811 p.quit()
812 del p
813 return scabtab
814 p.quit()
815 del p
816 ###
817 resspec._add_history("calfs",varlist)
818 return resspec
819
820@asaplog_post_dec
821def merge(*args):
822 """
823 Merge a list of scanatables, or comma-sperated scantables into one
824 scnatble.
825 Parameters:
826 A list [scan1, scan2] or scan1, scan2.
827 Example:
828 myscans = [scan1, scan2]
829 allscans = merge(myscans)
830 # or equivalent
831 sameallscans = merge(scan1, scan2)
832 """
833 varlist = vars()
834 if isinstance(args[0],list):
835 lst = tuple(args[0])
836 elif isinstance(args[0],tuple):
837 lst = args[0]
838 else:
839 lst = tuple(args)
840 varlist["args"] = "%d scantables" % len(lst)
841 # need special formatting her for history...
842 from asap._asap import stmath
843 stm = stmath()
844 for s in lst:
845 if not isinstance(s,scantable):
846 msg = "Please give a list of scantables"
847 raise TypeError(msg)
848 s = scantable(stm._merge(lst))
849 s._add_history("merge", varlist)
850 return s
851
852@asaplog_post_dec
853def calibrate( scantab, scannos=[], calmode='none', verify=None ):
854 """
855 Calibrate data.
856
857 Parameters:
858 scantab: scantable
859 scannos: list of scan number
860 calmode: calibration mode
861 verify: verify calibration
862 """
863 import re
864 antname = scantab.get_antennaname()
865 if ( calmode == 'nod' ):
866 asaplog.push( 'Calibrating nod data.' )
867 scal = calnod( scantab, scannos=scannos, verify=verify )
868 elif ( calmode == 'quotient' ):
869 asaplog.push( 'Calibrating using quotient.' )
870 scal = scantab.auto_quotient( verify=verify )
871 elif ( calmode == 'ps' ):
872 asaplog.push( 'Calibrating %s position-switched data.' % antname )
873 if ( antname.find( 'APEX' ) != -1 ):
874 scal = apexcal( scantab, scannos, calmode, verify )
875 elif ( antname.find( 'ALMA' ) != -1 or antname.find( 'OSF' ) != -1
876 or re.match('DV[0-9][0-9]$',antname) is not None
877 or re.match('PM[0-9][0-9]$',antname) is not None
878 or re.match('CM[0-9][0-9]$',antname) is not None
879 or re.match('DA[0-9][0-9]$',antname) is not None ):
880 scal = almacal( scantab, scannos, calmode, verify )
881 else:
882 scal = calps( scantab, scannos=scannos, verify=verify )
883 elif ( calmode == 'fs' or calmode == 'fsotf' ):
884 asaplog.push( 'Calibrating %s frequency-switched data.' % antname )
885 if ( antname.find( 'APEX' ) != -1 ):
886 scal = apexcal( scantab, scannos, calmode, verify )
887 elif ( antname.find( 'ALMA' ) != -1 or antname.find( 'OSF' ) != -1 ):
888 scal = almacal( scantab, scannos, calmode, verify )
889 else:
890 scal = calfs( scantab, scannos=scannos, verify=verify )
891 elif ( calmode == 'otf' ):
892 asaplog.push( 'Calibrating %s On-The-Fly data.' % antname )
893 scal = almacal( scantab, scannos, calmode, verify )
894 else:
895 asaplog.push( 'No calibration.' )
896 scal = scantab.copy()
897
898 return scal
899
900def apexcal( scantab, scannos=[], calmode='none', verify=False ):
901 """
902 Calibrate APEX data
903
904 Parameters:
905 scantab: scantable
906 scannos: list of scan number
907 calmode: calibration mode
908
909 verify: verify calibration
910 """
911 from asap._asap import stmath
912 stm = stmath()
913 antname = scantab.get_antennaname()
914 ssub = scantab.get_scan( scannos )
915 scal = scantable( stm.cwcal( ssub, calmode, antname ) )
916 return scal
917
918def almacal( scantab, scannos=[], calmode='none', verify=False ):
919 """
920 Calibrate ALMA data
921
922 Parameters:
923 scantab: scantable
924 scannos: list of scan number
925 calmode: calibration mode
926
927 verify: verify calibration
928 """
929 from asap._asap import stmath
930 stm = stmath()
931 ssub = scantab.get_scan( scannos )
932 scal = scantable( stm.almacal( ssub, calmode ) )
933 return scal
934
935@asaplog_post_dec
936def splitant(filename, outprefix='',overwrite=False):
937 """
938 Split Measurement set by antenna name, save data as a scantables,
939 and return a list of filename.
940 Notice this method can only be available from CASA.
941 Prameter
942 filename: the name of Measurement set to be read.
943 outprefix: the prefix of output scantable name.
944 the names of output scantable will be
945 outprefix.antenna1, outprefix.antenna2, ....
946 If not specified, outprefix = filename is assumed.
947 overwrite If the file should be overwritten if it exists.
948 The default False is to return with warning
949 without writing the output. USE WITH CARE.
950
951 """
952 # Import the table toolkit from CASA
953 import casac
954 from asap.scantable import is_ms
955 tbtool = casac.homefinder.find_home_by_name('tableHome')
956 tb = tbtool.create()
957 # Check the input filename
958 if isinstance(filename, str):
959 import os.path
960 filename = os.path.expandvars(filename)
961 filename = os.path.expanduser(filename)
962 if not os.path.exists(filename):
963 s = "File '%s' not found." % (filename)
964 raise IOError(s)
965 # check if input file is MS
966 #if not os.path.isdir(filename) \
967 # or not os.path.exists(filename+'/ANTENNA') \
968 # or not os.path.exists(filename+'/table.f1'):
969 if not is_ms(filename):
970 s = "File '%s' is not a Measurement set." % (filename)
971 raise IOError(s)
972 else:
973 s = "The filename should be string. "
974 raise TypeError(s)
975 # Check out put file name
976 outname=''
977 if len(outprefix) > 0: prefix=outprefix+'.'
978 else:
979 prefix=filename.rstrip('/')
980 # Now do the actual splitting.
981 outfiles=[]
982 tb.open(tablename=filename,nomodify=True)
983 ant1=tb.getcol('ANTENNA1',0,-1,1)
984 #anttab=tb.getkeyword('ANTENNA').split()[-1]
985 anttab=tb.getkeyword('ANTENNA').lstrip('Table: ')
986 tb.close()
987 #tb.open(tablename=filename+'/ANTENNA',nomodify=True)
988 tb.open(tablename=anttab,nomodify=True)
989 nant=tb.nrows()
990 antnames=tb.getcol('NAME',0,nant,1)
991 tb.close()
992 tmpname='asapmath.splitant.tmp'
993 for antid in set(ant1):
994 tb.open(tablename=filename,nomodify=True)
995 tbsel=tb.query('ANTENNA1 == %s && ANTENNA2 == %s'%(antid,antid),tmpname)
996 scan=scantable(tmpname,average=False,getpt=True,antenna=int(antid))
997 outname=prefix+antnames[antid]+'.asap'
998 scan.save(outname,format='ASAP',overwrite=overwrite)
999 tbsel.close()
1000 tb.close()
1001 del tbsel
1002 del scan
1003 outfiles.append(outname)
1004 os.system('rm -rf '+tmpname)
1005 del tb
1006 return outfiles
1007
1008@asaplog_post_dec
1009def _array2dOp( scan, value, mode="ADD", tsys=False, insitu=None):
1010 """
1011 This function is workaround on the basic operation of scantable
1012 with 2 dimensional float list.
1013
1014 scan: scantable operand
1015 value: float list operand
1016 mode: operation mode (ADD, SUB, MUL, DIV)
1017 tsys: if True, operate tsys as well
1018 insitu: if False, a new scantable is returned.
1019 Otherwise, the array operation is done in-sitsu.
1020 """
1021 nrow = scan.nrow()
1022 s = None
1023 from asap._asap import stmath
1024 stm = stmath()
1025 stm._setinsitu(insitu)
1026 if len( value ) == 1:
1027 s = scantable( stm._arrayop( scan, value[0], mode, tsys ) )
1028 elif len( value ) != nrow:
1029 raise ValueError( 'len(value) must be 1 or conform to scan.nrow()' )
1030 else:
1031 from asap._asap import stmath
1032 if not insitu:
1033 s = scan.copy()
1034 else:
1035 s = scan
1036 # insitu must be True as we go row by row on the same data
1037 stm._setinsitu( True )
1038 basesel = s.get_selection()
1039 # generate a new selector object based on basesel
1040 sel = selector(basesel)
1041 for irow in range( nrow ):
1042 sel.set_rows( irow )
1043 s.set_selection( sel )
1044 if len( value[irow] ) == 1:
1045 stm._unaryop( s, value[irow][0], mode, tsys )
1046 else:
1047 #stm._arrayop( s, value[irow], mode, tsys, 'channel' )
1048 stm._arrayop( s, value[irow], mode, tsys )
1049 s.set_selection(basesel)
1050 return s
Note: See TracBrowser for help on using the repository browser.