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 not have too much extraneous code.
Writing a Calibration File
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:
1 import aipy as a
2
3 def get_aa(freqs):
4 # Define the location of your instrument
5 lat, lon = '45:00', '90:00'
6 # Create a model of the primary beam. BeamFlat is a minimal model that has unity
7 # gain in all directions.
8 beam = a.fit.BeamFlat(freqs)
9 # Make a list of antennas with requisite nanosecond locations, primary beams, and
10 # any other calibration parameters you wish to provide.
11 ants = [
12 a.fit.Antenna( 0, 0, 0, beam),
13 a.fit.Antenna( 0, 100, 0, beam),
14 a.fit.Antenna(100, 0, 0, beam),
15 a.fit.Antenna(100, 100, 0, beam),
16 ]
17 # Create an AntennaArray at the specified location with the listed antennas
18 aa = a.fit.AntennaArray((lat,lon), ants)
19 return aa
20
21 def get_catalog(srcs=None, cutoff=None):
22 # Pass off the request for sources to the AIPY source catalog. If desired, you can
23 # substitute your own sources or source calibrations.
24 return a.src.get_catalog(srcs=srcs, cutoff=cutoff)
This code can be saved as a module (named, say, my_cal.py), and imported into AIPY scripts that need location-specific calibrations using -l my_cal. Note that my_cal.py 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
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 mdlvis.py. 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.
1 import aipy as a
2
3 uv = a.miriad.UV('new.uv', status='new') # Start a new UV file
4 uv._wrhd('obstype','mixed-auto-cross') # Miriad header item indicating data type
5 uv._wrhd('history','Started new file') # Record file creation for posterity
6
7 # Create and initialize UV variables
8 # a dict of variable data type is in a.miriad.data_types
9 # This is not a complete list of variables, see MIRIAD programmer reference
10 uv.add_var('epoch' ,'r') # Make a variable 'epoch', data type = real
11 uv['epoch'] = 2000. # Set epoch to 2000.
12 uv.add_var('source' ,'a') # Source we are tracking, as a string
13 uv['source'] = 'zenith'
14 uv.add_var('latitud' ,'d') # Latitude of our array, as a double
15 uv['latitud'] = 0.00
16 uv.add_var('longitu' ,'d') # Longitude of our array, as double
17 uv['longitu'] = 3.1415
18 uv.add_var('npol' ,'i') # Number of recorded polarizations, as int
19 uv['npol'] = 1
20 uv.add_var('nspect' ,'i') # Number of spectra recorded per antenna/baseline
21 uv['nspect'] = 1
22 uv.add_var('nants' ,'i') # Number of antennas in array
23 uv['nants'] = 4
24 uv.add_var('antpos' ,'d') # Positions (uvw) of antennas. Expected to be 3*nants in length
25 antpos = n.array([
26 [ 0, 0, 0],
27 [100, 0, 0],
28 [ 0, 100, 0],
29 [100, 100, 0]], dtype=n.double)
30 uv['antpos'] = antpos.transpose().flatten() # Transposition is a MIRIAD convention. You can follow it or not.
31 uv.add_var('sfreq' ,'d') # Freq of first channel in spectra (GHz)
32 uv['sfreq'] = .100
33 uv.add_var('sdf' ,'d') # Delta freq between channels
34 uv['sdf'] = .001
35 uv.add_var('nchan' ,'i') # Number of channels in spectrum
36 uv['nchan'] = 256
37 uv.add_var('nschan' ,'i') # Number of channels in bandpass cal spectra
38 uv['nschan'] = 256
39 uv.add_var('inttime' ,'r') # Integration time (seconds)
40 uv['inttime'] = 10
41
42 # These variables will get updated every spectrum
43 uv.add_var('time' ,'d')
44 uv.add_var('lst' ,'d')
45 uv.add_var('ra' ,'d')
46 uv.add_var('obsra' ,'d')
47 uv.add_var('baseline','r')
48 uv.add_var('pol' ,'i')
49
50 # Now start generating data
51 # Time steps in julian date
52 times = n.arange(2454500., 2454501, uv['inttime']/a.const.s_per_day)
53 for cnt,t in enumerate(times):
54 uv['lst'] = 0. # Should be sidereal time from AntennaArray
55 uv['ra'] = 0. # RA of source you're pointing at
56 for i,ai in enumerate(antpos):
57 for j,aj in enumerate(antpos):
58 if j < i: continue
59 crd = ai - aj # Find uvw coordinate of baseline
60 preamble = (crd, t, (i,j)) # Set preamble to (uvw, julian date, baseline)
61 uv['pol'] = a.miriad.str2pol['xx'] # Fix polarization as 'xx'
62 data = n.ones((uv['nchan'],), dtype=n.complex64) # Generate some data
63 flag = n.zeros((uv['nchan'],), dtype=n.int32) # Generate some flags (zero = valid)
64 uv.write(preamble, data, flags) # Write this entry to the UV file
65 del(uv) # Close the file
