source: trunk/python/asapmath.py @ 479

Last change on this file since 479 was 479, checked in by kil064, 19 years ago

be clear that gain-el correction is multiplier

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 16.9 KB
Line 
1from scantable import scantable
2from asap import rcParams
3
4def average_time(*args, **kwargs):
5    """
6    Return the (time) average of a scan or list of scans. [in channels only]
7    The cursor of the output scan is set to 0
8    Parameters:
9        one scan or comma separated  scans
10        mask:     an optional mask (only used for 'var' and 'tsys' weighting)
11        scanav:   True (default) averages each scan separately
12                  False averages all scans together,
13        weight:   Weighting scheme. 'none' (default), 'var' (variance
14                  weighted), 'tsys'
15    Example:
16        # return a time averaged scan from scana and scanb
17        # without using a mask
18        scanav = average_time(scana,scanb)
19        # return the (time) averaged scan, i.e. the average of
20        # all correlator cycles
21        scanav = average_time(scan)
22
23    """
24    scanAv = True
25    if kwargs.has_key('scanav'):
26       scanAv = kwargs.get('scanav')
27    weight = 'none'
28    if kwargs.has_key('weight'):
29       weight = kwargs.get('weight')
30    mask = ()
31    if kwargs.has_key('mask'):
32        mask = kwargs.get('mask')
33    lst = tuple(args)
34    from asap._asap import average as _av
35    for s in lst:
36        if not isinstance(s,scantable):
37            print "Please give a list of scantables"
38            return
39    return scantable(_av(lst, mask, scanAv, weight))
40
41def quotient(source, reference, preserve=True):
42    """
43    Return the quotient of a 'source' (signal) scan and a 'reference' scan.
44    The reference can have just one row, even if the signal has many. Otherwise
45    they must have the same number of rows.
46    The cursor of the output scan is set to 0
47    Parameters:
48        source:        the 'on' scan
49        reference:     the 'off' scan
50        preserve:      you can preserve (default) the continuum or
51                       remove it.  The equations used are
52                          preserve - Output = Tref * (sig/ref) - Tref
53                          remove   - Output = Tref * (sig/ref) - Tsig
54    """
55    from asap._asap import quotient as _quot
56    return scantable(_quot(source, reference, preserve))
57
58def simple_math(left, right, op='add', tsys=True):
59    """
60    Apply simple mathematical binary operations to two
61    scan tables,  returning the result in a new scan table.
62    The operation is applied to both the correlations and the TSys data
63    The cursor of the output scan is set to 0
64    Parameters:
65        left:          the 'left' scan
66        right:         the 'right' scan
67        op:            the operation: 'add' (default), 'sub', 'mul', 'div'
68        tsys:          if True (default) then apply the operation to Tsys
69                       as well as the data
70    """
71    if not isinstance(left,scantable) and not isinstance(right,scantable):
72        print "Please provide two scantables as input"
73        return
74    from asap._asap import b_operate as _bop
75    return scantable(_bop(left, right, op, tsys))
76
77def scale(scan, factor, insitu=None, allaxes=None, tsys=True):
78    """
79    Return a scan where all spectra are scaled by the give 'factor'
80    Parameters:
81        scan:        a scantable
82        factor:      the scaling factor
83        insitu:      if False a new scantable is returned.
84                     Otherwise, the scaling is done in-situ
85                     The default is taken from .asaprc (False)
86        allaxes:     if True apply to all spectra. Otherwise
87                     apply only to the selected (beam/pol/if)spectra only.
88                     The default is taken from .asaprc (True if none)
89        tsys:        if True (default) then apply the operation to Tsys
90                     as well as the data
91    """
92    if allaxes is None: allaxes = rcParams['scantable.allaxes']
93    if insitu is None: insitu = rcParams['insitu']
94    if not insitu:
95        from asap._asap import scale as _scale
96        return scantable(_scale(scan, factor, allaxes, tsys))
97    else:
98        from asap._asap import scale_insitu as _scale
99        _scale(scan, factor, allaxes, tsys)
100        return
101       
102
103def add(scan, offset, insitu=None, allaxes=None):
104    """
105    Return a scan where all spectra have the offset added
106    Parameters:
107        scan:        a scantable
108        offset:      the offset
109        insitu:      if False a new scantable is returned.
110                     Otherwise, the scaling is done in-situ
111                     The default is taken from .asaprc (False)
112        allaxes:     if True apply to all spectra. Otherwise
113                     apply only to the selected (beam/pol/if)spectra only
114                     The default is taken from .asaprc (True if none)
115    """
116    if allaxes is None: allaxes = rcParams['scantable.allaxes']
117    if insitu is None: insitu = rcParams['insitu']
118    if not insitu:
119        from asap._asap import add as _add
120        return scantable(_add(scan, offset, allaxes))
121    else:
122        from asap._asap import add_insitu as _add
123        _add(scan, offset, allaxes)
124        return
125       
126def convert_flux(scan, jyperk=None, eta=None, d=None, insitu=None, allaxes=None):
127    """
128    Return a scan where all spectra are converted to either Jansky or Kelvin
129        depending upon the flux units of the scan table.  By default the
130        function tries to look the values up internally. If it can't find
131        them (or if you want to over-ride), you must specify EITHER jyperk
132        OR eta (and D which it will try to look up also if you don't
133        set it).  jyperk takes precedence if you set both.
134    Parameters:
135        scan:        a scantable
136        jyperk:      the Jy / K conversion factor
137        eta:         the aperture efficiency 
138        d:           the geomtric diameter (metres)
139        insitu:      if False a new scantable is returned.
140                     Otherwise, the scaling is done in-situ
141                     The default is taken from .asaprc (False)
142        allaxes:         if True apply to all spectra. Otherwise
143                     apply only to the selected (beam/pol/if)spectra only
144                     The default is taken from .asaprc (True if none)
145    """
146    if allaxes is None: allaxes = rcParams['scantable.allaxes']
147    if insitu is None: insitu = rcParams['insitu']
148    if jyperk is None: jyperk = -1.0
149    if d is None: d = -1.0
150    if eta is None: eta = -1.0
151    if not insitu:
152        from asap._asap import convertflux as _convert
153        return scantable(_convert(scan, d, eta, jyperk, allaxes))
154    else:
155        from asap._asap import convertflux_insitu as _convert
156        _convert(scan, d, eta, jyperk, allaxes)
157        return
158
159def gain_el(scan, poly=None, filename="", method="linear",
160            insitu=None, allaxes=None):
161    """
162    Return a scan after applying a gain-elevation correction. The correction
163    can be made via either a polynomial or a table-based interpolation
164    (and extrapolation if necessary).
165    You specify polynomial coefficients, an ascii table or neither.
166    If you specify neither, then a polynomial correction will be made
167    with built in coefficients known for certain telescopes (an error will
168    occur if the instrument is not known).   The data are *multiplied*
169    by the scaling factors.
170    Parameters:
171        scan:        a scantable
172        poly:        Polynomial coefficients (default None) to compute a
173                     gain-elevation correction as a function of
174                     elevation (in degrees).
175        filename:    The name of an ascii file holding correction factors.
176                     The first row of the ascii file must give the column
177                     names and these MUST include columns
178                     "ELEVATION" (degrees) and "FACTOR" (multiply data by this)
179                     somewhere.
180                     The second row must give the data type of the column. Use
181                     'R' for Real and 'I' for Integer.  An example file
182                     would be (actual factors are arbitrary) :
183
184                     TIME ELEVATION FACTOR
185                     R R R
186                     0.1 0 0.8
187                     0.2 20 0.85
188                     0.3 40 0.9
189                     0.4 60 0.85
190                     0.5 80 0.8
191                     0.6 90 0.75
192        method:      Interpolation method when correcting from a table. Values
193                     are  "nearest", "linear" (default), "cubic" and "spline"
194        insitu:      if False a new scantable is returned.
195                     Otherwise, the scaling is done in-situ
196                     The default is taken from .asaprc (False)
197        allaxes:         if True apply to all spectra. Otherwise
198                     apply only to the selected (beam/pol/if) spectra only
199                     The default is taken from .asaprc (True if none)
200    """
201    if allaxes is None: allaxes = rcParams['scantable.allaxes']
202    if poly is None:
203       poly = ()
204    if insitu is None: insitu = rcParams['insitu']
205    from os.path import expandvars
206    filename = expandvars(filename)
207    if not insitu:
208        from asap._asap import gainel as _gainEl
209        return scantable(_gainEl(scan, poly, filename, method, allaxes))
210    else:
211        from asap._asap import gainel_insitu as _gainEl
212        _gainEl(scan, poly, filename, method, allaxes)
213        return
214       
215def freq_align(scan, reftime=None, method='cubic', perif=False, insitu=None):
216    """
217        Return a scan where all rows have been aligned in frequency. The
218        alignment frequency frame (e.g. LSRK) is that set by function
219        set_freqframe. 
220        scan:        a scantable
221        reftime:     reference time to align at. By default, the time of
222                     the first row of data is used. 
223        method:      Interpolation method for regridding the spectra. Choose
224                     from "nearest", "linear", "cubic" (default) and "spline"
225        perif:       Generate aligners per freqID (no doppler tracking) or
226                     per IF (scan-based doppler tracking)
227        insitu:      if False a new scantable is returned.
228                     Otherwise, the scaling is done in-situ
229                     The default is taken from .asaprc (False)
230    """
231    if reftime is None: reftime = ''
232    if insitu is None: insitu = rcParams['insitu']
233    perfreqid = not perif
234    if not insitu:
235        from asap._asap import freq_align as _align
236        return scantable(_align(scan, reftime, method, perfreqid))
237    else:
238        from asap._asap import freq_align_insitu as _align
239        _align(scan, reftime, method, perfreqid)
240        return
241       
242def opacity(scan, tau, insitu=None, allaxes=None):
243    """
244    Return a scan after applying an opacity correction.
245    Parameters:
246        scan:        a scantable
247        tau:         Opacity from which the correction factor is exp(tau*ZD)
248                     where ZD is the zenith-distance
249        insitu:      if False a new scantable is returned.
250                     Otherwise, the scaling is done in-situ
251                     The default is taken from .asaprc (False)
252        allaxes:     if True apply to all spectra. Otherwise
253                     apply only to the selected (beam/pol/if)spectra only
254                     The default is taken from .asaprc (True if none)
255    """
256    if allaxes is None: allaxes = rcParams['scantable.allaxes']
257    if insitu is None: insitu = rcParams['insitu']
258    if not insitu:
259        from asap._asap import opacity as _opacity
260        return scantable(_opacity(scan, tau, allaxes))
261    else:
262        from asap._asap import opacity_insitu as _opacity
263        _opacity(scan, tau, allaxes)
264        return
265       
266def bin(scan, width=5, insitu=None):
267    """
268    Return a scan where all spectra have been binned up
269        width:       The bin width (default=5) in pixels
270        insitu:      if False a new scantable is returned.
271                     Otherwise, the scaling is done in-situ
272                     The default is taken from .asaprc (False)
273    """
274    if insitu is None: insitu = rcParams['insitu']
275    if not insitu:
276        from asap._asap import bin as _bin
277        return scantable(_bin(scan, width))
278    else:
279        from asap._asap import bin_insitu as _bin
280        _bin(scan, width)
281        return
282
283def resample(scan, width=5, method='cubic', insitu=None):
284    """
285    Return a scan where all spectra have been binned up
286        width:       The bin width (default=5) in pixels
287        method:      Interpolation method when correcting from a table. Values
288                     are  "nearest", "linear", "cubic" (default) and "spline"
289        insitu:      if False a new scantable is returned.
290                     Otherwise, the scaling is done in-situ
291                     The default is taken from .asaprc (False)
292    """
293    if insitu is None: insitu = rcParams['insitu']
294    if not insitu:
295        from asap._asap import resample as _resample
296        return scantable(_resample(scan, method, width))
297    else:
298        from asap._asap import resample_insitu as _resample
299        _resample(scan, method, width)
300        return
301
302def average_pol(scan, mask=None, weight='none', insitu=None):
303    """
304    Average the Polarisations together.
305    The polarisation cursor of the output scan is set to 0
306    Parameters:
307        scan:        The scantable
308        mask:        An optional mask defining the region, where the
309                     averaging will be applied. The output will have all
310                     specified points masked.
311        weight:      Weighting scheme. 'none' (default), or 'var' (variance
312                     weighted)
313        insitu:      if False a new scantable is returned.
314                     Otherwise, the scaling is done in-situ
315                     The default is taken from .asaprc (False)
316    Example:
317        polav = average_pols(myscan)
318    """
319    if mask is None:
320        mask = ()
321    if insitu is None: insitu = rcParams['insitu']
322    if not insitu:
323        from asap._asap import averagepol as _avpol
324        return scantable(_avpol(scan, mask, weight))
325    else:
326        from asap._asap import averagepol_insitu as _avpol
327        _avpol(scan, mask, weight)
328        return
329   
330def smooth(scan, kernel="hanning", width=5.0, insitu=None, allaxes=None):
331    """
332    Smooth the spectrum by the specified kernel (conserving flux).
333    Parameters:
334        scan:       The input scan
335        kernel:     The type of smoothing kernel. Select from
336                    'hanning' (default), 'gaussian' and 'boxcar'.
337                    The first three characters are sufficient.
338        width:      The width of the kernel in pixels. For hanning this is
339                    ignored otherwise it defauls to 5 pixels.
340                    For 'gaussian' it is the Full Width Half
341                    Maximum. For 'boxcar' it is the full width.
342        insitu:     if False a new scantable is returned.
343                    Otherwise, the scaling is done in-situ
344                    The default is taken from .asaprc (False)
345        allaxes:    If True (default) apply to all spectra. Otherwise
346                    apply only to the selected (beam/pol/if)spectra only
347                    The default is taken from .asaprc (True if none)
348    Example:
349         none
350    """
351    if allaxes is None: allaxes = rcParams['scantable.allaxes']
352    if insitu is None: insitu = rcParams['insitu']
353    if not insitu:
354        from asap._asap import smooth as _smooth
355        return scantable(_smooth(scan,kernel,width,allaxes))
356    else:
357        from asap._asap import smooth_insitu as _smooth
358        _smooth(scan,kernel,width,allaxes)
359        return
360   
361def poly_baseline(scan, mask=None, order=0, insitu=None):
362    """
363    Return a scan which has been baselined (all rows) by a polynomial.
364    Parameters:
365        scan:    a scantable
366        mask:    an optional mask
367        order:   the order of the polynomial (default is 0)
368        insitu:      if False a new scantable is returned.
369                     Otherwise, the scaling is done in-situ
370                     The default is taken from .asaprc (False)
371    Example:
372        # return a scan baselined by a third order polynomial,
373        # not using a mask
374        bscan = poly_baseline(scan, order=3)
375    """
376    from asap.asapfitter import fitter
377    if mask is None:
378        from numarray import ones
379        mask = tuple(ones(scan.nchan()))
380    f = fitter()
381    f._verbose(True)
382    f.set_scan(scan, mask)
383    f.set_function(poly=order)   
384    sf = f.auto_fit(insitu)
385    return sf
386
387def rotate_xyphase (scan, angle, allaxes=None):
388    """
389    Rotate the phase of the XY correlation.  This is always done in situ
390    in the data.  So if you call this function more than once
391    then each call rotates the phase further.
392    Parameters:
393        angle:   The angle (degrees) to rotate (add) by.
394        allaxes: If True apply to all spectra. Otherwise
395                 apply only to the selected (beam/pol/if)spectra only.
396                 The default is taken from .asaprc (True if none)
397    Examples:
398        rotate_xyphase(scan, 2.3)
399    """
400    if allaxes is None: allaxes = rcParams['scantable.allaxes']
401    from asap._asap import rotate_xyphase as _rotate_xyphase
402    _rotate_xyphase(scan, angle, allaxes)
403    return
404
Note: See TracBrowser for help on using the repository browser.