source: trunk/python/asapmath.py@ 2902

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

New Development: No

JIRA Issue: Yes CAS-5875

Ready for Test: Yes

Interface Changes: No

What Interface Changed: Please list interface changes

Test Programs: test_sdcoadd

Put in Release Notes: No

Module(s): sd

Description: Describe your changes here...

Added freq_tol parameter to asapmath.merge.
The freq_tol allows to specify frequency tolerance as
numeric value (1.0e6) or string ('1MHz'). The value will
be used to merge FREQUENCIES rows, FREQ_ID, and IFNO.


  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 37.6 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.asapplotter import new_asaplot
6from matplotlib import rc as rcp
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,
93 weight.upper(), scanav))
94 s._add_history("average_time",varlist)
95
96 return s
97
98@asaplog_post_dec
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
120
121@asaplog_post_dec
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
139@asaplog_post_dec
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
159@asaplog_post_dec
160def calps(scantab, scannos, smooth=1, tsysval=0.0, tauval=0.0, tcalval=0.0, verify=False):
161 """
162 Calibrate GBT position switched data
163 Adopted from GBTIDL getps
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
167 enum of poncal and poffcal need to be present.
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)
179 verify: Verify calibration if true
180 """
181 varlist = vars()
182 # check for the appropriate data
183## s = scantab.get_scan('*_ps*')
184## if s is None:
185## msg = "The input data appear to contain no position-switch mode data."
186## raise TypeError(msg)
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:
194 msg = "The input data appear to contain no position-switch mode data."
195 raise TypeError(msg)
196 s.set_selection()
197 sel.reset()
198 ssub = s.get_scan(scannos)
199 if ssub is None:
200 msg = "No data was found with given scan numbers!"
201 raise TypeError(msg)
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()
214 if ssubon.nrow() != ssuboff.nrow():
215 msg = "mismatch in numbers of CAL on/off scans. Cannot calibrate. Check the scan numbers."
216 raise TypeError(msg)
217 cals = dototalpower(ssubon, ssuboff, tcalval)
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()
230 if sig.nscan() != ref.nscan():
231 msg = "mismatch in numbers of on/off scans. Cannot calibrate. Check the scan numbers."
232 raise TypeError(msg)
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"
238 raise TypeError(msg)
239 else:
240 sig.recalc_azel()
241 ref.recalc_azel()
242 #msg = "Use of user specified Tsys is not fully implemented yet."
243 #raise TypeError(msg)
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)
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
311 asaplog.post()
312 asaplog.push('Plot only first spectrum for each [if,pol] pairs to verify calibration.')
313 asaplog.post('WARN')
314 p=new_asaplot()
315 rcp('lines', linewidth=1)
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:
341 asaplog.post()
342 asaplog.push('Only first 6 [if,pol] pairs are plotted.')
343 asaplog.post('WARN')
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
359 nchan=s.nchan(ifnos[int(i/len(polnos))])
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':
392 p.quit()
393 del p
394 return scantab
395 p.quit()
396 del p
397 ###
398 ress._add_history("calps", varlist)
399 return ress
400
401@asaplog_post_dec
402def calnod(scantab, scannos=[], smooth=1, tsysval=0.0, tauval=0.0, tcalval=0.0, verify=False):
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
414 verify: Verify calibration if true
415 """
416 varlist = vars()
417 from asap._asap import stmath
418 from asap._asap import srctype
419 stm = stmath()
420 stm._setinsitu(False)
421
422 # check for the appropriate data
423## s = scantab.get_scan('*_nod*')
424## if s is None:
425## msg = "The input data appear to contain no Nod observing mode data."
426## raise TypeError(msg)
427 s = scantab.copy()
428 sel = selector()
429 sel.set_types( srctype.nod )
430 try:
431 s.set_selection( sel )
432 except Exception, e:
433 msg = "The input data appear to contain no Nod observing mode data."
434 raise TypeError(msg)
435 sel.reset()
436 del sel
437 del s
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."
456 # raise TypeError(msg)
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"
466 raise TypeError(msg)
467 else:
468 scantab.recalc_azel()
469 resspec = scantable(stm._donod(scantab, pairScans, smooth, tsysval,tauval,tcalval))
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
531 asaplog.post()
532 asaplog.push('Plot only first spectrum for each [if,pol] pairs to verify calibration.')
533 asaplog.post('WARN')
534 p=new_asaplot()
535 rcp('lines', linewidth=1)
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:
561 asaplog.post()
562 asaplog.push('Only first 6 [if,pol] pairs are plotted.')
563 asaplog.post('WARN')
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
579 nchan=scantab.nchan(ifnos[int(i/len(polnos))])
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':
612 p.quit()
613 del p
614 return scantab
615 p.quit()
616 del p
617 ###
618 resspec._add_history("calnod",varlist)
619 return resspec
620
621@asaplog_post_dec
622def calfs(scantab, scannos=[], smooth=1, tsysval=0.0, tauval=0.0, tcalval=0.0, verify=False):
623 """
624 Calibrate GBT frequency switched data.
625 Adopted from GBTIDL getfs.
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
629 enum of foncal and foffcal need to be present.
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
639 verify: Verify calibration if true
640 """
641 varlist = vars()
642 from asap._asap import stmath
643 from asap._asap import srctype
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."
650# raise TypeError(msg)
651 s = scantab.get_scan(scannos)
652 del scantab
653
654 resspec = scantable(stm._dofs(s, scannos, smooth, tsysval,tauval,tcalval))
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
742 asaplog.post()
743 asaplog.push('Plot only first spectrum for each [if,pol] pairs to verify calibration.')
744 asaplog.post('WARN')
745 p=new_asaplot()
746 rcp('lines', linewidth=1)
747 #nr=min(6,len(ifnos)*len(polnos))
748 nr=len(ifnos)/2*len(polnos)
749 titles=[]
750 btics=[]
751 if nr>3:
752 asaplog.post()
753 asaplog.push('Only first 3 [if,pol] pairs are plotted.')
754 asaplog.post('WARN')
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
770 nchan=s.nchan(ifnos[2*int(i/len(polnos))])
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':
815 p.quit()
816 del p
817 return scantab
818 p.quit()
819 del p
820 ###
821 resspec._add_history("calfs",varlist)
822 return resspec
823
824@asaplog_post_dec
825def merge(*args, **kwargs):
826 """
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 freq_tol: frequency tolerance for merging IFs. numeric values
832 in units of Hz (1.0e6 -> 1MHz) and string ('1MHz')
833 is allowed.
834 Example:
835 myscans = [scan1, scan2]
836 allscans = merge(myscans)
837 # or equivalent
838 sameallscans = merge(scan1, scan2)
839 # with freqtol
840 allscans = merge(scan1, scan2, freq_tol=1.0e6)
841 # or equivalently
842 allscans = merge(scan1, scan2, freq_tol='1MHz')
843 """
844 varlist = vars()
845 if isinstance(args[0],list):
846 lst = tuple(args[0])
847 elif isinstance(args[0],tuple):
848 lst = args[0]
849 else:
850 lst = tuple(args)
851 if kwargs.has_key('freq_tol'):
852 freq_tol = str(kwargs['freq_tol'])
853 else:
854 freq_tol = ''
855 varlist["args"] = "%d scantables" % len(lst)
856 # need special formatting her for history...
857 from asap._asap import stmath
858 stm = stmath()
859 for s in lst:
860 if not isinstance(s,scantable):
861 msg = "Please give a list of scantables"
862 raise TypeError(msg)
863 s = scantable(stm._merge(lst, freq_tol))
864 s._add_history("merge", varlist)
865 return s
866
867@asaplog_post_dec
868def calibrate( scantab, scannos=[], calmode='none', verify=None ):
869 """
870 Calibrate data.
871
872 Parameters:
873 scantab: scantable
874 scannos: list of scan number
875 calmode: calibration mode
876 verify: verify calibration
877 """
878 import re
879 antname = scantab.get_antennaname()
880 if ( calmode == 'nod' ):
881 asaplog.push( 'Calibrating nod data.' )
882 scal = calnod( scantab, scannos=scannos, verify=verify )
883 elif ( calmode == 'quotient' ):
884 asaplog.push( 'Calibrating using quotient.' )
885 scal = scantab.auto_quotient( verify=verify )
886 elif ( calmode == 'ps' ):
887 asaplog.push( 'Calibrating %s position-switched data.' % antname )
888 if ( antname.find( 'APEX' ) != -1 ):
889 scal = apexcal( scantab, scannos, calmode, verify )
890 elif ( antname.find( 'ALMA' ) != -1 or antname.find( 'OSF' ) != -1
891 or re.match('DV[0-9][0-9]$',antname) is not None
892 or re.match('PM[0-9][0-9]$',antname) is not None
893 or re.match('CM[0-9][0-9]$',antname) is not None
894 or re.match('DA[0-9][0-9]$',antname) is not None ):
895 scal = almacal( scantab, scannos, calmode, verify )
896 else:
897 scal = calps( scantab, scannos=scannos, verify=verify )
898 elif ( calmode == 'fs' or calmode == 'fsotf' ):
899 asaplog.push( 'Calibrating %s frequency-switched data.' % antname )
900 if ( antname.find( 'APEX' ) != -1 ):
901 scal = apexcal( scantab, scannos, calmode, verify )
902 elif ( antname.find( 'ALMA' ) != -1 or antname.find( 'OSF' ) != -1 ):
903 scal = almacal( scantab, scannos, calmode, verify )
904 else:
905 scal = calfs( scantab, scannos=scannos, verify=verify )
906 elif ( calmode == 'otf' ):
907 asaplog.push( 'Calibrating %s On-The-Fly data.' % antname )
908 scal = almacal( scantab, scannos, calmode, verify )
909 else:
910 asaplog.push( 'No calibration.' )
911 scal = scantab.copy()
912
913 return scal
914
915def apexcal( scantab, scannos=[], calmode='none', verify=False ):
916 """
917 Calibrate APEX data
918
919 Parameters:
920 scantab: scantable
921 scannos: list of scan number
922 calmode: calibration mode
923
924 verify: verify calibration
925 """
926 from asap._asap import stmath
927 stm = stmath()
928 antname = scantab.get_antennaname()
929 selection=selector()
930 selection.set_scans(scannos)
931 orig = scantab.get_selection()
932 scantab.set_selection(orig+selection)
933## ssub = scantab.get_scan( scannos )
934## scal = scantable( stm.cwcal( ssub, calmode, antname ) )
935 scal = scantable( stm.cwcal( scantab, calmode, antname ) )
936 scantab.set_selection(orig)
937 return scal
938
939def almacal( scantab, scannos=[], calmode='none', verify=False ):
940 """
941 Calibrate ALMA data
942
943 Parameters:
944 scantab: scantable
945 scannos: list of scan number
946 calmode: calibration mode
947
948 verify: verify calibration
949 """
950 from asap._asap import stmath
951 stm = stmath()
952 selection=selector()
953 selection.set_scans(scannos)
954 orig = scantab.get_selection()
955 scantab.set_selection(orig+selection)
956## ssub = scantab.get_scan( scannos )
957## scal = scantable( stm.almacal( ssub, calmode ) )
958 scal = scantable( stm.almacal( scantab, calmode ) )
959 scantab.set_selection(orig)
960 return scal
961
962@asaplog_post_dec
963def splitant(filename, outprefix='',overwrite=False, getpt=True):
964 """
965 Split Measurement set by antenna name, save data as a scantables,
966 and return a list of filename. Note that frequency reference frame
967 is imported as it is in Measurement set.
968 Notice this method can only be available from CASA.
969 Prameter
970 filename: the name of Measurement set to be read.
971 outprefix: the prefix of output scantable name.
972 the names of output scantable will be
973 outprefix.antenna1, outprefix.antenna2, ....
974 If not specified, outprefix = filename is assumed.
975 overwrite If the file should be overwritten if it exists.
976 The default False is to return with warning
977 without writing the output. USE WITH CARE.
978 getpt Whether to import direction from MS/POINTING
979 table or not. Default is True (import direction).
980 """
981 # Import the table toolkit from CASA
982 from taskinit import gentools
983 from asap.scantable import is_ms
984 tb = gentools(['tb'])[0]
985 # Check the input filename
986 if isinstance(filename, str):
987 import os.path
988 filename = os.path.expandvars(filename)
989 filename = os.path.expanduser(filename)
990 if not os.path.exists(filename):
991 s = "File '%s' not found." % (filename)
992 raise IOError(s)
993 # check if input file is MS
994 if not is_ms(filename):
995 s = "File '%s' is not a Measurement set." % (filename)
996 raise IOError(s)
997 else:
998 s = "The filename should be string. "
999 raise TypeError(s)
1000 # Check out put file name
1001 outname=''
1002 if len(outprefix) > 0: prefix=outprefix+'.'
1003 else:
1004 prefix=filename.rstrip('/')
1005 # Now do the actual splitting.
1006 outfiles=[]
1007 tb.open(tablename=filename,nomodify=True)
1008 ant1=tb.getcol('ANTENNA1',0,-1,1)
1009 anttab=tb.getkeyword('ANTENNA').lstrip('Table: ')
1010 tb.close()
1011 tb.open(tablename=anttab,nomodify=True)
1012 nant=tb.nrows()
1013 antnames=tb.getcol('NAME',0,nant,1)
1014 tb.close()
1015 for antid in set(ant1):
1016 scan=scantable(filename,average=False,antenna=int(antid),getpt=getpt)
1017 outname=prefix+antnames[antid]+'.asap'
1018 scan.save(outname,format='ASAP',overwrite=overwrite)
1019 del scan
1020 outfiles.append(outname)
1021 return outfiles
1022
1023@asaplog_post_dec
1024def _array2dOp( scan, value, mode="ADD", tsys=False, insitu=None):
1025 """
1026 This function is workaround on the basic operation of scantable
1027 with 2 dimensional float list.
1028
1029 scan: scantable operand
1030 value: float list operand
1031 mode: operation mode (ADD, SUB, MUL, DIV)
1032 tsys: if True, operate tsys as well
1033 insitu: if False, a new scantable is returned.
1034 Otherwise, the array operation is done in-sitsu.
1035 """
1036 if insitu is None: insitu = rcParams['insitu']
1037 nrow = scan.nrow()
1038 s = None
1039 from asap._asap import stmath
1040 stm = stmath()
1041 stm._setinsitu(insitu)
1042 if len( value ) == 1:
1043 s = scantable( stm._arrayop( scan, value[0], mode, tsys ) )
1044 elif len( value ) != nrow:
1045 raise ValueError( 'len(value) must be 1 or conform to scan.nrow()' )
1046 else:
1047 from asap._asap import stmath
1048 if not insitu:
1049 s = scan.copy()
1050 else:
1051 s = scan
1052 # insitu must be True as we go row by row on the same data
1053 stm._setinsitu( True )
1054 basesel = s.get_selection()
1055 # generate a new selector object based on basesel
1056 sel = selector(basesel)
1057 for irow in range( nrow ):
1058 sel.set_rows( irow )
1059 s.set_selection( sel )
1060 if len( value[irow] ) == 1:
1061 stm._unaryop( s, value[irow][0], mode, tsys )
1062 else:
1063 #stm._arrayop( s, value[irow], mode, tsys, 'channel' )
1064 stm._arrayop( s, value[irow], mode, tsys )
1065 s.set_selection(basesel)
1066 return s
Note: See TracBrowser for help on using the repository browser.