source: trunk/python/asapmath.py @ 2451

Last change on this file since 2451 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.