Esempio n. 1
0
def check_recombine(obsID, directory=None, required_size=327680000, \
                        required_size_ics=30720000, startsec=None, n_secs=None):
    '''
    Checks that the number of files in directory (/astro/mwaops/vcs/[obsID]/combined/) is ....
    as that found on the archive and also checks that all files have the same size (327680000 by default).
    '''
    if not directory:
        directory = "/astro/mwaops/vcs/{0}/combined/".format(obsID)
    base = "\n Checking file size and number of files for obsID {0} in {1} for ".format(
        obsID, directory)
    n_secs = n_secs if n_secs else 1
    logger.info(base +
                "gps times {0} to {1}".format(startsec, startsec + n_secs -
                                              1) if startsec else base +
                "the whole time range.")
    required_size = required_size
    # we need to get the number of unique seconds from the file names
    meta = getmeta(service='obs', params={'obs_id': obsID})
    files = np.array(list(meta['files'].keys()))
    mask = np.array(['.dat' in file for file in files])
    if not startsec:
        times = [time[11:21] for time in files[mask]]
        n_secs = len(set(times))
        command = "ls -l %s/*ch*.dat | ((tee /dev/fd/5 | wc -l >/dev/fd/4) 5>&1 | " %(directory) + \
            "awk '($5!=%s){print $9}' | tee >> %s/%s_all.txt | xargs rm -rf) 4>&1;" %(required_size, directory, obsID) + \
            "cat %s/%s_all.txt; rm -rf %s/%s_all.txt" %(directory, obsID, directory, obsID)
        output = subprocess.Popen([command],
                                  stdout=subprocess.PIPE,
                                  shell=True).stdout
    else:
        output = subprocess.Popen(["count=0;for sec in `seq -w %s %s `;do let count=${count}+`ls -l %s/*${sec}*ch*.dat | " %(startsec, startsec+n_secs-1, directory) + \
                                       "((tee /dev/fd/5 | wc -l >/dev/fd/4) 5>&1 | awk '($5!=%s) " %(required_size) + \
                                       "{print $9}' | tee >> %s/errors_%s.txt | xargs rm -rf) 4>&1`;done;" %(directory,startsec) +\
                                       "echo ${count}; cat %s/errors_%s.txt;rm -rf %s/errors_%s.txt" %(directory,startsec,directory,startsec)],
                                  stdout=subprocess.PIPE, shell=True).stdout

    output = output.readlines()
    files_in_dir = int(output[0].strip())

    expected_files = n_secs * 25
    error = False
    error, n_ics = check_recombine_ics(directory=directory, \
                                           startsec=startsec, n_secs=n_secs, required_size=required_size_ics)
    files_in_dir += n_ics
    if not files_in_dir == expected_files:
        logger.error("We have {0} files but expected {1}".format(
            files_in_dir, expected_files))
        error = True
    for line in output[1:]:
        if b'dat' in line:
            logger.warning("Deleted {0} due to wrong size.".format(
                line.strip()))
            error = True
    if not error:
        logger.info("We have all {0} files as expected.".format(files_in_dir))
    return error
Esempio n. 2
0
def get_delay_steps(obs):
    beam_meta_data = getmeta(service='obs', params={'obs_id':obs})
    ra = beam_meta_data[u'metadata'][u'ra_pointing']
    dec = beam_meta_data[u'metadata'][u'dec_pointing']
    duration = beam_meta_data[u'stoptime'] - beam_meta_data[u'starttime'] #gps time
    xdelays = beam_meta_data[u'rfstreams'][u"0"][u'xdelays']

    minfreq = float(min(beam_meta_data[u'rfstreams'][u"0"][u'frequencies']))
    maxfreq = float(max(beam_meta_data[u'rfstreams'][u"0"][u'frequencies']))
    channels = beam_meta_data[u'rfstreams'][u"0"][u'frequencies']
    centrefreq = 1.28 * (minfreq + (maxfreq - minfreq) / 2)

    return  obs, ra, dec, duration, xdelays, centrefreq, channels
Esempio n. 3
0
def get_obs_metadata(obs):
    beam_meta_data = getmeta(service='obs', params={'obs_id': obs})
    channels = beam_meta_data[u'rfstreams'][u"0"][u'frequencies']
    freqs = [float(c) * 1.28 for c in channels]
    xdelays = beam_meta_data[u'rfstreams'][u"0"][u'xdelays']
    #pythodelays = beam_meta_data[u'rfstreams'][u"0"][u'xdelays']
    ydelays = beam_meta_data[u'rfstreams'][u"0"][u'ydelays']
    _, pointing_AZ, pointing_ZA = mwa_alt_az_za(obs)

    return {
        "channels": channels,
        "frequencies": freqs,
        "xdelays": xdelays,
        "ydelays": ydelays,
        "az": pointing_AZ,
        "za": pointing_ZA
    }
Esempio n. 4
0
def get_files_and_sizes(obsID, mode):
    if mode == 'raw':
        suffix = '.dat'
    elif mode == 'tar_ics':
        suffix = '.tar'
    elif mode == 'ics':
        suffix = '_ics.dat'
    else:
        logger.error("Wrong mode supplied. Options are raw, tar_ics, and ics")
        return
    logger.info(
        "Retrieving file info from MWA database for all {0} files...".format(
            suffix))
    meta = getmeta(service='obs', params={'obs_id': obsID, 'nocache': 1})
    # 'nocache' is used above so we get don't use the cached metadata as that could
    # be out of data so we force it to get up to date values
    files = np.array(list(meta['files'].keys()))
    files_masked = []
    sizes = []
    for f in files:
        if suffix in f:
            sizes.append(meta['files'][f]['size'])
            files_masked.append(f)
    #mask = np.array([suffix in file for file in files])
    #files = files[mask]
    #sizes=np.array([meta['files'][f]['size'] for f in files])
    logger.info(
        "...Done. Expect all on database to be {0} bytes in size...".format(
            sizes[0]))

    size_check = True
    for s in sizes:
        if not s == sizes[0]:
            size_check = False
    #if np.all(sizes == sizes[0]): #this stopped working for some reason
    if size_check:
        logger.info("...yep they are. Now checking on disk.")
        return files_masked, suffix, sizes[0]
    else:
        logger.error("Not all files have the same size. Check your data!")
        logger.error("{0}".format(np.vstack((files, sizes)).T))
        return
Esempio n. 5
0
def find_obsids_meta_pages(params={'mode': 'VOLTAGE_START'}):
    """
    Loops over pages for each page for MWA metadata calls
    """
    obsid_list = []
    temp = []
    page = 1
    #need to ask for a page of results at a time
    while len(temp) == 200 or page == 1:
        params['page'] = page
        logger.debug("Page: {0}   params: {1}".format(page, params))
        temp = getmeta(service='find', params=params)
        if temp is not None:
            # if there are non obs in the field (which is rare) None is returned
            for row in temp:
                obsid_list.append(row[0])
        else:
            temp = []
        page += 1

    return obsid_list
Esempio n. 6
0
    def construct_base_string(self):
        """Construct the basic string to be written to the RTS config file.
        This string will then be edit with regexp to update the relevant details.

        Returns
        -------
        file_str : str
            The base string to be written to an RTS configuration srcipt after manipulation.

        Raises
        ------
        CalibrationError
            When there is a problem with some of the observation information and/or its manipulation.
        """
        # get calibrator observation information from database
        logger.info("Querying metadata database for obsevation information...")
        obsinfo = getmeta(service='obs',
                          params={'obs_id': str(self.cal_obsid)})

        # quick check to make sure what's returned is actually real data
        if obsinfo[u'metadata'] is None:
            errmsg = "Metadata database error (metadata empty). Maybe an invalid obs ID?"
            logger.error(errmsg)
            raise CalibrationError(errmsg)

        # get the RA/Dec pointing for the primary beam
        ra_pointing_degs = obsinfo['metadata']['ra_pointing']
        dec_pointing_degs = obsinfo['metadata']['dec_pointing']

        # now get the absolute channels
        self.channels = obsinfo[u'rfstreams'][u"0"][u'frequencies']
        # and figure out the MaxFrequency parameter
        self.max_frequency = 1.28 * (
            max(self.channels) + 1
        )  # this way we ensure that MaxFrequency is applicable for ALL subbands

        # use the same operations as in timeconvert.py for our specific need
        logger.info("Converting times with astropy")
        #mwa_loc = EarthLocation.of_site('Murchison Widefield Array')
        mwa_loc = EarthLocation.from_geodetic(lon="116:40:14.93",
                                              lat="-26:42:11.95",
                                              height=377.8)
        #Astropy formating
        utctime = strptime(self.utctime, '%Y%m%d%H%M%S')
        a_time = strftime('%Y-%m-%dT%H:%M:%S', utctime)
        obstime = Time(a_time, format='fits', scale='utc', location=mwa_loc)
        lst_in_hours = obstime.sidereal_time('apparent').hourangle
        jd = obstime.jd
        logger.info("   LST: {0}".format(lst_in_hours))
        logger.info("   JD : {0}".format(jd))

        # set the HA of the image centre to the primary beam HA
        logger.debug("Determining HA and DEC for primary beam")
        self.JD = jd
        pb_ha_hours = (ra_pointing_degs / 360.0) * 24.0
        self.PB_HA = lst_in_hours - pb_ha_hours
        self.PB_DEC = dec_pointing_degs

        logger.debug("Primary beam: HA = {0} hrs, Dec = {1} deg".format(
            self.PB_HA, self.PB_DEC))
        logger.debug("JD = {0}".format(self.JD))

        # get the lowest frequency channel
        freqs = obsinfo['rfstreams']['0']['frequencies']
        start_channel = freqs[0]

        self.freq_base = start_channel * 1.28e6 - 0.64e6 + 15e3  # frequency base in Hz (based on Steve Ord's logic)
        self.freq_base = self.freq_base / 1.0e6  # convert to MHz

        logger.debug("Frequency lower edge = {0} MHz".format(self.freq_base))

        # make metafits file formatted for RTS
        self.metafits_RTSform = self.metafits.split("_metafits_ppds.fits")[0]
        logger.debug("RTS form metafits location: {0}".format(
            self.metafits_RTSform))

        # create the final file string, expanding symlinks to real paths
        logger.info("Constructing base RTS configuration script content")
        file_str = """
ReadAllFromSingleFile=
BaseFilename={base}/*_gpubox
ReadGpuboxDirect={read_direct}
UseCorrelatorInput={use_corr_input}

ReadMetafitsFile=1
MetafitsFilename={metafits_file}

DoCalibration=
doMWArxCorrections=1
doRawDataCorrections=1
doRFIflagging=0
useFastPrimaryBeamModels={beam_model_bool}
generateDIjones=1
applyDIcalibration=1
UsePacketInput=0
UseThreadedVI=1

MaxFrequency={max_freq}
ObservationFrequencyBase={base_freq}
ObservationTimeBase={base_time}
ObservationPointCentreHA={obs_ha}
ObservationPointCentreDec={obs_dec}
ChannelBandwidth={fcbw}
NumberOfChannels={nchan}

CorrDumpsPerCadence={corr_dumps_per_cadence}
CorrDumpTime={corr_dump_time}
NumberOfIntegrationBins={n_int_bins}
NumberOfIterations=1

StartProcessingAt=0

ArrayPositionLat={array_lat}
ArrayPositionLong={array_lon}
ArrayNumberOfStations=128

ArrayFile=

SourceCatalogueFile={source_list}
NumberOfCalibrators=1
NumberOfSourcesToPeel=0
calBaselineMin=20.0
calShortBaselineTaper=40.0
FieldOfViewDegrees=1""".format(base=self.data_dir,
                               read_direct=self.readDirect,
                               use_corr_input=self.useCorrInput,
                               metafits_file=self.metafits_RTSform,
                               beam_model_bool=self.beam_model_bool,
                               max_freq=self.max_frequency,
                               base_freq=self.freq_base,
                               base_time=self.JD,
                               obs_ha=self.PB_HA,
                               obs_dec=self.PB_DEC,
                               fcbw=self.fine_cbw,
                               nchan=self.nfine_chan,
                               corr_dumps_per_cadence=self.n_dumps_to_average,
                               corr_dump_time=self.corr_dump_time,
                               n_int_bins=self.n_integration_bins,
                               array_lat=self.ArrayPositionLat,
                               array_lon=self.ArrayPositionLong,
                               source_list=self.source_list)

        return file_str
Esempio n. 7
0
obsid = args.observation

# Check if already spliced
if glob.glob('{0}/{1}*fits'.format(args.work_dir, args.observation)) and \
   not glob.glob('{0}/*_{1}*fits'.format(args.work_dir, args.observation)):
    print('All files are already spliced so exiting')
    exit()

# Get frequency channels
if args.channels:
    channels = args.channels
else:
    print(
        "Obtaining metadata from http://mwa-metadata01.pawsey.org.au/metadata/ for OBS ID: "
        + str(obsid))
    beam_meta_data = meta.getmeta(service='obs', params={'obs_id': obsid})
    channels = beam_meta_data[u'rfstreams'][u"0"][u'frequencies']
print("Chan order: {}".format(channels))

#hostname = socket.gethostname()
hostname = 'temp'
if hostname.startswith('john') or hostname.startswith('bryan'):
    #If on ozstar use their SSD to improve I/O
    SSD_file_dir = '{}/'.format(os.environ['JOBFS'])
    print(SSD_file_dir)
else:
    SSD_file_dir = ''

# Move into working dir
old_dir = os.getcwd()
if hostname.startswith('john') or hostname.startswith('bryan'):
Esempio n. 8
0
def get_files_and_sizes(obsID, mode, mintime=0, maxtime=2000000000):
    """
    Get files and sizes from the MWA metadata server and check that they're all the same size

    Parameters:
    -----------
    obsID: int
        The MWA observation ID
    mode: str
        The typ of file from 'raw', 'tar_ics' and 'ics'
    mintime: int
        The minimum GPS time of observations to check (inclusive, >=)  Default: 0
    maxtime: int
        The maximum GPS time of observations to check (exculsive, <)  Default: 2000000000

    Returns:
    --------
    files_masked, suffix, sizes[0]: list
        files_masked: list of the files with the input mode/suffix
        suffix:       '.dat', '.tar' or '_ics.dat' depnding on the input mode
        sizes[0]:     size of files in bytes
    """
    if mode == 'raw':
        suffix = '.dat'
    elif mode == 'tar_ics':
        suffix = '.tar'
    elif mode == 'ics':
        suffix = '_ics.dat'
    else:
        logger.error("Wrong mode supplied. Options are raw, tar_ics, and ics")
        return
    logger.info(
        "Retrieving file info from MWA database for all {0} files...".format(
            suffix))
    files_meta = getmeta(service='data_files',
                         params={
                             'obs_id': obsID,
                             'nocache': 1,
                             'mintime': mintime,
                             'maxtime': maxtime
                         })
    # 'nocache' is used above so we get don't use the cached metadata as that could
    # be out of data so we force it to get up to date values
    files = np.array(list(files_meta.keys()))
    files_masked = []
    sizes = []
    for f in files:
        if suffix in f:
            sizes.append(files_meta[f]['size'])
            files_masked.append(f)
    logger.info(
        "...Done. Expect all on database to be {0} bytes in size...".format(
            sizes[0]))

    size_check = True
    for s in sizes:
        if not s == sizes[0]:
            size_check = False
    if size_check:
        logger.info("...yep they are. Now checking on disk.")
        return files_masked, suffix, sizes[0]
    else:
        logger.error("Not all files have the same size. Check your data!")
        logger.error("{0}".format(np.vstack((files, sizes)).T))
        return
def find_sources_in_obs(obsid_list, names_ra_dec,
                        obs_for_source=False, dt_input=100, beam='analytic',
                        min_power=0.3, cal_check=False, all_volt=False,
                        degrees_check=False, metadata_list=None):
    """
    Either creates text files for each MWA obs ID of each source within it or a text
    file for each source with each MWA obs is that the source is in.
    Args:
        obsid_list: list of MWA obs IDs
        names_ra_dec: [[source_name, ra, dec]]
        dt: the time step in seconds to do power calculations
        beam: beam simulation type ['analytic', 'advanced', 'full_EE']
        min_power: if above the minium power assumes it's in the beam
        cal_check: checks the MWA pulsar database if there is a calibration for the obsid
        all_volt: Use all voltages observations including some inital test data
                  with incorrect formats
        degrees_check: if false ra and dec is in hms, if true in degrees
    Output [output_data, obsid_meta]:
        output_data: The format of output_data is dependant on obs_for_source.
                     If obs_for_source is True:
                        output_data = {jname:[[obsid, duration, enter, exit, max_power],
                                              [obsid, duration, enter, exit, max_power]]}
                     If obs_for_source is False:
                        ouput_data = {obsid:[[jname, enter, exit, max_power],
                                             [jname, enter, exit, max_power]]}
        obsid_meta: a list of the output of get_common_obs_metadata for each obsid
    """
    #prepares metadata calls and calculates power
    powers = []
    #powers[obsid][source][time][freq]
    obsid_meta = []
    obsid_to_remove = []

    for i, obsid in enumerate(obsid_list):
        if metadata_list:
            beam_meta_data, full_meta = metadata_list[i]
        else:
            beam_meta_data, full_meta = get_common_obs_metadata(obsid, return_all=True)
        #beam_meta_data = obsid,ra_obs,dec_obs,time_obs,delays,centrefreq,channels

        if dt_input * 4 >  beam_meta_data[3]:
            # If the observation time is very short then a smaller dt time is required
            # to get enough ower imformation
            dt = int(beam_meta_data[3] / 4.)
        else:
            dt = dt_input
        logger.debug("obsid: {0}, time_obs {1} s, dt {2} s".format(obsid, beam_meta_data[3], dt))

        #check for raw volatge files
        filedata = getmeta(service='data_files', params={'obs_id':obsid, 'nocache':1})
        keys = filedata.keys()
        check = False
        for k in keys:
            if '.dat' in k: #TODO check if is still robust
                check = True
        if check or all_volt:
            powers.append(get_beam_power_over_time(beam_meta_data, names_ra_dec,
                                    dt=dt, centeronly=True, verbose=False,
                                    option=beam, degrees=degrees_check))
            obsid_meta.append(beam_meta_data)
        else:
            logger.warning('No raw voltage files for %s' % obsid)
            obsid_to_remove.append(obsid)
    for otr in obsid_to_remove:
        obsid_list.remove(otr)

    #chooses whether to list the source in each obs or the obs for each source
    output_data = {}
    if obs_for_source:
        for sn, source in enumerate(names_ra_dec):
            source_data = []
            for on, obsid in enumerate(obsid_list):
                source_ob_power = powers[on][sn]
                if max(source_ob_power) > min_power:
                    duration = obsid_meta[on][3]
                    centre_freq = obsid_meta[on][5] #MHz
                    channels = obsid_meta[on][6]
                    bandwidth = (channels[-1] - channels[0] + 1.)*1.28 #MHz
                    logger.debug("Running beam_enter_exit on obsid: {}".format(obsid))
                    enter, exit = beam_enter_exit(source_ob_power,duration,
                                                  dt=dt, min_power=min_power)
                    if enter is not None:
                        source_data.append([obsid, duration, enter, exit,
                                            max(source_ob_power)[0],
                                            centre_freq, bandwidth])
            # For each source make a dictionary key that contains a list of
            # lists of the data for each obsid
            output_data[source[0]] = source_data

    else:
        #output a list of sorces for each obs
        for on, obsid in enumerate(obsid_list):
            duration = obsid_meta[on][3]
            obsid_data = []
            for sn, source in enumerate(names_ra_dec):
                source_ob_power = powers[on][sn]
                if max(source_ob_power) > min_power:
                    enter, exit = beam_enter_exit(source_ob_power, duration,
                                                  dt=dt, min_power=min_power)
                    obsid_data.append([source[0], enter, exit, max(source_ob_power)[0]])
            # For each obsid make a dictionary key that contains a list of
            # lists of the data for each source/pulsar
            output_data[obsid] = obsid_data

    return output_data, obsid_meta
Esempio n. 10
0
def plotSkyMap(obsfile, targetfile, oname, show_psrcat=False, show_mwa_sky=False, show_mwa_unique=False):


    fig = plt.figure()
    ax = fig.add_subplot(111, projection="mollweide")

    mwa_dec_lim = 30
    mwa_only_dec_lim = -50

    if show_mwa_sky:
        # Make a patch that is transformable through axis projection
        # and highlight the visible sky for the MWA
        Path = mpath.Path
        ra_start = -np.pi
        ra_end = np.pi
        dec_start = -np.pi / 2
        dec_end = np.radians(mwa_dec_lim)
        path_data = [
                    (Path.MOVETO, (ra_start, dec_start)),
                    (Path.LINETO, (ra_start, dec_end)),
                    (Path.LINETO, (ra_end, dec_end)),
                    (Path.LINETO, (ra_end, dec_start)),
                    (Path.CLOSEPOLY, (ra_end, dec_start)),
                    ]
        codes, verts = zip(*path_data)
        path = mpath.Path(verts, codes)
        patch = mpatches.PathPatch(path, lw=0, ec="lightskyblue", fc="lightskyblue", label="All MWA sky")
        ax.add_patch(patch)

    if show_mwa_unique:
        # Make a patch that is transformable through axis projection
        # and highlight the part of the sky ONLY visible to the MWA
        ra_start = -np.pi
        ra_end = np.pi
        dec_start = -np.pi / 2
        dec_end = np.radians(mwa_only_dec_lim)
        path_data = [
                    (Path.MOVETO, (ra_start, dec_start)),
                    (Path.LINETO, (ra_start, dec_end)),
                    (Path.LINETO, (ra_end, dec_end)),
                    (Path.LINETO, (ra_end, dec_start)),
                    (Path.CLOSEPOLY, (ra_end, dec_start)),
                    ]
        codes, verts = zip(*path_data)
        path = mpath.Path(verts, codes)
        patch = mpatches.PathPatch(path, lw=0, ec="lightgreen", fc="lightgreen", label="Unique MWA sky")
        ax.add_patch(patch)

    if show_psrcat:
        # Retrieve the local installed PSRCAT catalogue and plot those pulsar positions
        cmd = 'psrcat -o short_csv -nocand -nonumber -c "Jname RAJ DECJ" | sed "2d" > psrcat.csv'
        subprocess.call(cmd, shell=True)
        psrcat_coords = read_data("psrcat.csv", delim=";")
        os.remove("psrcat.csv")

        # Create a mask for pulsar in and out of the declination limit of the MWA
        maskGood = psrcat_coords.dec.wrap_at(180*u.deg).deg < mwa_dec_lim
        maskBad = psrcat_coords.dec.wrap_at(180*u.deg).deg >= mwa_dec_lim

        psrcat_ra_good = -psrcat_coords.ra.wrap_at(180*u.deg).rad[maskGood] # negative because RA increases to the West
        psrcat_dec_good = psrcat_coords.dec.wrap_at(180*u.deg).rad[maskGood]

        psrcat_ra_bad = -psrcat_coords.ra.wrap_at(180*u.deg).rad[maskBad] # negative because RA increases to the West
        psrcat_dec_bad = psrcat_coords.dec.wrap_at(180*u.deg).rad[maskBad]

        # Now plot the pulsar locations
        ax.scatter(psrcat_ra_good, psrcat_dec_good, 0.01, marker="x", color="0.4", zorder=1.4)
        ax.scatter(psrcat_ra_bad, psrcat_dec_bad, 0.01, marker="x", color="0.8", zorder=1.4)


    # Calculate beam patterns and plot contours
    levels = np.arange(0.25, 1., 0.05)
    cmap = plt.get_cmap("cubehelix_r")

    obsids = read_data(obsfile, coords=False)["OBSID"]
    for obsid in obsids:
        #print "Accessing database for observation: {0}".format(obsid)
        logger.info("Accessing database for observation: {0}".format(obsid))

        # TODO: I think this process is now implemented in a function in mwa_metadb_utils, need to double check
        beam_meta_data = getmeta(service='obs', params={'obs_id': obsid})

        ra = beam_meta_data[u'metadata'][u'ra_pointing']
        dec = beam_meta_data[u'metadata'][u'dec_pointing']
        duration = beam_meta_data[u'stoptime'] - beam_meta_data[u'starttime'] #gps time
        delays = beam_meta_data[u'rfstreams'][u'0'][u'xdelays']

        minfreq = float(min(beam_meta_data[u'rfstreams'][u"0"][u'frequencies']))
        maxfreq = float(max(beam_meta_data[u'rfstreams'][u"0"][u'frequencies']))
        centrefreq = 1.28e6 * (minfreq + (maxfreq-minfreq)/2) #in MHz
        channels = beam_meta_data[u'rfstreams'][u"0"][u'frequencies']

        metadata = [obsid, ra, dec, duration, delays, centrefreq, channels]
        beam_meta_data, full_meta = get_common_obs_metadata(obsid, return_all = True)

        # Create a meshgrid over which to iterate
        Dec = [] ; RA = []
        map_dec_range = np.arange(-89, 90, 3)
        map_ra_range = np.arange(0, 360, 3)
        for i in map_dec_range:
            for j in map_ra_range:
                Dec.append(i)
                RA.append(j)
        RADecIndex = np.arange(len(RA))
        names_ra_dec = np.column_stack((RADecIndex, RA, Dec))

        #print "Creating beam patterns..."
        time_intervals = 600 # seconds

        powout = get_beam_power_over_time(beam_meta_data, names_ra_dec, dt=time_intervals, degrees=True)
        z=[] ; x=[] ; y=[]
        for c in range(len(RA)):
            temppower = 0.
            for t in range(powout.shape[1]):
                power_ra = powout[c,t,0]
                if power_ra > temppower:
                    temppower = power_ra
            z.append(temppower)
            if RA[c] > 180:
                x.append(-RA[c]/180.*np.pi+2*np.pi)
            else:
                x.append(-RA[c]/180.*np.pi)

            y.append(Dec[c]/180.*np.pi)

        nx=np.array(x) ; ny=np.array(y); nz=np.array(z)

        #print "Plotting beam pattern contours..."
        logger.info("Plotting beam pattern contours...")
        # Set vmin and vmax to ensure the beam patterns are on the same color scale
        # and plot the beam pattern contours on the map

        #c = ax.tricontour(wrapped_ra, wrapped_dec, final_pattern_power, levels=levels, cmap=cmap, vmin=levels.min(), vmax=levels.max(), zorder=1.3)
        c = ax.tricontour(nx, ny, nz, levels=levels, cmap=cmap, vmin=levels.min(), vmax=levels.max(), zorder=1.3)

    # Make a figure color scale based on the contour sets (which all have the same max/min values
    fig.colorbar(c, fraction=0.02, pad=0.03, label="Zenith normalised power")


    # Plot the target positions, using Astropy to wrap at correct RA
    target_coords = read_data(targetfile)
    wrapped_target_ra = -target_coords.ra.wrap_at(180*u.deg).rad # negative because RA increases to the West
    wrapped_target_dec = target_coords.dec.wrap_at(180*u.deg).rad
    #print "Plotting target source positions..."
    logger.info("Plotting target source positions...")
    ax.scatter(wrapped_target_ra, wrapped_target_dec, 10, marker="x", color="red", zorder=1.6, label="Target sources")

    xtick_labels = ["10h", "8h", "6h", "4h", "2h", "0h", "22h", "20h", "18h", "16h", "14h"]
    ax.set_xticklabels(xtick_labels, color="0.2")
    ax.set_xlabel("Right Ascension")
    ax.set_ylabel("Declination")
    ax.grid(True, color="k", lw=0.5, ls=":")

    # Place upper-right corner of legend at specified Axis coordinates
    ax.legend(loc="upper right", bbox_to_anchor=(1.02, 0.08), numpoints=1, borderaxespad=0., fontsize=6)


    plt.savefig(oname, format="eps", bbox_inches="tight")