MIRIAD Data Utilities: mirtask.util

The module mirtask.util contains miscellaneous utilities for working with MIRIAD data. It is located in the mirtask package because some of these utilities make calls into the MIRIAD subroutine library, unlike the general, pure-Python tools in the miriad module.

Antpols and Basepols

Docs here.

Document FPOL_XYRLIQUV.

Textual Conversion

mirtask.util.fmtAP(ap)
mirtask.util.fPolNames = 'XYRLIQUV'

str(object=’‘) -> string

Return a nice string representation of the object. If the argument is a string, the return value is the same object.

mirtask.util.parseAP(text)
mirtask.util.fmtBP(bp)
mirtask.util.parseBP(text)
mirtask.util.fmtPBP32(pbp32)
mirtask.util.parsePBP32(text)

Data Conversion

mirtask.util.apAnt(ap)
mirtask.util.apFPol(ap)
mirtask.util.antpol2ap(m, fpol)
mirtask.util.bp2aap(bp)

Converts a basepol into a tuple of (ant1, ant2, pol).

mirtask.util.aap2bp(m1, m2, pol)

Create a basepol from antenna numbers and a FITS/MIRIAD polarization code.

Parameters:
  • m1 (int) – the first antenna number; one-based as used internally by MIRIAD, not zero based
  • m2 (int) – the second antenna number; also one-based
  • pol (FITS/MIRIAD polarization code) – the polarization
Returns:

the corresponding basepol

Raises :

ValueError if m1 or m2 is below one, or pol is not a known polarization code.

Note that the input antenna numbers should be one-based, not zero-based as more conventional for C and Python. (This is consistent with bp2aap().) m1 need not be smaller than m2, although this is the typical convention.

mirtask.util.bp2blpol(bp)

Converts a basepol into a tuple of (bl, pol) where ‘bl’ is the MIRIAD-encoded baseline number.

mirtask.util.mir2bp(inp, preamble)

Uses a UV dataset and a preamble array to return a basepol.

mirtask.util.bpIsInten(bp)
mirtask.util.pbp32ToBP(pbp32)
mirtask.util.bpToPBP32(bp)
mirtask.util.mir2pbp32(handle, preamble)
mirtask.util.pbp32IsInten(pbp32)

Utilities for Writing Tasks

mirtask.util.printBannerSvn(name, desc, idstr)

Print a banner string containing the name of a task, its description, and versioning information extracted from a Subversion ID string. The banner string is returned as well.

mirtask.util.die(format, *args)

Raise a SystemExit exception with a formatted error message.

Parameters:
  • format (str) – a format string
  • args – arguments to the format string

A SystemExit exception is raised with the argument 'error: ' + (format % args). If uncaught, the interpreter exits with an error code and prints the exception argument.

Example:

if ndim != 3:
   die ('require exactly 3 dimensions, not %d', ndim)
mirtask.util.checkusage(docstring, argv=None, usageifnoargs=False)

Check if the program has been run with a –help argument; if so, print usage information and exit.

Parameters:
  • docstring (str) – the program help text
  • argv – the program arguments; taken as sys.argv if given as None (the default)
  • usageifnoargs (bool) – if True, usage information will be printed and the program will exit if no command-line arguments are passed. Default is False.

This function is intended for small programs launched from the command line. The intention is for the program help information to be written in its docstring, and then for the preamble to contain something like:

"""myprogram - this is all the usage help you get"""
from mirtask.util import checkusage
... # other setup
checkusage (__doc__)
... # go on with business

If it is determined that usage information should be shown, showusage() is called and the program exits.

As described more fully in the showusage() documentation, docstring is treated specially if it begins with an equals sign, which indicates that it is written in MIRIAD “doc” markup. In that case, the mirpyhelp.py MIRIAD documentation program is run.

See also wrongusage().

mirtask.util.showusage(docstring)

Print program usage information and exit.

Parameters:docstring (str) – the program help text

This function just prints docstring, with one wrinkle described below, and exits. In most cases, the function checkusage() should be used: it automatically checks sys.argv for a sole “-h” or “–help” argument and invokes this function.

The wrinkle is that if docstring[0] is ‘=’, which is the signpost that the docstring is written in MIRIAD “doc” markup, the miriad-python help program mirpyhelp.py is executed with a guess of the name of the current program as an argument. The program name is guessed from the second token of the docstring, which should be the program name by MIRIAD conventions. If this launch fails, the raw docstring is printed.

This function is provided in case there are instances where the user should get a friendly usage message that checkusage() doesn’t catch. It can be contrasted with wrongusage(), which prints a terser usage message and exits with an error code.

mirtask.util.wrongusage(docstring, *rest)

Print a message indicating invalid command-line arguments and exit with an error code.

Parameters:
  • docstring (str) – the program help text
  • rest – an optional specific error message

This function is intended for small programs launched from the command line. The intention is for the program help information to be written in its docstring, and then for argument checking to look something like this:

"""mytask <input> <output>

Do something to the input to create the output.
"""
...
import sys
from mirtask.util import checkusage, wrongusage
... # other setup
checkusage (__doc__)
... # more setup
if len (sys.argv) != 3:
   wrongusage (__doc__, "expect exactly 3 arguments, not %d",
               len (sys.argv))

When called, an error message is printed along with the first stanza of docstring. The program then exits with an error code and a suggestion to run the program with a –help argument to see more detailed usage information. The “first stanza” of docstring is defined as everything up until the first blank line, ignoring any leading blank lines.

The optional message in rest is treated as follows. If rest is empty, the error message “invalid command-line arguments” is printed. If it is a single item, that item is printed. If it is more than one item, the first item is treated as a format string, and it is percent-formatted with the remaining values. See the above example.

If docstring starts with an equals sign, it is taken to be MIRIAD-format doc markup, and the first stanza is not printed.

See also checkusage() and showusage().

Linetypes

mirtask.util.linetypeName(linetype)

Given a linetype number, return its textual description

Parameters:linetype (int) – the linetype code
Returns:the description
Return type:str

The linetypes are:

Symbolic Constant Numeric Value Description
LINETYPE_NONE 0 “undefined”
LINETYPE_CHANNEL 1 “channel”
LINETYPE_WIDE 2 “wide”
LINETYPE_VELOCITY 3 “velocity”
LINETYPE_FELOCITY 4 “felocity”

The “felocity” type is used for spectral data resampled at even velocity increments, using the “optical definition” of velocity, v / c = (lambda - lambda0) / lambda0. The “radio definition” is slightly different: v / c = (nu0 - nu) / nu0.

mirtask.util.linetypeFromName(text)

Given a linetype name, return the corresponding numeric code.

Parameters:text (str) – the name of a linetype
Returns:the code
Return type:int
Throws :ValueError if text doesn’t correspond to one of the linetype names.

See linetypeName() for a description of the linetype symbolic constants, their numerical values, and standard textual descriptions.

Matching in this function is done case-insensitively and accepts partial matches. Because the linetype names all begin with different letters, this means that a code can be retrieved using just a single letter. Strings of all whitespace, or the empty string, are mapped to LINETYPE_NONE.

Baselines

mirtask.util.decodeBaseline(encoded, check=True)

Decode an encoded baseline double into two antenna numbers.

mirtask.util.encodeBaseline(ant1, ant2)

Encode a pair of antenna numbers into one baseline number suitable for use in UV data preambles.

Polarizations

mirtask.util.polarizationName(polnum)

Return the textual description of a MIRIAD polarization type from its number.

mirtask.util.polarizationNumber(polname)
mirtask.util.polarizationIsInten(polnum)

Return True if the given polarization is intensity-type, e.g., is I, XX, YY, RR, or LL.

Julian Dates

mirtask.util.jdToFull(jd, form='H')

Return a textual representation of a Julian date.

Parameters:
  • jd (double) – a Julian date
  • form (character) – the output format, described below. Defaults to “H”.
Returns:

the textualization of the Julian date

Raises :

MiriadError in case of buffer overflow (should never happen)

The possible output formats are:

Character Result
H “yyMONdd:mm:mm:ss.s” (“MON” is the three-letter abbreviation of the month name.)
T “yyyy-mm-ddThh:mm:ss.s” (The “T” is literal.)
D “yyMONdd.dd”
V “dd-MON-yyyy” (loses fractional day)
F “dd/mm/yy” (loses fractional day)
mirtask.util.jdToPartial(jd)

Return a string representing the time-of-day portion of the given Julian date in the form ‘HH:MM:SS’. Obviously, this loses precision from the JD representation.

mirtask.util.dateOrTimeToJD(calendar)

Return a full or offset Julian date parsed from the argument. (An offset Julian date is between 0 and 1 and measures a time of day. The anchor point to which the offset Julian date is relative to is irrelevant to this function.) Acceptable input formats are:

yymmmdd.dd (D) dd/mm/yy (F) [yymmmdd:][hh[:mm[:ss.s]]] (H) ccyy-mm-dd[Thh[:mm[:ss.ss]]] (T) dd-mm-ccyy

See the documentation to Miriad function DAYJUL for a more detailed description of the parser behavior. The returned Julian date is of moderate accuracy only, e.g. good to a few seconds (I think?).

Optimizers

mirtask.util.nlLeastSquares(guess, neqn, func, derivative=None, maxIter=None, absCrit=None, relCrit=None, stepSizes=None, allowFail=False)

Optimize parameters by performing a nonlinear least-squares fit.

Parameters:
  • guess (1D ndarray) – the initial guess of the parameters. The size of the array is used to determine the number of parameters, to which we refer as nunk below.
  • neqn (int) – the number of equations – usually, the number of data points you have. Should be at least nunk.
  • func (callable) – a function evaluating the fit residuals. Prototype below.
  • derivative (callable) – an optional function giving the derivative of func with regards to changes in the parameters. Prototype below. If unspecified, the derivative will be approximated by exploring values of func, and stepSizes below must be given.
  • maxIter (int/None) – the maximum number of iterations to perform before giving up. An integer, or None. If None, maxIter is set to 200 times nunk. Defaults to None.
  • absCrit (float/None) – absolute termination criterion: iteration stops if sum(normResids**2) < criterion. If None, set to neqn - nunk (i.e., reduced chi squared = 1). Default is None.
  • relCrit (float/none) – relative termination criterion: iteration stops if relCrit * sum(abs(params)) < sum (abs(dparams)). If None, set to nunk * 1e-4, i.e. explore until the parameters are constrained to about one in 10000 . Default is None.
  • stepSizes (1D ndarray) – if derivative isn’t given, this should be a 1D array of nunk parameters, giving the parameter step sizes to use when evaluating the derivative of func numerically. If derivative is given, the value is ignored.
  • allowFail (bool) – if True, return results even for fits that did not succeed. If False, raise an exception in these cases. It is better to choose better values for absCrit and relCrit than it is to set allowFail to True.
Return type:

(int, 1D ndarray, 1D ndarray, float)

Returns:

tuple of (success, best, normResids, rchisq), described below.

The argument func is a function taking two arguments, params and normResids, and returning None.

Parameters:
  • params (1D ndarray) – the current guess of the parameters
  • normResids (1D ndarray) –

    an output argument of size neqn. sum(normResids**2) is minimized by the solver. So-called because in the classic case, this variable is set to the normalized residuals:

    normResids[i] = (model (x[i], params) - data[i]) / sigma[i]
    
Returns:

ignored

The optional argument derivative is a function taking two arguments, params and dfdx, and returning None.

Parameters:
  • params (1D ndarray) – the current guess of the parameters.
  • dfdx (2D ndarray) –

    an output argument of shape (nunk, neqn). Should be filled with the derivative of func with regard to the parameters:

    dfdx[i,j] = d(normResids[j]) / d(params[i]) .
Returns:

ignored

The return value is a tuple (success, best, normResids, rchisq), with the following meanings:

  • success – an integer describing the outcome of the fit:

    • 0 – fit succeeded; one of the convergence criteria was achieved.
    • 1 – a singular matrix was encountered; unable to complete fit.
    • 2 – maximum number of iterations completed before able to find a solution meeting either convergence criterion.
    • 3 – failed to achieve a better chi-squared than on the previous iteration, and the convergence criteria were not met on the previous iteration. The convergence criteria may be too stringent, or the initial guess may be leading the solver into a local minimum too far from the correct solution.
  • best – a 1D array giving the best-fit parameter values found by the algorithm.

  • normResids – a 1D array giving the last-evaluated normalized residuals as described in the prototype of func.

  • rchisq – the reduced chi squared of the fit:

    rChiSq = sum (normResids**2) / (neqn - nunk)
    

Implemented using the Miriad function NLLSQU.

mirtask.util.linLeastSquares(coeffs, vals)

Solve for parameters in a linear least-squares problem. The problem has neqn equations used to solve for nunk unknown parameters.

Parameters:
  • coeffs (2D ndarray) – an array of shape (nunk, neqn). With vals, defines the linear equations specifying the problem.
  • vals (1D ndarray) – data array of size neqn.
Return type:

1D ndarray

Returns:

an array of size nunk giving the parameters that yield the least-squares fit to the given equation.

The linear least squares problem is that of finding best solution (in a least-squares sense), retval, such that coeffs.T * retval = vals, using matrix notation. This is the same as solving neqn linear equations simultaneously, where the i’th equation is:

vals[i] = coeffs[0,i] * retval[0] + ... + coeffs[nunk-1,i] * retval[nunk-1]

Coordinate Manipulations

mirtask.util.precess(jd1, ra1, dec1, jd2)

Precess a coordinate from one Julian Date to another.

Parameters:
  • jd1 (double) – the JD of the input coordinates
  • ra1 (double) – the input RA in radians
  • dec1 (double) – the input dec in radians
  • jd2 (double) – the JD to precess to
Return type:

(double, double)

Returns:

(ra2, dec2), the precessed equatorial coordinates, both in radians

Claimed accuracy is 0.3 arcsec over 50 years. Based on the algorithm described in the Explanatory Supplement to the Astronomical Almanac, 1993, pp 105-106. Does not account for atmospheric refraction, nutation, aberration, or gravitational deflection.

mirtask.util.equToHorizon(ra, dec, lst, lat)

Convert equatorial coordinates to horizon coordinates.

Parameters:
  • ra (double) – the apparent RA in radians
  • dec (double) – the apparent dec in radians
  • lst (double) – the local sidereal time in radians
  • lat (double) – the geodetic latitude of the observatory in radians
Return type:

(double, double)

Returns:

(az, el), both in radians

mirtask.util.horizonToEqu(az, el, lst, lat)

Convert horizon coordinates to equatorial coordinates.

Parameters:
  • az (double) – the elevation coordinate in radians
  • el (double) – the azimuth coordinate in radians
  • lst (double) – the local sidereal time in radians
  • lat (double) – the geodetic latitude of the observatory in radians
Return type:

(double, double)

Returns:

(ra, dec), apparent equatorial coordinates, both in radians

Fast-Fourier-Transform Imaging

mirtask.util.sphGridFunc(nsamp, width, alpha)

Compute a spheroidal convolutional gridding function.

Parameters:
  • nsamp (int) – the number of points at which to sample the function. In MIRIAD, nsamp is always 2047.
  • width (int) – the width of the correction function, in pixels; must be 4, 5, or 6. In MIRIAD, width is always 6.
  • alpha (float) – spheroidal parameter; must be between 0 and 2.25, and will be rounded to the nearest half-integral value (i.e., 0, 0.5, 1, 1.5, or 2). In MIRIAD, alpha is always 1.0.
Return type:

nsamp-element real ndarray

Returns:

the tabulated function

The spheroidal convolutional gridding function is used to put visibility measurements on a regular grid so that a dirty map can be made using a fast Fourier transform (FFT) algorithm. A thorough discussion of the topic is beyond the scope of this docstring. See Chapter 10 of Thompson, Moran & Swenson or Lecture 7 of Synthesis Imaging in Radio Astronomy II.

In MIRIAD’s standard usage of this function, all of the arguments are fixed. You should probably use the MIRIAD values (nsamp = 2047, width = 6, alpha = 1.0) unless you really know what you’re doing. I don’t know how alpha affects the spheroidal function used but it’s probably not hard to look up.

Indices into the tabulated array are related to pixel offsets by the expression index = (nsamp // width) * pixeloffset + nsamp // 2. Using the standard MIRIAD parameters, this is index = 341 * pixeloffset + 1023.

mirtask.util.sphCorrFunc(axislen, width, alpha)

Compute a spheroidal gridding correction function.

Parameters:
  • axislen (int) – length of image axis to be corrected, in pixels
  • width (int) – width of gridding function; must be 4, 5, or 6
  • alpha (float) – spheroidal parameter; must be 0, 0.5, 1, 1.5, or 2.
Return type:

axislen-element real ndarray

Returns:

the tabulated function

I don’t quite understand the details of this function, but it’s used to correct the dirty map for the effects of the spheroidal function used to put visibilities onto a grid before FFTing int the mapping process. See the usage of xcorr and ycorr in mapper.for:MapFFT2. The correction function is separable in u/v or l/m so that there’s one for each image axis, which is why axislen is a single integer in this function. The output image is divided by the correction functions, scaled by their central pixels. The overall profile of the correction function is similar to that of the spheroidal convolution function itself.

In MIRIAD, width is always 6 and alpha is always 1.0. I don’t know how alpha affects the spheroidal function used but it’s probably not hard to look up.