source: trunk/python/asapmath.py@ 2464

Last change on this file since 2464 was 2451, checked in by Kana Sugimoto, 12 years ago

New Development: No

JIRA Issue: Yes (CAS-3749)

Ready for Test: Yes

Interface Changes: No

What Interface Changed:

Test Programs: unit tests of sdplot

Put in Release Notes: No

Module(s): sdplot, sdfit, sdstat, sdflag, sdcal, sdreduce

Description:

Made asapplotter not to generate plotter window at start-up, but the window is
only generated at the first invokation of plotting operation.


  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 37.1 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 Example:
29 # return a time averaged scan from scana and scanb
30 # without using a mask
31 scanav = average_time(scana,scanb)
32 # or equivalent
33 # scanav = average_time([scana, scanb])
34 # return the (time) averaged scan, i.e. the average of
35 # all correlator cycles
36 scanav = average_time(scan, scanav=True)
37 """
38 scanav = False
39 if kwargs.has_key('scanav'):
40 scanav = kwargs.get('scanav')
41 weight = 'tint'
42 if kwargs.has_key('weight'):
43 weight = kwargs.get('weight')
44 mask = ()
45 if kwargs.has_key('mask'):
46 mask = kwargs.get('mask')
47 align = False
48 if kwargs.has_key('align'):
49 align = kwargs.get('align')
50 compel = False
51 if kwargs.has_key('compel'):
52 compel = kwargs.get('compel')
53 varlist = vars()
54 if isinstance(args[0],list):
55 lst = args[0]
56 elif isinstance(args[0],tuple):
57 lst = list(args[0])
58 else:
59 lst = list(args)
60
61 del varlist["kwargs"]
62 varlist["args"] = "%d scantables" % len(lst)
63 # need special formatting here for history...
64
65 from asap._asap import stmath
66 stm = stmath()
67 for s in lst:
68 if not isinstance(s,scantable):
69 msg = "Please give a list of scantables"
70 raise TypeError(msg)
71 if scanav: scanav = "SCAN"
72 else: scanav = "NONE"
73 alignedlst = []
74 if align:
75 refepoch = lst[0].get_time(0)
76 for scan in lst:
77 alignedlst.append(scan.freq_align(refepoch,insitu=False))
78 else:
79 alignedlst = lst
80 if weight.upper() == 'MEDIAN':
81 # median doesn't support list of scantables - merge first
82 merged = None
83 if len(alignedlst) > 1:
84 merged = merge(alignedlst)
85 else:
86 merged = alignedlst[0]
87 s = scantable(stm._averagechannel(merged, 'MEDIAN', scanav))
88 del merged
89 else:
90 #s = scantable(stm._average(alignedlst, mask, weight.upper(), scanav))
91 s = scantable(stm._new_average(alignedlst, compel, mask, weight.upper(), scanav))
92 s._add_history("average_time",varlist)
93
94 return s
95
96@asaplog_post_dec
97def quotient(source, reference, preserve=True):
98 """
99 Return the quotient of a 'source' (signal) scan and a 'reference' scan.
100 The reference can have just one scan, even if the signal has many. Otherwise
101 they must have the same number of scans.
102 The cursor of the output scan is set to 0
103 Parameters:
104 source: the 'on' scan
105 reference: the 'off' scan
106 preserve: you can preserve (default) the continuum or
107 remove it. The equations used are
108 preserve: Output = Toff * (on/off) - Toff
109 remove: Output = Toff * (on/off) - Ton
110 """
111 varlist = vars()
112 from asap._asap import stmath
113 stm = stmath()
114 stm._setinsitu(False)
115 s = scantable(stm._quotient(source, reference, preserve))
116 s._add_history("quotient",varlist)
117 return s
118
119@asaplog_post_dec
120def dototalpower(calon, caloff, tcalval=0.0):
121 """
122 Do calibration for CAL on,off signals.
123 Adopted from GBTIDL dototalpower
124 Parameters:
125 calon: the 'cal on' subintegration
126 caloff: the 'cal off' subintegration
127 tcalval: user supplied Tcal value
128 """
129 varlist = vars()
130 from asap._asap import stmath
131 stm = stmath()
132 stm._setinsitu(False)
133 s = scantable(stm._dototalpower(calon, caloff, tcalval))
134 s._add_history("dototalpower",varlist)
135 return s
136
137@asaplog_post_dec
138def dosigref(sig, ref, smooth, tsysval=0.0, tauval=0.0):
139 """
140 Calculate a quotient (sig-ref/ref * Tsys)
141 Adopted from GBTIDL dosigref
142 Parameters:
143 sig: on source data
144 ref: reference data
145 smooth: width of box car smoothing for reference
146 tsysval: user specified Tsys (scalar only)
147 tauval: user specified Tau (required if tsysval is set)
148 """
149 varlist = vars()
150 from asap._asap import stmath
151 stm = stmath()
152 stm._setinsitu(False)
153 s = scantable(stm._dosigref(sig, ref, smooth, tsysval, tauval))
154 s._add_history("dosigref",varlist)
155 return s
156
157@asaplog_post_dec
158def calps(scantab, scannos, smooth=1, tsysval=0.0, tauval=0.0, tcalval=0.0, verify=False):
159 """
160 Calibrate GBT position switched data
161 Adopted from GBTIDL getps
162 Currently calps identify the scans as position switched data if source
163 type enum is pson or psoff. The data must contains 'CAL' signal
164 on/off in each integration. To identify 'CAL' on state, the source type
165 enum of poncal and poffcal need to be present in the source name field.
166 (GBT MS data reading process to scantable automatically append these
167 id names to the source names)
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 #nr=min(6,len(ifnos)*len(polnos))
316 nr=len(ifnos)*len(polnos)
317 titles=[]
318 btics=[]
319 if nr<4:
320 p.set_panels(rows=nr,cols=2,nplots=2*nr,ganged=False)
321 for i in range(2*nr):
322 b=False
323 if i >= 2*nr-2:
324 b=True
325 btics.append(b)
326 elif nr==4:
327 p.set_panels(rows=2,cols=4,nplots=8,ganged=False)
328 for i in range(2*nr):
329 b=False
330 if i >= 2*nr-4:
331 b=True
332 btics.append(b)
333 elif nr<7:
334 p.set_panels(rows=3,cols=4,nplots=2*nr,ganged=False)
335 for i in range(2*nr):
336 if i >= 2*nr-4:
337 b=True
338 btics.append(b)
339 else:
340 asaplog.post()
341 asaplog.push('Only first 6 [if,pol] pairs are plotted.')
342 asaplog.post('WARN')
343 nr=6
344 for i in range(2*nr):
345 b=False
346 if i >= 2*nr-4:
347 b=True
348 btics.append(b)
349 p.set_panels(rows=3,cols=4,nplots=2*nr,ganged=False)
350 for i in range(nr):
351 p.subplot(2*i)
352 p.color=0
353 title='raw data IF%s POL%s' % (ifnos[int(i/len(polnos))],polnos[i%len(polnos)])
354 titles.append(title)
355 #p.set_axes('title',title,fontsize=40)
356 ymin=1.0e100
357 ymax=-1.0e100
358 nchan=s.nchan(ifnos[int(i/len(polnos))])
359 edge=int(nchan*0.01)
360 for j in range(4):
361 spmin=min(precal[keys[j]][i][edge:nchan-edge])
362 spmax=max(precal[keys[j]][i][edge:nchan-edge])
363 ymin=min(ymin,spmin)
364 ymax=max(ymax,spmax)
365 for j in range(4):
366 if i==0:
367 p.set_line(label=keys[j])
368 else:
369 p.legend()
370 p.plot(precal[keys[j]][i])
371 p.axes.set_ylim(ymin-0.1*abs(ymin),ymax+0.1*abs(ymax))
372 if not btics[2*i]:
373 p.axes.set_xticks([])
374 p.subplot(2*i+1)
375 p.color=0
376 title='cal data IF%s POL%s' % (ifnos[int(i/len(polnos))],polnos[i%len(polnos)])
377 titles.append(title)
378 #p.set_axes('title',title)
379 p.legend()
380 ymin=postcal[i][edge:nchan-edge].min()
381 ymax=postcal[i][edge:nchan-edge].max()
382 p.plot(postcal[i])
383 p.axes.set_ylim(ymin-0.1*abs(ymin),ymax+0.1*abs(ymax))
384 if not btics[2*i+1]:
385 p.axes.set_xticks([])
386 for i in range(2*nr):
387 p.subplot(i)
388 p.set_axes('title',titles[i],fontsize='medium')
389 x=raw_input('Accept calibration ([y]/n): ' )
390 if x.upper() == 'N':
391 p.quit()
392 del p
393 return scabtab
394 p.quit()
395 del p
396 ###
397 ress._add_history("calps", varlist)
398 return ress
399
400@asaplog_post_dec
401def calnod(scantab, scannos=[], smooth=1, tsysval=0.0, tauval=0.0, tcalval=0.0, verify=False):
402 """
403 Do full (but a pair of scans at time) processing of GBT Nod data
404 calibration.
405 Adopted from GBTIDL's getnod
406 Parameters:
407 scantab: scantable
408 scannos: a pair of scan numbers, or the first scan number of the pair
409 smooth: box car smoothing order
410 tsysval: optional user specified Tsys value
411 tauval: optional user specified tau value (not implemented yet)
412 tcalval: optional user specified Tcal value
413 verify: Verify calibration if true
414 """
415 varlist = vars()
416 from asap._asap import stmath
417 from asap._asap import srctype
418 stm = stmath()
419 stm._setinsitu(False)
420
421 # check for the appropriate data
422## s = scantab.get_scan('*_nod*')
423## if s is None:
424## msg = "The input data appear to contain no Nod observing mode data."
425## raise TypeError(msg)
426 s = scantab.copy()
427 sel = selector()
428 sel.set_types( srctype.nod )
429 try:
430 s.set_selection( sel )
431 except Exception, e:
432 msg = "The input data appear to contain no Nod observing mode data."
433 raise TypeError(msg)
434 sel.reset()
435 del sel
436 del s
437
438 # need check correspondance of each beam with sig-ref ...
439 # check for timestamps, scan numbers, subscan id (not available in
440 # ASAP data format...). Assume 1st scan of the pair (beam 0 - sig
441 # and beam 1 - ref...)
442 # First scan number of paired scans or list of pairs of
443 # scan numbers (has to have even number of pairs.)
444
445 #data splitting
446 scan1no = scan2no = 0
447
448 if len(scannos)==1:
449 scan1no = scannos[0]
450 scan2no = scannos[0]+1
451 pairScans = [scan1no, scan2no]
452 else:
453 #if len(scannos)>2:
454 # msg = "calnod can only process a pair of nod scans at time."
455 # raise TypeError(msg)
456 #
457 #if len(scannos)==2:
458 # scan1no = scannos[0]
459 # scan2no = scannos[1]
460 pairScans = list(scannos)
461
462 if tsysval>0.0:
463 if tauval<=0.0:
464 msg = "Need to supply a valid tau to use the supplied Tsys"
465 raise TypeError(msg)
466 else:
467 scantab.recalc_azel()
468 resspec = scantable(stm._donod(scantab, pairScans, smooth, tsysval,tauval,tcalval))
469 ###
470 if verify:
471 # get data
472 import numpy
473 precal={}
474 postcal=[]
475 keys=['','_calon']
476 types=[srctype.nod,srctype.nodcal]
477 ifnos=list(scantab.getifnos())
478 polnos=list(scantab.getpolnos())
479 sel=selector()
480 ss = scantab.copy()
481 for i in range(2):
482 #ss=scantab.get_scan('*'+keys[i])
483 ll=[]
484 ll2=[]
485 for j in range(len(ifnos)):
486 for k in range(len(polnos)):
487 sel.set_ifs(ifnos[j])
488 sel.set_polarizations(polnos[k])
489 sel.set_scans(pairScans[0])
490 sel.set_types(types[i])
491 try:
492 ss.set_selection(sel)
493 except:
494 continue
495 ll.append(numpy.array(ss._getspectrum(0)))
496 sel.reset()
497 ss.set_selection()
498 sel.set_ifs(ifnos[j])
499 sel.set_polarizations(polnos[k])
500 sel.set_scans(pairScans[1])
501 sel.set_types(types[i])
502 try:
503 ss.set_selection(sel)
504 except:
505 ll.pop()
506 continue
507 ll2.append(numpy.array(ss._getspectrum(0)))
508 sel.reset()
509 ss.set_selection()
510 key='%s%s' %(pairScans[0],keys[i])
511 precal[key]=ll
512 key='%s%s' %(pairScans[1],keys[i])
513 precal[key]=ll2
514 #del ss
515 keys=precal.keys()
516 for j in range(len(ifnos)):
517 for k in range(len(polnos)):
518 sel.set_ifs(ifnos[j])
519 sel.set_polarizations(polnos[k])
520 sel.set_scans(pairScans[0])
521 try:
522 resspec.set_selection(sel)
523 except:
524 continue
525 postcal.append(numpy.array(resspec._getspectrum(0)))
526 sel.reset()
527 resspec.set_selection()
528 del sel
529 # plot
530 asaplog.post()
531 asaplog.push('Plot only first spectrum for each [if,pol] pairs to verify calibration.')
532 asaplog.post('WARN')
533 p=new_asaplot()
534 #nr=min(6,len(ifnos)*len(polnos))
535 nr=len(ifnos)*len(polnos)
536 titles=[]
537 btics=[]
538 if nr<4:
539 p.set_panels(rows=nr,cols=2,nplots=2*nr,ganged=False)
540 for i in range(2*nr):
541 b=False
542 if i >= 2*nr-2:
543 b=True
544 btics.append(b)
545 elif nr==4:
546 p.set_panels(rows=2,cols=4,nplots=8,ganged=False)
547 for i in range(2*nr):
548 b=False
549 if i >= 2*nr-4:
550 b=True
551 btics.append(b)
552 elif nr<7:
553 p.set_panels(rows=3,cols=4,nplots=2*nr,ganged=False)
554 for i in range(2*nr):
555 if i >= 2*nr-4:
556 b=True
557 btics.append(b)
558 else:
559 asaplog.post()
560 asaplog.push('Only first 6 [if,pol] pairs are plotted.')
561 asaplog.post('WARN')
562 nr=6
563 for i in range(2*nr):
564 b=False
565 if i >= 2*nr-4:
566 b=True
567 btics.append(b)
568 p.set_panels(rows=3,cols=4,nplots=2*nr,ganged=False)
569 for i in range(nr):
570 p.subplot(2*i)
571 p.color=0
572 title='raw data IF%s POL%s' % (ifnos[int(i/len(polnos))],polnos[i%len(polnos)])
573 titles.append(title)
574 #p.set_axes('title',title,fontsize=40)
575 ymin=1.0e100
576 ymax=-1.0e100
577 nchan=scantab.nchan(ifnos[int(i/len(polnos))])
578 edge=int(nchan*0.01)
579 for j in range(4):
580 spmin=min(precal[keys[j]][i][edge:nchan-edge])
581 spmax=max(precal[keys[j]][i][edge:nchan-edge])
582 ymin=min(ymin,spmin)
583 ymax=max(ymax,spmax)
584 for j in range(4):
585 if i==0:
586 p.set_line(label=keys[j])
587 else:
588 p.legend()
589 p.plot(precal[keys[j]][i])
590 p.axes.set_ylim(ymin-0.1*abs(ymin),ymax+0.1*abs(ymax))
591 if not btics[2*i]:
592 p.axes.set_xticks([])
593 p.subplot(2*i+1)
594 p.color=0
595 title='cal data IF%s POL%s' % (ifnos[int(i/len(polnos))],polnos[i%len(polnos)])
596 titles.append(title)
597 #p.set_axes('title',title)
598 p.legend()
599 ymin=postcal[i][edge:nchan-edge].min()
600 ymax=postcal[i][edge:nchan-edge].max()
601 p.plot(postcal[i])
602 p.axes.set_ylim(ymin-0.1*abs(ymin),ymax+0.1*abs(ymax))
603 if not btics[2*i+1]:
604 p.axes.set_xticks([])
605 for i in range(2*nr):
606 p.subplot(i)
607 p.set_axes('title',titles[i],fontsize='medium')
608 x=raw_input('Accept calibration ([y]/n): ' )
609 if x.upper() == 'N':
610 p.quit()
611 del p
612 return scabtab
613 p.quit()
614 del p
615 ###
616 resspec._add_history("calnod",varlist)
617 return resspec
618
619@asaplog_post_dec
620def calfs(scantab, scannos=[], smooth=1, tsysval=0.0, tauval=0.0, tcalval=0.0, verify=False):
621 """
622 Calibrate GBT frequency switched data.
623 Adopted from GBTIDL getfs.
624 Currently calfs identify the scans as frequency switched data if source
625 type enum is fson and fsoff. The data must contains 'CAL' signal
626 on/off in each integration. To identify 'CAL' on state, the source type
627 enum of foncal and foffcal need to be present in the source name field.
628 (GBT MS data reading via scantable automatically append these
629 id names to the source names)
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 #nr=min(6,len(ifnos)*len(polnos))
747 nr=len(ifnos)/2*len(polnos)
748 titles=[]
749 btics=[]
750 if nr>3:
751 asaplog.post()
752 asaplog.push('Only first 3 [if,pol] pairs are plotted.')
753 asaplog.post('WARN')
754 nr=3
755 p.set_panels(rows=nr,cols=3,nplots=3*nr,ganged=False)
756 for i in range(3*nr):
757 b=False
758 if i >= 3*nr-3:
759 b=True
760 btics.append(b)
761 for i in range(nr):
762 p.subplot(3*i)
763 p.color=0
764 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)])
765 titles.append(title)
766 #p.set_axes('title',title,fontsize=40)
767 ymin=1.0e100
768 ymax=-1.0e100
769 nchan=s.nchan(ifnos[2*int(i/len(polnos))])
770 edge=int(nchan*0.01)
771 for j in range(4):
772 spmin=min(precal[keys[j]][i][edge:nchan-edge])
773 spmax=max(precal[keys[j]][i][edge:nchan-edge])
774 ymin=min(ymin,spmin)
775 ymax=max(ymax,spmax)
776 for j in range(4):
777 if i==0:
778 p.set_line(label=keys[j])
779 else:
780 p.legend()
781 p.plot(precal[keys[j]][i])
782 p.axes.set_ylim(ymin-0.1*abs(ymin),ymax+0.1*abs(ymax))
783 if not btics[3*i]:
784 p.axes.set_xticks([])
785 p.subplot(3*i+1)
786 p.color=0
787 title='sig data IF%s POL%s' % (ifnos[2*int(i/len(polnos))],polnos[i%len(polnos)])
788 titles.append(title)
789 #p.set_axes('title',title)
790 p.legend()
791 ymin=postcal[2*i][edge:nchan-edge].min()
792 ymax=postcal[2*i][edge:nchan-edge].max()
793 p.plot(postcal[2*i])
794 p.axes.set_ylim(ymin-0.1*abs(ymin),ymax+0.1*abs(ymax))
795 if not btics[3*i+1]:
796 p.axes.set_xticks([])
797 p.subplot(3*i+2)
798 p.color=0
799 title='ref data IF%s POL%s' % (ifnos[2*int(i/len(polnos))+1],polnos[i%len(polnos)])
800 titles.append(title)
801 #p.set_axes('title',title)
802 p.legend()
803 ymin=postcal[2*i+1][edge:nchan-edge].min()
804 ymax=postcal[2*i+1][edge:nchan-edge].max()
805 p.plot(postcal[2*i+1])
806 p.axes.set_ylim(ymin-0.1*abs(ymin),ymax+0.1*abs(ymax))
807 if not btics[3*i+2]:
808 p.axes.set_xticks([])
809 for i in range(3*nr):
810 p.subplot(i)
811 p.set_axes('title',titles[i],fontsize='medium')
812 x=raw_input('Accept calibration ([y]/n): ' )
813 if x.upper() == 'N':
814 p.quit()
815 del p
816 return scabtab
817 p.quit()
818 del p
819 ###
820 resspec._add_history("calfs",varlist)
821 return resspec
822
823@asaplog_post_dec
824def merge(*args):
825 """
826 Merge a list of scanatables, or comma-sperated scantables into one
827 scnatble.
828 Parameters:
829 A list [scan1, scan2] or scan1, scan2.
830 Example:
831 myscans = [scan1, scan2]
832 allscans = merge(myscans)
833 # or equivalent
834 sameallscans = merge(scan1, scan2)
835 """
836 varlist = vars()
837 if isinstance(args[0],list):
838 lst = tuple(args[0])
839 elif isinstance(args[0],tuple):
840 lst = args[0]
841 else:
842 lst = tuple(args)
843 varlist["args"] = "%d scantables" % len(lst)
844 # need special formatting her for history...
845 from asap._asap import stmath
846 stm = stmath()
847 for s in lst:
848 if not isinstance(s,scantable):
849 msg = "Please give a list of scantables"
850 raise TypeError(msg)
851 s = scantable(stm._merge(lst))
852 s._add_history("merge", varlist)
853 return s
854
855@asaplog_post_dec
856def calibrate( scantab, scannos=[], calmode='none', verify=None ):
857 """
858 Calibrate data.
859
860 Parameters:
861 scantab: scantable
862 scannos: list of scan number
863 calmode: calibration mode
864 verify: verify calibration
865 """
866 import re
867 antname = scantab.get_antennaname()
868 if ( calmode == 'nod' ):
869 asaplog.push( 'Calibrating nod data.' )
870 scal = calnod( scantab, scannos=scannos, verify=verify )
871 elif ( calmode == 'quotient' ):
872 asaplog.push( 'Calibrating using quotient.' )
873 scal = scantab.auto_quotient( verify=verify )
874 elif ( calmode == 'ps' ):
875 asaplog.push( 'Calibrating %s position-switched data.' % antname )
876 if ( antname.find( 'APEX' ) != -1 ):
877 scal = apexcal( scantab, scannos, calmode, verify )
878 elif ( antname.find( 'ALMA' ) != -1 or antname.find( 'OSF' ) != -1
879 or re.match('DV[0-9][0-9]$',antname) is not None
880 or re.match('PM[0-9][0-9]$',antname) is not None
881 or re.match('CM[0-9][0-9]$',antname) is not None
882 or re.match('DA[0-9][0-9]$',antname) is not None ):
883 scal = almacal( scantab, scannos, calmode, verify )
884 else:
885 scal = calps( scantab, scannos=scannos, verify=verify )
886 elif ( calmode == 'fs' or calmode == 'fsotf' ):
887 asaplog.push( 'Calibrating %s frequency-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 scal = almacal( scantab, scannos, calmode, verify )
892 else:
893 scal = calfs( scantab, scannos=scannos, verify=verify )
894 elif ( calmode == 'otf' ):
895 asaplog.push( 'Calibrating %s On-The-Fly data.' % antname )
896 scal = almacal( scantab, scannos, calmode, verify )
897 else:
898 asaplog.push( 'No calibration.' )
899 scal = scantab.copy()
900
901 return scal
902
903def apexcal( scantab, scannos=[], calmode='none', verify=False ):
904 """
905 Calibrate APEX data
906
907 Parameters:
908 scantab: scantable
909 scannos: list of scan number
910 calmode: calibration mode
911
912 verify: verify calibration
913 """
914 from asap._asap import stmath
915 stm = stmath()
916 antname = scantab.get_antennaname()
917 ssub = scantab.get_scan( scannos )
918 scal = scantable( stm.cwcal( ssub, calmode, antname ) )
919 return scal
920
921def almacal( scantab, scannos=[], calmode='none', verify=False ):
922 """
923 Calibrate ALMA data
924
925 Parameters:
926 scantab: scantable
927 scannos: list of scan number
928 calmode: calibration mode
929
930 verify: verify calibration
931 """
932 from asap._asap import stmath
933 stm = stmath()
934 ssub = scantab.get_scan( scannos )
935 scal = scantable( stm.almacal( ssub, calmode ) )
936 return scal
937
938@asaplog_post_dec
939def splitant(filename, outprefix='',overwrite=False):
940 """
941 Split Measurement set by antenna name, save data as a scantables,
942 and return a list of filename.
943 Notice this method can only be available from CASA.
944 Prameter
945 filename: the name of Measurement set to be read.
946 outprefix: the prefix of output scantable name.
947 the names of output scantable will be
948 outprefix.antenna1, outprefix.antenna2, ....
949 If not specified, outprefix = filename is assumed.
950 overwrite If the file should be overwritten if it exists.
951 The default False is to return with warning
952 without writing the output. USE WITH CARE.
953
954 """
955 # Import the table toolkit from CASA
956 import casac
957 from asap.scantable import is_ms
958 tbtool = casac.homefinder.find_home_by_name('tableHome')
959 tb = tbtool.create()
960 # Check the input filename
961 if isinstance(filename, str):
962 import os.path
963 filename = os.path.expandvars(filename)
964 filename = os.path.expanduser(filename)
965 if not os.path.exists(filename):
966 s = "File '%s' not found." % (filename)
967 raise IOError(s)
968 # check if input file is MS
969 #if not os.path.isdir(filename) \
970 # or not os.path.exists(filename+'/ANTENNA') \
971 # or not os.path.exists(filename+'/table.f1'):
972 if not is_ms(filename):
973 s = "File '%s' is not a Measurement set." % (filename)
974 raise IOError(s)
975 else:
976 s = "The filename should be string. "
977 raise TypeError(s)
978 # Check out put file name
979 outname=''
980 if len(outprefix) > 0: prefix=outprefix+'.'
981 else:
982 prefix=filename.rstrip('/')
983 # Now do the actual splitting.
984 outfiles=[]
985 tb.open(tablename=filename,nomodify=True)
986 ant1=tb.getcol('ANTENNA1',0,-1,1)
987 #anttab=tb.getkeyword('ANTENNA').split()[-1]
988 anttab=tb.getkeyword('ANTENNA').lstrip('Table: ')
989 tb.close()
990 #tb.open(tablename=filename+'/ANTENNA',nomodify=True)
991 tb.open(tablename=anttab,nomodify=True)
992 nant=tb.nrows()
993 antnames=tb.getcol('NAME',0,nant,1)
994 tb.close()
995 tmpname='asapmath.splitant.tmp'
996 for antid in set(ant1):
997 tb.open(tablename=filename,nomodify=True)
998 tbsel=tb.query('ANTENNA1 == %s && ANTENNA2 == %s'%(antid,antid),tmpname)
999 scan=scantable(tmpname,average=False,getpt=True,antenna=int(antid))
1000 outname=prefix+antnames[antid]+'.asap'
1001 scan.save(outname,format='ASAP',overwrite=overwrite)
1002 tbsel.close()
1003 tb.close()
1004 del tbsel
1005 del scan
1006 outfiles.append(outname)
1007 os.system('rm -rf '+tmpname)
1008 del tb
1009 return outfiles
1010
1011@asaplog_post_dec
1012def _array2dOp( scan, value, mode="ADD", tsys=False, insitu=None):
1013 """
1014 This function is workaround on the basic operation of scantable
1015 with 2 dimensional float list.
1016
1017 scan: scantable operand
1018 value: float list operand
1019 mode: operation mode (ADD, SUB, MUL, DIV)
1020 tsys: if True, operate tsys as well
1021 insitu: if False, a new scantable is returned.
1022 Otherwise, the array operation is done in-sitsu.
1023 """
1024 nrow = scan.nrow()
1025 s = None
1026 from asap._asap import stmath
1027 stm = stmath()
1028 stm._setinsitu(insitu)
1029 if len( value ) == 1:
1030 s = scantable( stm._arrayop( scan, value[0], mode, tsys ) )
1031 elif len( value ) != nrow:
1032 raise ValueError( 'len(value) must be 1 or conform to scan.nrow()' )
1033 else:
1034 from asap._asap import stmath
1035 if not insitu:
1036 s = scan.copy()
1037 else:
1038 s = scan
1039 # insitu must be True as we go row by row on the same data
1040 stm._setinsitu( True )
1041 basesel = s.get_selection()
1042 # generate a new selector object based on basesel
1043 sel = selector(basesel)
1044 for irow in range( nrow ):
1045 sel.set_rows( irow )
1046 s.set_selection( sel )
1047 if len( value[irow] ) == 1:
1048 stm._unaryop( s, value[irow][0], mode, tsys )
1049 else:
1050 #stm._arrayop( s, value[irow], mode, tsys, 'channel' )
1051 stm._arrayop( s, value[irow], mode, tsys )
1052 s.set_selection(basesel)
1053 return s
Note: See TracBrowser for help on using the repository browser.