From AstroBaki
Revision as of 11:54, 15 February 2010 by WikiSysop (talk | contribs) (Created page with '= The AIPY Cookbook = This page is for posting examples of how AIPY is used to accomplish various tasks. Examples should be fully functional (i.e. they should run), but should …')
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

The AIPY Cookbook[edit]

This page is for posting examples of how AIPY is used to accomplish various tasks. Examples should be fully functional (i.e. they should run), but should not have too much extraneous code.

Writing a Calibration File[edit]

A calibration file is a Python module that is imported by AIPY scripts to get deployment-specific information about your instrument. A calibration file should implement 2 functions: `get_aa(...)` and `get_catalog(...)`. These functions should return, respectively, an `AntennaArray` object representing your array, and a `SrcCatalog` containing sources to use for simulation. A bare-minimum calibration file would be something like:

import aipy as a

def get_aa(freqs):
    # Define the location of your instrument
    lat, lon = '45:00', '90:00'
    # Create a model of the primary beam.  BeamFlat is a minimal model that has unity
    # gain in all directions.  
    beam =   
    # Make a list of antennas with requisite nanosecond locations, primary beams, and
    # any other calibration parameters you wish to provide.
    ants = [  0,   0,  0, beam),  0, 100,  0, beam),,   0,  0, beam),, 100,  0, beam),
    # Create an AntennaArray at the specified location with the listed antennas
    aa =,lon), ants)
    return aa

def get_catalog(srcs=None, cutoff=None):
    # Pass off the request for sources to the AIPY source catalog.  If desired, you can
    # substitute your own sources or source calibrations.
    return a.src.get_catalog(srcs=srcs, cutoff=cutoff)

This code can be saved as a module (named, say, ``), and imported into AIPY scripts that need location-specific calibrations using `-l my_cal`. Note that `` must be in a location where Python can find and import it. Your current working directory should suffice most of the time.

Starting a new UV File[edit]

Starting a brand-new UV file takes a bit of setup work. This example shows a bare-bones UV file setup; more detailed code for setting up a UV file is in the script ``. This example creates a UV file filled with constant data. In most applications, you would probably want to import an `AntennaArray` at the beginning of a script, and you would use data from that object to fill in various fields (`latitud`, `longitud`, `antpos`, `lst`, etc.) and to simulate data.

import aipy as a

uv = a.miriad.UV('new.uv', status='new')      # Start a new UV file
uv._wrhd('obstype','mixed-auto-cross')        # Miriad header item indicating data type
uv._wrhd('history','Started new file')        # Record file creation for posterity

# Create and initialize UV variables
# a dict of variable data type is in a.miriad.data_types
# This is not a complete list of variables, see MIRIAD programmer reference
uv.add_var('epoch'   ,'r')                    # Make a variable 'epoch', data type = real
uv['epoch'] = 2000.                           # Set epoch to 2000.
uv.add_var('source'  ,'a')                    # Source we are tracking, as a string
uv['source'] = 'zenith'
uv.add_var('latitud' ,'d')                    # Latitude of our array, as a double
uv['latitud'] = 0.00
uv.add_var('longitu' ,'d')                    # Longitude of our array, as double
uv['longitu'] = 3.1415
uv.add_var('npol'    ,'i')                    # Number of recorded polarizations, as int
uv['npol'] = 1
uv.add_var('nspect'  ,'i')                    # Number of spectra recorded per antenna/baseline
uv['nspect'] = 1
uv.add_var('nants'   ,'i')                    # Number of antennas in array
uv['nants'] = 4
uv.add_var('antpos'  ,'d')                    # Positions (uvw) of antennas.  Expected to be 3*nants in length
antpos = n.array([
    [  0,   0, 0],
    [100,   0, 0],
    [  0, 100, 0],
    [100, 100, 0]], dtype=n.double)
uv['antpos'] = antpos.transpose().flatten()   # Transposition is a MIRIAD convention.  You can follow it or not.
uv.add_var('sfreq'   ,'d')                    # Freq of first channel in spectra (GHz)
uv['sfreq'] = .100
uv.add_var('sdf'     ,'d')                    # Delta freq between channels
uv['sdf'] = .001
uv.add_var('nchan'   ,'i')                    # Number of channels in spectrum
uv['nchan'] = 256
uv.add_var('nschan'  ,'i')                    # Number of channels in bandpass cal spectra
uv['nschan'] = 256
uv.add_var('inttime' ,'r')                    # Integration time (seconds)
uv['inttime'] = 10

# These variables will get updated every spectrum
uv.add_var('time'    ,'d')
uv.add_var('lst'     ,'d')
uv.add_var('ra'      ,'d')
uv.add_var('obsra'   ,'d')
uv.add_var('pol'     ,'i')

# Now start generating data
# Time steps in julian date
times = n.arange(2454500., 2454501, uv['inttime']/a.const.s_per_day)
for cnt,t in enumerate(times):
    uv['lst'] = 0.                           # Should be sidereal time from AntennaArray
    uv['ra'] = 0.                            # RA of source you're pointing at
    for i,ai in enumerate(antpos):
        for j,aj in enumerate(antpos):
            if j < i: continue
            crd = ai - aj                    # Find uvw coordinate of baseline
            preamble = (crd, t, (i,j))       # Set preamble to (uvw, julian date, baseline)
            uv['pol'] = a.miriad.str2pol['xx']                 # Fix polarization as 'xx'
            data = n.ones((uv['nchan'],), dtype=n.complex64)   # Generate some data
            flag = n.zeros((uv['nchan'],), dtype=n.int32)      # Generate some flags (zero = valid)
            uv.write(preamble, data, flags)                    # Write this entry to the UV file
del(uv)   # Close the file