Example #1
0
def heraBeam(loc,f,params):
    obs=params[0]
    df=params[1]
    fc=params[2]
    dPhi=np.radians(params[3])
    dTheta=np.radians(params[4])
    beamCube=params[5]
    pos=ephem.FixedBody()
    lst=np.degrees(float(repr(obs.sidereal_time())))
    lat=float(repr(obs.lat))*180./np.pi
    ra=loc[:,0]
    dec=loc[:,1]
    az,alt=ephem_utils.eq2horz(lst-ra,dec,lat)
    theta=(90.-alt)*math.pi/180.
    phi=az*math.pi/180.
    thInd=np.round(theta/dTheta).astype(int)
    phInd=np.round(phi/dPhi).astype(int)
    output=np.zeros(len(ra))
    fInd=np.round((f-fc)/df)+beamCube.shape[0]/2
    inFieldTh=np.logical_and(thInd>=0,thInd<beamCube.shape[2])
    inFieldPh=np.logical_and(phInd>=0,phInd<beamCube.shape[1])
    inField=np.logical_and(inFieldTh,inFieldPh)
    if(fInd>=0 and fInd<beamCube.shape[0]):
        output[inField]=beamCube[fInd,phInd[inField],thInd[inField]]
    return output
Example #2
0
def mwabeam(loc,f,params):
    #az,alt=obs.az,el(ra,dec)
    obs=params[1]
    pcentre=params[0]
    #find az el of pointing centre
    pos=ephem.FixedBody()
    pos._ra=np.radians(pcentre[0])
    pos._dec=np.radians(pcentre[1])
    pos.compute(obs)
    az=float(repr(ephem.degrees(pos.az)))*180./np.pi
    alt=float(repr(ephem.degrees(pos.alt)))*180./np.pi
    #find closets sweet splot
    cpc=[az,alt]
    #    print 'center='+str(cpc)
    sep=geom.arc_length_list(mwaSweetSpots[:,:2],cpc)
    #print sep
    delays=mwaSweetSpots[np.where(sep==sep.min())[0][0],3:].astype(int)
    ra=loc[:,0]
    dec=loc[:,1]
    #azAlt=np.zeros(loc.shape)
    pos=ephem.FixedBody()
#    for ss in range(azAlt.shape[0]):
#        pos._ra=np.radians(loc[ss,0])
#        pos._dec=np.radians(loc[ss,1])
#        pos.compute(obs)
#        az=float(repr(ephem.degrees(pos.az)))
#        alt=float(repr(ephem.degrees(pos.alt)))
#        azAlt[ss,:]=az,alt
    lst=np.degrees(float(repr(obs.sidereal_time())))
    #print 'lat='+str(float(repr(obs.lat))*180./np.pi)
    lat=float(repr(obs.lat))*180./np.pi
    #print 'delays='+str(delays)
    az,alt=ephem_utils.eq2horz(lst-ra,dec,lat)
    theta=(90.-alt)*math.pi/180.
    phi=az*math.pi/180.
    dip_sep=mwa_primary_beam._DIPOLE_SEPARATION
    dipheight=mwa_primary_beam._DIPOLE_HEIGHT
    rX,rY=mwa_primary_beam.MWA_Tile_analytic(theta,phi,freq=f,delays=delays,dipheight=dipheight,dip_sep=dip_sep,zenithnorm=True,power=True)
    #for now let's return the stokes sum
    return (rX+rY)/2.
Example #3
0
    sys.exit(1)

RA, Dec = 69.3158945833333, -47.2523944444444
gpstime = 1063400456
filename = '1063400456_corr_phased.fits'

o = get_observation_info.MWA_Observation(gpstime, db=db)

mwatime = ephem_utils.MWATime(gpstime=gpstime + o.duration / 2)
frequency = o.center_channel * 1.28e6
delays = o.delays

RAnow, Decnow = ephem_utils.precess(RA, Dec, 2000, mwatime.epoch)
HA = float(mwatime.LST) - RAnow
mwa = ephem_utils.Obs[ephem_utils.obscode['MWA']]
Az, Alt = ephem_utils.eq2horz(HA, Decnow, mwa.lat)
theta = (90 - Alt) * math.pi / 180
phi = Az * math.pi / 180


def MWA_Jones_Analytic(theta,
                       phi,
                       ha,
                       dec,
                       freq=100.0e6,
                       delays=None,
                       zenithnorm=True):
    c = 2.998e8
    # wavelength in meters
    lam = c / freq
def get_beam_power_obsforsource(obsid_data,
                   sources, coord1, coord2, names,
                   dt=296,
                   centeronly=True,
                   verbose=False,
                   min_power=0.3):
    """
    obsid_data = [obsid,ra, dec, time, delays,centrefreq, channels]
    sources=[names,coord1,coord2] #astropy table coloumn names

    Calulates the power (gain at coordinate/gain at zenith) for each source and if it is above
    the min_power then it outputs it to the text file.
    """
    print "Calculating beam power"
    Powers= []
    for ob in obsid_data:
        obsid,ra, dec, time, delays,centrefreq, channels = ob
        
        starttimes=np.arange(0,time,dt)
        stoptimes=starttimes+dt
        stoptimes[stoptimes>time]=time
        Ntimes=len(starttimes)
        midtimes=float(obsid)+0.5*(starttimes+stoptimes)
        
        mwa = ephem_utils.Obs[ephem_utils.obscode['MWA']]
        # determine the LST
        observer = ephem.Observer()
        # make sure no refraction is included
        observer.pressure = 0
        observer.long = mwa.long / ephem_utils.DEG_IN_RADIAN
        observer.lat = mwa.lat / ephem_utils.DEG_IN_RADIAN
        observer.elevation = mwa.elev

        if not centeronly:
            PowersX=np.zeros((len(sources),
                                 Ntimes,
                                 len(channels)))
            PowersY=np.zeros((len(sources),
                                 Ntimes,
                                 len(channels)))
            # in Hz
            frequencies=np.array(channels)*1.28e6
        else:
            PowersX=np.zeros((len(sources),
                                 Ntimes,1))
            PowersY=np.zeros((len(sources),
                                 Ntimes,1))
            frequencies=[centrefreq]

        RAs, Decs = sex2deg(sources[coord1],sources[coord2])
        if len(RAs)==0:
            sys.stderr.write('Must supply >=1 source positions\n')
            return None
        if not len(RAs)==len(Decs):
            sys.stderr.write('Must supply equal numbers of RAs and Decs\n')
            return None
        for itime in xrange(Ntimes):
            obstime = Time(midtimes[itime],format='gps',scale='utc')
            observer.date = obstime.datetime.strftime('%Y/%m/%d %H:%M:%S')
            LST_hours = observer.sidereal_time() * ephem_utils.HRS_IN_RADIAN

            HAs = -RAs + LST_hours * 15
            Azs, Alts = ephem_utils.eq2horz(HAs, Decs, mwa.lat)
            # go from altitude to zenith angle
            theta=np.radians(90-Alts)
            phi=np.radians(Azs)
            
            for ifreq in xrange(len(frequencies)):
                rX,rY=primary_beam.MWA_Tile_analytic(theta, phi,
                                                     freq=frequencies[ifreq], delays=delays,
                                                     zenithnorm=True,
                                                     power=True)
                PowersX[:,itime,ifreq]=rX
                PowersY[:,itime,ifreq]=rY
        #temp_power [#sources, #times, #frequencies]
        temp_power=0.5*(PowersX+PowersY)
        counter = 0
        for sourc in temp_power:
            counter = counter + 1
            if max(sourc) > min_power:
                print obsid
                
                for imax in range(len(sourc)):
                    if sourc[imax] == max(sourc):
                        max_time = midtimes[imax] - obsid
                        Powers.append([sources[names][counter-1], obsid, time, max_time, sourc, imax])
    
    for sourc in sources:    
        outputfile = str(args.output)
        os.system( 'rm -f ' + outputfile + str(sourc[names]) + '_analytic_beam.txt')
        with open(outputfile + str(sourc[names]) + '_analytic_beam.txt',"wb") as out_list:
            out_list.write('All of the observation IDs that the analytic beam model calculated a power of '\
                           + str(min_power) + ' or greater for the source: ' + str(sourc[names]) + '\n' +\
                           'Obs ID     Duration  Time during observation that the power was at a'+\
                           ' maximum    File number source entered    File number source exited\n')
            for p in Powers:
                if str(p[0]) == str(sourc[names]):
                    enter, exit = beam_enter_exit(min_power, p[4], p[5], dt, time)
                    out_list.write(str(p[1]) + ' ' + str(p[2]) + ' ' + str(p[3]) + ' ' + str(enter) +\
                                   ' ' + str(exit) + "\n")
           
    print "A list of observation IDs that containt: " + str(sourc[names]) + \
              " has been output to the text file: " + str(sourc[names]) + '_analytic_beam.txt'             
    return 
def get_beam_power(obsid_data,
                   sources,
                   dt=296,
                   centeronly=True,
                   verbose=False,
                   min_power=0.6):
    """
    obsid_data = [obsid,ra, dec, time, delays,centrefreq, channels]
    sources=[names,coord1,coord2] #astropy table coloumn names

    Calulates the power (gain at coordinate/gain at zenith) for each source and if it is above
    the min_power then it outputs it to the text file.

    """
    #print "Calculating beam power"
    obsid, ra, dec, time, delays, centrefreq, channels = obsid_data

    #starttimes=np.arange(0,time,dt)
    starttimes = np.arange(0, time, time)
    stoptimes = starttimes + dt
    stoptimes[stoptimes > time] = time
    Ntimes = len(starttimes)
    midtimes = float(obsid) + 0.5 * (starttimes + stoptimes)

    mwa = ephem_utils.Obs[ephem_utils.obscode['MWA']]
    # determine the LST
    observer = ephem.Observer()
    # make sure no refraction is included
    observer.pressure = 0
    observer.long = mwa.long / ephem_utils.DEG_IN_RADIAN
    observer.lat = mwa.lat / ephem_utils.DEG_IN_RADIAN
    observer.elevation = mwa.elev

    if not centeronly:
        PowersX = np.zeros((len(sources), Ntimes, len(channels)))
        PowersY = np.zeros((len(sources), Ntimes, len(channels)))
        # in Hz
        frequencies = np.array(channels) * 1.28e6
    else:
        PowersX = np.zeros((len(sources), Ntimes, 1))
        PowersY = np.zeros((len(sources), Ntimes, 1))
        frequencies = [centrefreq]

    RAs = np.array([x[0] for x in sources])
    Decs = np.array([x[1] for x in sources])
    if len(RAs) == 0:
        sys.stderr.write('Must supply >=1 source positions\n')
        return None
    if not len(RAs) == len(Decs):
        sys.stderr.write('Must supply equal numbers of RAs and Decs\n')
        return None
    for itime in xrange(Ntimes):
        obstime = Time(midtimes[itime], format='gps', scale='utc')
        observer.date = obstime.datetime.strftime('%Y/%m/%d %H:%M:%S')
        LST_hours = observer.sidereal_time() * ephem_utils.HRS_IN_RADIAN

        HAs = -RAs + LST_hours * 15
        Azs, Alts = ephem_utils.eq2horz(HAs, Decs, mwa.lat)
        # go from altitude to zenith angle
        theta = np.radians(90 - Alts)
        phi = np.radians(Azs)

        for ifreq in xrange(len(frequencies)):
            rX, rY = primary_beam.MWA_Tile_analytic(theta,
                                                    phi,
                                                    freq=frequencies[ifreq],
                                                    delays=delays,
                                                    zenithnorm=True,
                                                    power=True)
            PowersX[:, itime, ifreq] = rX
            PowersY[:, itime, ifreq] = rY

    #Power [#sources, #times, #frequencies]
    Powers = 0.5 * (PowersX + PowersY)

    return Powers
Example #6
0
def get_skytemp(datetimestring, delays, frequency, alpha=-2.6, verbose=True):
    """
    Tx,Ty=get_skytemp(datetimestring, delays, frequency, alpha=-2.6, verbose=True)
    not completely sure about the normalization, since the Haslam FITS image is not specific
    
    """
    # get the Haslam 408 MHz map
    dir = os.path.dirname(__file__)
    if (len(dir) == 0):
        dir = '.'
    radio_image_touse = dir + '/' + radio_image

    if not os.path.exists(radio_image_touse):
        logger.error("Could not find 408 MHz image: %s\n" %
                     (radio_image_touse))
        return None
    try:
        if (verbose):
            print "Loading 408 MHz map from %s..." % radio_image_touse
        f = pyfits.open(radio_image_touse)
    except:
        logger.error("Error opening 408 MHz image: %s\n" % (radio_image_touse))
        return None
    skymap = f[0].data[0]

    ra = (f[0].header.get('CRVAL1') +
          (numpy.arange(1, skymap.shape[1] + 1) - f[0].header.get('CRPIX1')) *
          f[0].header.get('CDELT1')) / 15.0
    dec = f[0].header.get(
        'CRVAL2') + (numpy.arange(1, skymap.shape[0] + 1) -
                     f[0].header.get('CRPIX2')) * f[0].header.get('CDELT2')

    # parse the datetimestring
    try:
        yr = int(datetimestring[:4])
        mn = int(datetimestring[4:6])
        dy = int(datetimestring[6:8])
        hour = int(datetimestring[8:10])
        minute = int(datetimestring[10:12])
        second = int(datetimestring[12:14])
    except:
        logger.error('Could not parse datetimestring %s\n' % datetimestring)
        return None
    UT = hour + minute / 60.0 + second / 3600.0
    UTs = '%02d:%02d:%02d' % (hour, minute, second)
    mwa = ephem_utils.Obs[ephem_utils.obscode['MWA']]

    # determine the LST
    observer = ephem.Observer()
    # make sure no refraction is included
    observer.pressure = 0
    observer.long = mwa.long / ephem_utils.DEG_IN_RADIAN
    observer.lat = mwa.lat / ephem_utils.DEG_IN_RADIAN
    observer.elevation = mwa.elev
    observer.date = '%d/%d/%d %s' % (yr, mn, dy, UTs)
    LST_hours = observer.sidereal_time() * ephem_utils.HRS_IN_RADIAN
    LST = ephem_utils.dec2sexstring(LST_hours, digits=0, roundseconds=1)
    if (verbose):
        print "For %02d-%02d-%02d %s UT, LST=%s" % (yr, mn, dy, UTs, LST)

    # use LST to get Az,Alt grid for image
    RA, Dec = numpy.meshgrid(ra * 15, dec)
    #HA=RA-LST_hours*15
    HA = -RA + LST_hours * 15
    Az, Alt = ephem_utils.eq2horz(HA, Dec, mwa.lat)

    if (verbose):
        print "Creating primary beam response for frequency %.2f MHz..." % (
            frequency)
        print "Beamformer delays are %s" % delays
    # get the beam response
    # first go from altitude to zenith angle
    theta = (90 - Alt) * math.pi / 180
    phi = Az * math.pi / 180

    # this is the response for XX and YY
    try:
        respX, respY = primary_beam.MWA_Tile_analytic(
            theta, phi, freq=frequency * 1e6, delays=numpy.array(delays))
    except:
        logger.error('Error creating primary beams\n')
        return None
    rX = numpy.real(numpy.conj(respX) * respX)
    rY = numpy.real(numpy.conj(respY) * respY)

    maskedskymap = numpy.ma.array(skymap, mask=Alt <= 0)
    maskedskymap *= (frequency / 408.0)**alpha
    rX /= rX.sum()
    rY /= rY.sum()
    return ((rX * maskedskymap).sum()) / 10.0, (
        (rY * maskedskymap).sum()) / 10.0
Example #7
0
    if (verbose):
        print "For %02d-%02d-%02d %s UT, LST=%s" % (yr, mn, dy, UTs, LST)

    # this will be the center of the image
    RA0 = 0
    if (center):
        RA0 = LST_hours * 15
    else:
        if (LST_hours > 6 and LST_hours < 18):
            RA0 = 180

    # use LST to get Az,Alt grid for image
    RA, Dec = numpy.meshgrid(ra * 15, dec)
    #HA=RA-LST_hours*15
    HA = -RA + LST_hours * 15
    Az, Alt = ephem_utils.eq2horz(HA, Dec, mwa.lat)

    # get the horizon line
    Az_Horz = numpy.arange(360.0)
    Alt_Horz = numpy.zeros(Az_Horz.shape)
    HA_Horz, Dec_Horz = ephem_utils.horz2eq(Az_Horz, Alt_Horz, mwa.lat)
    #RA_Horz=HA_Horz+LST_hours*15
    RA_Horz = -HA_Horz + LST_hours * 15
    RA_Horz[numpy.where(RA_Horz > 180 + RA0)[0]] -= 360
    RA_Horz[numpy.where(RA_Horz < -180 + RA0)[0]] += 360

    maskedskymap = numpy.where(Alt > 0, skymap, numpy.nan)

    # figure out where the Sun will be
    RAsun, Decsun, Azsun, Altsun = sunposition(yr, mn, dy, UT)
    if (RAsun > 180 + RA0):
Example #8
0
def write_primary_beam(datetime=None,
                       freq=100.0e6,
                       useazza=False,
                       xpol=True,
                       ypol=True,
                       HA=None,
                       Dec=None):

    if (not datetime is None):
        dir = "./"
        try:
            gps = daystr2gps(datetime)
        except ValueError:
            if ('/' in datetime):
                dir, datetime = os.path.split(datetime)
            while ('.' in datetime):
                datetime, ext = os.path.splitext(datetime)
            # assume that it has channel in there too
            source, channel, datetime = datetime.split('_')
            freq = 1.28e6 * int(channel)
            gps = daystr2gps(datetime)
        print >> sys.stderr, "GPS time for that observation is: %f" % gps
        mydelay = getDelays2(gps + 16)
        if mydelay is not None:
            print >> sys.stderr, str(mydelay)[1:-1]
        else:
            print "None"
            return None
    else:
        mydelay = [0]

    if (useazza):
        theta, phi = maketp()

    else:
        if (HA is not None and Dec is not None):
            # latitude of the site, in degrees
            latMWA = -26.7033194444444
            Az, Alt = ephem_utils.eq2horz(HA, Dec, latMWA)

            # go from altitude to zenith angle
            theta = (90 - Alt) * math.pi / 180
            phi = Az * math.pi / 180
        else:
            nDec = 120 * 8
            nHA = 180 * 8
            dDec = (30.0 - (-90.0)) / (nDec - 1)
            dHA = (90.0 - (-90.0)) / (nHA - 1)
            dec = numpy.arange(-90, 30, dDec)
            ha = numpy.arange(-90, 90, dHA)
            HA, Dec = numpy.meshgrid(ha, dec)
            # latitude of the site, in degrees
            latMWA = -26.7033194444444
            Az, Alt = ephem_utils.eq2horz(HA, Dec, latMWA)

            # go from altitude to zenith angle
            theta = (90 - Alt) * math.pi / 180
            phi = Az * math.pi / 180

    respX, respY = MWA_Tile_analytic(theta,
                                     phi,
                                     freq=freq,
                                     delays=numpy.array(mydelay))
    rX = numpy.real(numpy.conj(respX) * respX)
    rY = numpy.real(numpy.conj(respY) * respY)
    if (xpol and ypol):
        r = rX + rY
        polstring = ''
    else:
        if (xpol):
            r = rX
            polstring = 'X'
        else:
            r = rY
            polstring = 'Y'

    if (isinstance(r, numpy.float64) or len(r) == 1):
        print r
        return

    if (not datetime is None):
        outname = '%s/primarybeam%s_%s.fits' % (dir, polstring, datetime)
    else:
        outname = 'primarybeam%s_zenith.fits' % polstring
    if (os.path.exists(outname)):
        os.remove(outname)

    h = pyfits.PrimaryHDU()
    h.data = r
    if (useazza):
        h.header.update('CTYPE1', 'THETA')
        h.header.update('CRPIX1', 1.0)
        h.header.update('CRVAL1', 90)
        h.header.update('CDELT1',
                        (180.0 / math.pi) * (theta[0, 1] - theta[0, 0]))
        h.header.update('CTYPE2', 'PHI')
        h.header.update('CRPIX2', 1.0)
        h.header.update('CRVAL2', 0)
        h.header.update('CDELT2', (180.0 / math.pi) * (phi[1, 0] - phi[0, 0]))
    else:
        h.header.update('CTYPE1', 'HA')
        h.header.update('CRPIX1', 1.0)
        h.header.update('CRVAL1', -90)
        h.header.update('CDELT1', dHA)
        h.header.update('CTYPE2', 'DEC')
        h.header.update('CRPIX2', 1.0)
        h.header.update('CRVAL2', -90)
        h.header.update('CDELT2', dDec)

    if (not datetime is None):
        h.header.update('DATETIME', datetime, 'DATETIME string')
        h.header.update('GPSTIME', gps, 'GPS time')
        h.header.update('DELAYS', "%s" % mydelay, 'Rx delays')
    else:
        h.header.update('DELAYS', "%s" % 'zenith', 'Rx delays')
    h.header.update('FREQNCY', (freq / 1e6), '[MHz] Frequency')
    h.writeto(outname)
    print >> sys.stderr, "Wrote output to %s" % outname
Example #9
0
	sys.exit(1)

RA,Dec=69.3158945833333, -47.2523944444444
gpstime=1063400456
filename='1063400456_corr_phased.fits'

o=get_observation_info.MWA_Observation(gpstime, db=db)

mwatime=ephem_utils.MWATime(gpstime=gpstime+o.duration/2)
frequency=o.center_channel*1.28e6
delays=o.delays

RAnow,Decnow=ephem_utils.precess(RA,Dec,2000,mwatime.epoch)
HA=float(mwatime.LST)-RAnow
mwa=ephem_utils.Obs[ephem_utils.obscode['MWA']]
Az,Alt=ephem_utils.eq2horz(HA,Decnow,mwa.lat)
theta=(90-Alt)*math.pi/180
phi=Az*math.pi/180


def MWA_Jones_Analytic(theta, phi, ha, dec,
                       freq=100.0e6, delays=None,
                       zenithnorm=True):
    c=2.998e8
    # wavelength in meters
    lam=c/freq

    dip_sep=primary_beam._DIPOLE_SEPARATION
    delay_int=primary_beam._DELAY_INT
    dipheight=primary_beam._DIPOLE_HEIGHT
Example #10
0
def main():
    
    low=100
    high=10000
    cm=pylab.cm.gray
    
    usage="Usage: %prog [options]\n"
    usage+='\tMakes plot of MWA sky\n'
    parser = OptionParser(usage=usage,
                          version=mwapy.__version__ + ' ' + mwapy.__date__)
    parser.add_option('-o','--out',dest='out',default='/home/webdev/html/status/images/gbtmwasky.png',
                      help='Name for output [default=%default]')
    parser.add_option('-g','--gps',dest='gpstime',default=None,
                      type='int',
                      help='GPS time to process [default=most recent]')
    parser.add_option('--text',dest='text',default=False,
                      action='store_true',
                      help='Include text of target on plot?')
    parser.add_option('--notext',dest='text',default=False,
                      action='store_false',
                      help='Do not include text of target on plot?')

    (options, args) = parser.parse_args()

    basepath=os.path.join(os.path.split(mwapy.__file__)[0],'data')
    
    # read the constellation data
    try:
        fi=open(os.path.join(basepath,'constellationship.fab'))
    except:
        make_error('Could not find constellation data', options.out)
        sys.exit(1)
    Constellations={}
    for l in fi.readlines():
        d=l.split()
        name=d[0]
        n=int(d[1])
        data=numpy.array(map(int,d[2:]))
        Constellations[name]=[n,data]
    fi.close()      

    # read the HIP data on those stars
    try:
        HIP=Table.read(os.path.join(basepath,'HIP_constellations.dat'),
                       format='ascii.commented_header')
    except:
        make_error('Could not find star data', options.out)
        sys.exit(1)

    # Solar system bodies to plot
    # includes size in pixels and color
    Bodies={ephem.Sun: [120, 'y'],
            ephem.Jupiter: [60, 'c'],
            ephem.Moon: [120, 'w'],
            ephem.Mars: [30, 'r'],
            ephem.Venus: [40, 'c'],
            ephem.Saturn: [50, 'b'],
            }

    
    try:
        if options.gpstime is None:
            obsinfo=metadata.fetch_metadata(service='obs')
        else:
            obsinfo=metadata.fetch_metadata(gpstime=options.gpstime,
                                            service='obs')            
            if obsinfo['stoptime']==0:
                make_error('Unable to find observation info for observation %d', (options.gpstime,options.out))
                sys.exit(1)
    except:
        make_error('Unable to find observation info', options.out)
        sys.exit(1)

    try:    
        mwaobs=metadata.MWA_Observation(obsinfo)
    except:
        make_error('Unable to parse observation info', options.out)
        sys.exit(1)

    obstime=Time(mwaobs.observation_number, format='gps',
                 scale='utc')
    
    try:
        radio_image=os.path.join(basepath,'radio408.RaDec.fits')
        f=pyfits.open(radio_image)
    except:
        make_error('Cannot open Haslam image', options.out)
        sys.exit(1)

    skymap=f[0].data[0]
    ra=(f[0].header.get('CRVAL1')+(numpy.arange(1,skymap.shape[1]+1)-f[0].header.get('CRPIX1'))*f[0].header.get('CDELT1'))/15.0
    dec=f[0].header.get('CRVAL2')+(numpy.arange(1,skymap.shape[0]+1)-f[0].header.get('CRPIX2'))*f[0].header.get('CDELT2')
    mwa=ephem_utils.Obs[ephem_utils.obscode['MWA']]
    RA,Dec=numpy.meshgrid(ra*15,dec)

    # determine the LST
    observer=ephem.Observer()
    # make sure no refraction is included
    observer.pressure=0
    observer.long=mwa.long/ephem_utils.DEG_IN_RADIAN
    observer.lat=mwa.lat/ephem_utils.DEG_IN_RADIAN
    observer.elevation=mwa.elev
    observer.date=obstime.datetime.strftime('%Y/%m/%d %H:%M:%S')
    UTs=obstime.datetime.strftime('%H:%M:%S')
    LST_hours=observer.sidereal_time()*ephem_utils.HRS_IN_RADIAN
    LST=ephem_utils.dec2sexstring(LST_hours,digits=0,roundseconds=1)
    
    HA=-RA+LST_hours*15
    Az,Alt=ephem_utils.eq2horz(HA,Dec,mwa.lat)
    
    fig=pylab.figure(figsize=(figsize,figsize),dpi=dpi)
    ax1=fig.add_subplot(1,1,1)

    bmap = Basemap(projection='ortho',lat_0=mwa.lat,lon_0=LST_hours*15-360)
    nx=len(ra)
    ny=len(dec)

    ax1.cla()

    # get the primary beam
    R=primarybeammap.return_beam(Alt,Az,mwaobs.delays,
                                 mwaobs.center_channel*1.28)

    # figure out the constellation
    if mwaobs.ra_phase_center is not None:
        constellation=ephem.constellation((numpy.radians(mwaobs.ra_phase_center),
                                           numpy.radians(mwaobs.dec_phase_center)))
    else:
        racenter=RA[R==R.max()]
        deccenter=Dec[R==R.max()]
        constellation=ephem.constellation((numpy.radians(racenter),
                                           numpy.radians(deccenter)))

    # show the Haslam map
    tform_skymap=bmap.transform_scalar(skymap[:,::-1],ra[::-1]*15,
                                       dec,nx,ny,masked=True)
    bmap.imshow(numpy.ma.log10(tform_skymap[:,::-1]),
                cmap=cm,
                vmin=math.log10(low),vmax=math.log10(high))
    # show the beam
    X,Y=bmap(RA,Dec)
    bmap.contour(bmap.xmax-X,Y,R,[0.5,0.95],colors='w')
    
    X0,Y0=bmap(LST_hours*15-360,mwa.lat)

    # plot the constellations
    ConstellationStars=[]
    for c in Constellations.keys():
        for i in xrange(0,len(Constellations[c][1]),2):
            i1=numpy.where(HIP['HIP']==Constellations[c][1][i])[0][0]
            i2=numpy.where(HIP['HIP']==Constellations[c][1][i+1])[0][0]
            star1=HIP[i1]
            star2=HIP[i2]
            if not i1 in ConstellationStars:
                ConstellationStars.append(i1)
            if not i2 in ConstellationStars:
                ConstellationStars.append(i2)
            ra1,dec1=map(numpy.degrees,(star1['RArad'],star1['DErad']))
            ra2,dec2=map(numpy.degrees,(star2['RArad'],star2['DErad']))
            ra=numpy.array([ra1,ra2])
            dec=numpy.array([dec1,dec2])
            newx,newy=bmap(ra,dec)
            testx,testy=bmap(newx,newy,inverse=True)
            if testx.max()<1e30 and testy.max()<1e30:
                bmap.plot(2*X0-newx,newy,'r-',latlon=False)

    # figure out the coordinates
    # and plot the stars
    ra=numpy.degrees(HIP[ConstellationStars]['RArad'])
    dec=numpy.degrees(HIP[ConstellationStars]['DErad'])
    m=numpy.degrees(HIP[ConstellationStars]['Hpmag'])
    newx,newy=bmap(ra,dec)
    testx,testy=bmap(newx,newy,inverse=True)
    good=(newx > bmap.xmin) & (newx < bmap.xmax) & (newy > bmap.ymin) & (newy < bmap.ymax)
    size=60-15*m
    size[size<=15]=15
    size[size>=60]=60
    bmap.scatter(bmap.xmax-newx[good], newy[good], size[good], 'b',
                 edgecolor='none',
                 alpha=0.7)
     
    # plot the bodies    
    for b in Bodies.keys():
        color=Bodies[b][1]
        size=Bodies[b][0]
        body=b(observer)
        ra,dec=map(numpy.degrees,(body.ra,body.dec))
        newx,newy=bmap(ra,dec)
        testx,testy=bmap(newx,newy,inverse=True)
        if testx<1e30 and testy<1e30:
            bmap.scatter(2*X0-newx,newy,latlon=False,s=size,c=color,alpha=0.5,
                         edgecolor='none')

    # and label some sources
    for source in primarybeammap.sources.keys():
        if source == 'EOR0b':
            continue
        if source=='CenA':
            primarybeammap.sources[source][0]='Cen A'
        if source=='ForA':
            primarybeammap.sources[source][0]='For A'
        r=ephem_utils.sexstring2dec(primarybeammap.sources[source][1])
        d=ephem_utils.sexstring2dec(primarybeammap.sources[source][2])
        horizontalalignment='left'
        x=r
        if (len(primarybeammap.sources[source])>=6 and primarybeammap.sources[source][5]=='c'):    
            horizontalalignment='center'
            x=r
        if (len(primarybeammap.sources[source])>=6 and primarybeammap.sources[source][5]=='r'):    
            horizontalalignment='right'
            x=r      
        fontsize=primarybeammap.defaultsize
        if (len(primarybeammap.sources[source])>=5):
            fontsize=primarybeammap.sources[source][4]
        color=primarybeammap.defaultcolor
        if (len(primarybeammap.sources[source])>=4):
            color=primarybeammap.sources[source][3]
        if color=='k':
            color='w'
        xx,yy=bmap(x*15-360,d)
        try:
            if xx<1e30 and yy<1e30:
                ax1.text(bmap.xmax-xx+2e5,yy,primarybeammap.sources[source][0],
                         horizontalalignment=horizontalalignment,
                         fontsize=fontsize,color=color,
                         verticalalignment='center')
        except:
            pass

        if options.text:
            ax1.text(0, bmap.ymax-2e5,
                     '%s:\n%s at %d MHz\n in the constellation %s' % (obstime.datetime.strftime('%Y-%m-%d %H:%M UT'),
                                                                      mwaobs.filename.replace('_','\_'),
                                                                      mwaobs.center_channel*1.28,
                                                                      constellation[1]),
                     fontsize=10)

        ax1.text(bmap.xmax,Y0,'W',fontsize=12,
                 horizontalalignment='left',verticalalignment='center')
        ax1.text(bmap.xmin,Y0,'E',fontsize=12,
                 horizontalalignment='right',verticalalignment='center')
        ax1.text(X0,bmap.ymax,'N',fontsize=12,
                 horizontalalignment='center',verticalalignment='bottom')         
        ax1.text(X0,bmap.ymin,'S',fontsize=12,
                 horizontalalignment='center',verticalalignment='top')

        try:
            fig.savefig(options.out,transparent=True,facecolor='none')
        except:
            make_error('Cannot save output',options.out)