コード例 #1
0
ファイル: mwabeam.py プロジェクト: torrance/radical
 def jones(self, ra, dec, freq):
     alt, az = radec_to_altaz(ra, dec, self.time, self.location)
     return pb.MWA_Tile_full_EE(np.pi / 2 - alt,
                                az,
                                freq,
                                delays=self.delays,
                                jones=True)
コード例 #2
0
ファイル: mwabeam.py プロジェクト: torrance/astrobits
    def power(self, ras, decs, freq, time=None):
        if time is None:
            time = self.time

        alt, az = radec_to_altaz(ras, decs, time, self.location)
        with threadlock:
            return pb.MWA_Tile_full_EE(np.pi / 2 - alt,
                                       az,
                                       freq,
                                       delays=self.delays,
                                       power=True)
コード例 #3
0
ファイル: mwabeam.py プロジェクト: torrance/astrobits
    def jones(self, ras, decs, freq, time=None):
        if time is None:
            time = self.time

        t0 = tm.time()
        alt, az = radec_to_altaz(ras, decs, time, self.location)
        print("Altaz elapsed: %g" % (tm.time() - t0))
        with threadlock:
            return pb.MWA_Tile_full_EE(np.pi / 2 - alt,
                                       az,
                                       freq,
                                       delays=self.delays,
                                       jones=True)
コード例 #4
0
def get_beam_weights(ras=None, decs=None):
    '''Takes ra and dec coords, and works out the overall beam power
    at that location using the 2016 spherical harmonic beam code from mwapy'''

    mwatime = Time(obsID, format='gps', scale='utc')
    coords = SkyCoord(ra=ras,
                      dec=decs,
                      equinox='J2000',
                      unit=(astropy.units.hour, astropy.units.deg))
    coords.location = MWAPOS
    coords.obstime = mwatime
    coords_prec = coords.transform_to('altaz')
    za_rad = math.pi - coords_prec.alt.rad  # Need zenith angle in radians, not altitude in radians
    az_rad = coords_prec.az.rad

    # go from altitude to zenith angle
    # theta = numpy.radians((90 - Alt))
    # phi = numpy.radians(Az)

    ##For each component, work out it's position, convolve with the beam and sum for the source
    #for ra,dec in zip(source.ras,source.decs):
    ##HA=LST-RA in def of ephem_utils.py
    # has = LST - array(ras)*15.0  ##RTS stores things in hours
    ##Convert to zenith angle, azmuth in rad

    # Az,Alt=ephem_utils.eq2horz(has,array(decs),mwa_lat)
    # za=(90-Alt)*pi/180
    # az=Az*pi/180

    XX, YY = primary_beam.MWA_Tile_full_EE([za_rad], [az_rad],
                                           freq=freqcent,
                                           delays=delays,
                                           zenithnorm=True,
                                           power=True,
                                           interp=False)

    beam_weights = (XX[0] + YY[0]) / 2.0
    ##OLd way of combining XX and YY - end up with beam values greater than 1, not good!
    #beam_weights = n.sqrt(XX[0]**2+YY[0]**2)

    return beam_weights
コード例 #5
0
def get_beam_weights(ras=None,decs=None,LST=None, mwa_lat=None, freqcent=None,delays=None):
    '''Takes ra and dec coords, and works out the overall beam power
    at that location using the 2016 spherical harmonic beam code from mwapy'''

    ##For each component, work out it's position, convolve with the beam and sum for the source
    #for ra,dec in zip(source.ras,source.decs):
    ##HA=LST-RA in def of ephem_utils.py
    has = LST - array(ras)*15.0  ##RTS stores things in hours
    ##Convert to zenith angle, azmuth in rad

    Az,Alt=eq2horz(has,array(decs),mwa_lat)
    za=(90-Alt)*pi/180
    az=Az*pi/180

    XX,YY = primary_beam.MWA_Tile_full_EE([za], [az], freq=freqcent, delays=delays, zenithnorm=True, power=True, interp=False)

    beam_weights = (XX[0]+YY[0]) / 2.0
    ##OLd way of combining XX and YY - end up with beam values greater than 1, not good!
    #beam_weights = sqrt(XX[0]**2+YY[0]**2)

    return beam_weights
コード例 #6
0
def get_beam_power_over_time(beam_meta_data,
                             names_ra_dec,
                             dt=296,
                             centeronly=True,
                             verbose=False,
                             option='analytic',
                             degrees=False,
                             start_time=0):
    """
    Calulates the power (gain at coordinate/gain at zenith) for each source over time.

    get_beam_power_over_time(beam_meta_data, names_ra_dec,
                             dt=296, centeronly=True, verbose=False,
                             option = 'analytic')
    Args:
        beam_meta_data: [obsid,ra, dec, time, delays,centrefreq, channels]
                        obsid metadata obtained from meta.get_common_obs_metadata
        names_ra_dec: and array in the format [[source_name, RAJ, DecJ]]
        dt: time step in seconds for power calculations (default 296)
        centeronly: only calculates for the centre frequency (default True)
        verbose: prints extra data to (default False)
        option: primary beam model [analytic, advanced, full_EE]
        start_time: the time in seconds from the begining of the observation to
                    start calculating at
    """
    obsid, _, _, time, delays, centrefreq, channels = beam_meta_data
    names_ra_dec = np.array(names_ra_dec)
    logger.info("Calculating beam power for OBS ID: {0}".format(obsid))

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

    if not centeronly:
        PowersX = np.zeros((len(names_ra_dec), Ntimes, len(channels)))
        PowersY = np.zeros((len(names_ra_dec), Ntimes, len(channels)))
        # in Hz
        frequencies = np.array(channels) * 1.28e6
    else:
        PowersX = np.zeros((len(names_ra_dec), Ntimes, 1))
        PowersY = np.zeros((len(names_ra_dec), Ntimes, 1))
        if centrefreq > 1e6:
            logger.warning(
                "centrefreq is greater than 1e6, assuming input with units of Hz."
            )
            frequencies = np.array([centrefreq])
        else:
            frequencies = np.array([centrefreq]) * 1e6
    if degrees:
        RAs = np.array(names_ra_dec[:, 1], dtype=float)
        Decs = np.array(names_ra_dec[:, 2], dtype=float)
    else:
        RAs, Decs = sex2deg(names_ra_dec[:, 1], names_ra_dec[:, 2])

    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
    if verbose is False:
        #Supress print statements of the primary beam model functions
        sys.stdout = open(os.devnull, 'w')
    for itime in range(Ntimes):
        # this differ's from the previous ephem_utils method by 0.1 degrees
        _, Azs, Zas = mwa_alt_az_za(midtimes[itime],
                                    ra=RAs,
                                    dec=Decs,
                                    degrees=True)
        # go from altitude to zenith angle
        theta = np.radians(Zas)
        phi = np.radians(Azs)
        for ifreq in range(len(frequencies)):
            #Decide on beam model
            if option == 'analytic':
                rX, rY = primary_beam.MWA_Tile_analytic(
                    theta,
                    phi,
                    freq=frequencies[ifreq],
                    delays=delays,
                    zenithnorm=True,
                    power=True)
            elif option == 'advanced':
                rX, rY = primary_beam.MWA_Tile_advanced(
                    theta,
                    phi,
                    freq=frequencies[ifreq],
                    delays=delays,
                    zenithnorm=True,
                    power=True)
            elif option == 'full_EE':
                rX, rY = primary_beam.MWA_Tile_full_EE(theta,
                                                       phi,
                                                       freq=frequencies[ifreq],
                                                       delays=delays,
                                                       zenithnorm=True,
                                                       power=True)
        PowersX[:, itime, ifreq] = rX
        PowersY[:, itime, ifreq] = rY
    if verbose is False:
        sys.stdout = sys.__stdout__
    Powers = 0.5 * (PowersX + PowersY)
    return Powers
コード例 #7
0
ファイル: Model_format_3.py プロジェクト: JaidenCook/bin
print "Number of sources above the horizon:", len(Alt0_samp)

# Creating new sampled table.
Sky_Mod = temp_table[Alt0 > 0.0]

#start1 = time.time()

#"""
################################################################################
# Thresholding the apparent brightest 1500 sources in the OBSID
################################################################################
#"""

# Determining the beam power at the central frequency for each source above the horizon.
beam_power = pb.MWA_Tile_full_EE(Zen0_samp, Az0_samp, cent_freq, delays_flt)

#end1 = time.time()

# Splitting the xx and yy cross correlation power components
beam_power_XX = np.array(beam_power[0])
beam_power_YY = np.array(beam_power[1])

# Determining the average power or stokes I power.
beamvalue = (beam_power_XX + beam_power_YY) / 2

S300_fit = Sky_Mod.field("Fint300")
"""
# Replace this remaping section with JOOF.py log-poly map

コード例 #8
0
ファイル: calc_jones.py プロジェクト: MWATelescope/mwa_pb
def calc_jones(az, za, target_freq_Hz=205e6):
    za_rad = za * math.pi / 180.0
    az_rad = az * math.pi / 180.0
    za_rad = np.array([[za_rad]])
    az_rad = np.array([[az_rad]])

    gridpoint = mwa_sweet_spots.find_closest_gridpoint(az, za)
    print("Az = %.2f [deg], za = %.2f [deg], gridpoint = %d" % (az, za, gridpoint[0]))

    delays = gridpoint[4]
    delays = np.vstack((delays, delays))
    print(delays)
    print("-----------")

    Jones_FullEE = primary_beam.MWA_Tile_full_EE(za_rad,
                                                 az_rad,
                                                 target_freq_Hz,
                                                 delays=delays,
                                                 zenithnorm=True,
                                                 jones=True, interp=True)
    # swap axis to have Jones martix in the 1st
    Jones_FullEE_swap = np.swapaxes(np.swapaxes(Jones_FullEE, 0, 2), 1, 3)

    # TEST if equivalent to :
    Jones_FullEE_2D = Jones_FullEE_swap[:, :, 0, 0]
    # Jones_FullEE_2D = np.array([ [Jones_FullEE_swap[0, 0][0][0], Jones_FullEE_swap[0, 1][0][0]] , [Jones_FullEE_swap[1, 0][0][0], Jones_FullEE_swap[1, 1][0][0]] ])
    print("Jones FullEE:")
    print("----------------------")
    print(Jones_FullEE)
    print("----------------------")
    print(Jones_FullEE_2D)
    print("----------------------")

    beams = {}
    beams['XX'], beams['YY'] = primary_beam.MWA_Tile_full_EE(za_rad,
                                                             az_rad,
                                                             target_freq_Hz,
                                                             delays=delays,
                                                             zenithnorm=True,
                                                             power=True)
    print("Beams power = %.4f / %.4f" % (beams['XX'], beams['YY']))

    # Average Embeded Element model:
    print("size(delays) = %d" % np.size(delays))
    Jones_AEE = primary_beam.MWA_Tile_advanced(za_rad, az_rad, target_freq_Hz, delays=delays, jones=True)
    # Jones_AEE = primary_beam.MWA_Tile_advanced(np.array([[0]]), np.array([[0]]), target_freq_Hz,delays=delays, zenithnorm=True, jones=True)
    Jones_AEE_swap = np.swapaxes(np.swapaxes(Jones_AEE, 0, 2), 1, 3)
    Jones_AEE_2D = Jones_AEE_swap[:, :, 0, 0]
    # Jones_AEE_2D = np.array([ [Jones_AEE_swap[0, 0][0][0], Jones_AEE_swap[0, 1][0][0]], [Jones_AEE_swap[1, 0][0][0], Jones_AEE_swap[1, 1][0][0]] ])
    print("----------------------")
    print("Jones AEE:")
    print("----------------------")
    print(Jones_AEE)
    print("----------------------")
    print(Jones_AEE_2D)
    print("----------------------")

    Jones_Anal = primary_beam.MWA_Tile_analytic(za_rad,
                                                az_rad,
                                                target_freq_Hz,
                                                delays=delays,
                                                zenithnorm=True,
                                                jones=True)
    Jones_Anal_swap = np.swapaxes(np.swapaxes(Jones_Anal, 0, 2), 1, 3)
    Jones_Anal_2D = Jones_Anal_swap[:, :, 0, 0]

    print("----------------------  COMPARISON OF JONES MATRICES FEE vs. AEE ----------------------")
    print("Jones FullEE:")
    print("----------------------")
    print(Jones_FullEE_2D)
    print("----------------------")
    print()
    print("Jones AEE:")
    print("----------------------")
    print(Jones_AEE_2D)
    print("----------------------")
    print()
    print("----------------------")
    print("Jones Analytic:")
    print("----------------------")
    print(Jones_Anal_2D)
    print("----------------------")

    return (Jones_FullEE_2D, Jones_AEE_2D, Jones_Anal_2D)
コード例 #9
0
ファイル: calc_jones.py プロジェクト: MWATelescope/mwa_pb
def calc_ratio(dec, target_freq_Hz, gridpoint):
    za = dec + 26.7
    az = 0

    print("\n\n\n\n")
    print("################################# DEC = %.2f #################################" % dec)
    za_rad = za * math.pi / 180.0
    az_rad = az * math.pi / 180.0
    za_rad = np.array([[za_rad]])
    az_rad = np.array([[az_rad]])

    # non-realistic scenario - I am ~tracking the source with the closest sweetspot - whereas I should be staying at the same sweetspot
    #   gridpoint=find_closest_gridpoint(za)
    #
    print("dec=%.4f [deg] -> za=%.4f [deg] - %s" % (dec, za, gridpoint))
    delays = gridpoint[4]
    delays = np.vstack((delays, delays))
    print(delays)
    print("-----------")

    Jones_FullEE = primary_beam.MWA_Tile_full_EE(za_rad, az_rad, target_freq_Hz, delays=delays, zenithnorm=True,
                                                 jones=True, interp=True)
    # swap axis to have Jones martix in the 1st
    Jones_FullEE_swap = np.swapaxes(np.swapaxes(Jones_FullEE, 0, 2), 1, 3)

    # TEST if equivalent to :
    Jones_FullEE_2D = Jones_FullEE_swap[:, :, 0, 0]
    # Jones_FullEE_2D = np.array([ [Jones_FullEE_swap[0, 0][0][0], Jones_FullEE_swap[0, 1][0][0]], [Jones_FullEE_swap[1, 0][0][0], Jones_FullEE_swap[1, 1][0][0]] ])
    print("Jones FullEE:")
    print("----------------------")
    print(Jones_FullEE)
    print("----------------------")
    print(Jones_FullEE_2D)
    print("----------------------")

    #  Average Embeded Element model:
    print("size(delays) = %d" % np.size(delays))
    Jones_AEE = primary_beam.MWA_Tile_advanced(za_rad, az_rad, target_freq_Hz, delays=delays, jones=True)
    # Jones_AEE = primary_beam.MWA_Tile_advanced(np.array([[0]]), np.array([[0]]), target_freq_Hz, delays=delays, zenithnorm=True, jones=True)
    Jones_AEE_swap = np.swapaxes(np.swapaxes(Jones_AEE, 0, 2), 1, 3)
    Jones_AEE_2D = Jones_AEE_swap[:, :, 0, 0]
    # Jones_AEE_2D = np.array([ [Jones_AEE_swap[0, 0][0][0], Jones_AEE_swap[0, 1][0][0]], [Jones_AEE_swap[1, 0][0][0], Jones_AEE_swap[1, 1][0][0]] ])
    print("----------------------")
    print("Jones AEE:")
    print("----------------------")
    print(Jones_AEE)
    print("----------------------")
    print(Jones_AEE_2D)
    print("----------------------")

    # Analytical Model:
    # beams = {}
    # beams['XX'], beams['YY'] = primary_beam.MWA_Tile_analytic(za_rad, az_rad, target_freq_Hz, delays=delays, zenithnorm=True, jones=True)
    Jones_Anal = primary_beam.MWA_Tile_analytic(za_rad,
                                                az_rad,
                                                target_freq_Hz,
                                                delays=delays,
                                                zenithnorm=True,
                                                jones=True)
    Jones_Anal_swap = np.swapaxes(np.swapaxes(Jones_Anal, 0, 2), 1, 3)
    Jones_Anal_2D = Jones_Anal_swap[:, :, 0, 0]
    # Jones_Anal_2D = np.array([ [Jones_Anal_swap[0, 0][0][0], Jones_Anal_swap[0, 1][0][0]] , [Jones_Anal_swap[1, 0][0][0],Jones_Anal_swap[1, 1][0][0]] ])
    print("----------------------")
    print("Jones Analytic:")
    print("----------------------")
    print(Jones_Anal)
    print("----------------------")
    print(Jones_Anal_2D)
    print("----------------------")
    print("TEST:")
    print("----------------------")
    print("%.8f    %.8f" % (Jones_Anal_2D[0, 0], Jones_Anal_2D[0, 1]))
    print("%.8f    %.8f" % (Jones_Anal_2D[1, 0], Jones_Anal_2D[1, 1]))
    print("----------------------")

    # Use Jones_FullEE_2D as REAL sky and then ...
    B_sky = np.array([[1, 0], [0, 1]])
    Jones_FullEE_2D_H = np.transpose(Jones_FullEE_2D.conj())
    B_app = np.dot(Jones_FullEE_2D, np.dot(B_sky, Jones_FullEE_2D_H))  # E x B x E^H

    # test the procedure itself:
    Jones_FullEE_2D_H_Inv = inv2x2(Jones_FullEE_2D_H)
    Jones_FullEE_2D_Inv = inv2x2(Jones_FullEE_2D)
    B_sky_cal = np.dot(Jones_FullEE_2D_Inv, np.dot(B_app, Jones_FullEE_2D_H_Inv))
    print(B_sky)
    print("Recovered using FullEE model:")
    print(B_sky_cal)

    # calibrate back using AEE model :
    #   Jones_AEE_2D=Jones_Anal_2D # overwrite Jones_AEE_2D with Analytic to use it for calibration
    Jones_AEE_2D_H = np.transpose(Jones_AEE_2D.conj())
    Jones_AEE_2D_H_Inv = inv2x2(Jones_AEE_2D_H)
    Jones_AEE_2D_Inv = inv2x2(Jones_AEE_2D)
    B_sky_cal = np.dot(Jones_AEE_2D_Inv, np.dot(B_app, Jones_AEE_2D_H_Inv))
    print("Recovered using AEE model:")
    print(B_sky_cal)
    # I_cal = B_sky_cal[0, 0] + B_sky_cal[1, 1]
    #   print "FINAL : %.8f ratio = %.8f / 2 = %.8f" % (dec,abs(I_cal),(abs(I_cal)/2.00))
    # ratio = abs(B_sky_cal[0][0] / B_sky_cal[1][1])
    # FINAL VALUES for the paper to compare with Figure 4 in GLEAM paper :
    ratio_ms = B_sky_cal[0][0] / B_sky_cal[1][1]
    gleam_ratio = ratio_ms
    gleam_XX = B_sky_cal[0][0]
    gleam_YY = B_sky_cal[1][1]
    # gleam_q_leakage = (B_sky_cal[0][0] - B_sky_cal[1][1]) / (B_sky_cal[0][0] + B_sky_cal[1][1])
    print("DEBUG (DEC = %.2f deg) : GLEAM-ratio = %.4f = (%s / %s)" % (dec, gleam_ratio, gleam_XX, gleam_YY))

    return (gleam_ratio.real, gleam_XX, gleam_YY)
コード例 #10
0
ファイル: peeler.py プロジェクト: torrance/mwaprocessing
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--ms', help="The measurement set from which to peel")
    parser.add_argument('--meta', help="The observation metafits file")
    parser.add_argument('--model', help="The skymodel to peel, in aoskymodel 1.1 format")
    parser.add_argument('--aegean', help="Aegean CSV")
    parser.add_argument('--datacolumn', default='CORRECTED_DATA')
    parser.add_argument('--width', type=int, required=True)
    parser.add_argument('--passes', type=int, default=2)
    parser.add_argument('--minuv', type=float, default=0, help="Fit models only on baselines above this minimum uv distance (metres)")
    parser.add_argument('--workers', type=int, default=0)
    parser.add_argument('--threshold', type=float, default=0.8)
    args = parser.parse_args()

    metafits = getheader(args.meta)
    date = Time(metafits['DATE-OBS'], location=mwa_pb.config.MWAPOS)
    delays = [int(d) for d in metafits['DELAYS'].split(',')]
    delays = [delays, delays] # Shuts up mwa_pb
    location = mwa_pb.config.MWAPOS

    print("Observation date: ", date)
    print("Delays: ", delays)

    # Retrieve telescope position
    dm = measures()
    obs = table(args.ms + '/OBSERVATION', ack=False)
    if 'TELESCOPE_NAME' in obs.colnames():
        names = obs.getcol('TELESCOPE_NAME')
        if len(names) == 1:
            obspos = dm.observatory(names[0])
            dm.do_frame(obspos)

        else:
            print("Failed to work out the telescope name of this observation")
            exit(1)
    else:
        print("Measurement set did not provide the telescope name")
        exit(1)
    print("Observation taken using telescope %s" % names[0])

    ms = table(args.ms, readonly=False, ack=False)
    freqs = table(args.ms + '/SPECTRAL_WINDOW', ack=False).getcell('CHAN_FREQ', 0)
    midfreq = (max(freqs) + min(freqs)) / 2
    lambdas = speed_of_light / freqs
    ra0, dec0 = table(args.ms + '/FIELD', ack=False).getcell('PHASE_DIR', 0)[0]  # Phase centre in radians
    chans, pols = ms.getcell(args.datacolumn, 0).shape
    print("There are %d channels" % chans)

    # Check whether width evenly divides the total channels
    if chans % args.width != 0:
        print("Width (%d) does not evenly divide channel number (%d)" % (args.width, chans))
        exit(1)

    widefreqs = np.array([
        np.mean(freqs[i:i+args.width]) for i in range(0, len(freqs), args.width)
    ])
    widelambdas = speed_of_light / widefreqs

    antennas = table(args.ms + '/ANTENNA', ack=False).getcol('POSITION')
    antennas = dm.position(
        'itrf',
        quantity(antennas.T[0], 'm'),
        quantity(antennas.T[1], 'm'),
        quantity(antennas.T[2], 'm'),
    )

    # Create PEELED_DATA column if it does not exist
    if ('CORRECTED_DATA' not in ms.colnames()):
        print("Creating CORRECTED_DATA column...", end=" ")
        sys.stdout.flush()
        coldesc = ms.getcoldesc('DATA')
        coldesc['name'] = 'CORRECTED_DATA'
        ms.addcols(coldesc)

        peeled = ms.getcol(args.datacolumn)
        ms.putcol('CORRECTED_DATA', peeled)
        print("Done")

    # Load models
    if args.model:
        with open(args.model) as f:
            models = model_parser(f)
            comps = [c for m in models for c in m.components]
    elif args.aegean:
        with open(args.aegean) as f:
            comps = aegean_parser(f, midfreq)
    else:
        print("No model (--aegean or --model) specified", file=sys.stderr)
        exit(1)
    print("Initialised %d model sources" % len(comps))


    # Calculate Jones matrices for each model component
    # JBeams[widefreq, component, row, col]
    JBeams = []
    for widefreq in widefreqs:
        altaz = [radec_to_altaz(comp.ra, comp.dec, date, location) for comp in comps]
        altaz = np.array(zip(*altaz))
        JBeam = pb.MWA_Tile_full_EE(np.pi/2 - altaz[0], altaz[1], widefreq, delays=delays, jones=True)
        JBeams.append(JBeam)

    sources = []
    for i, comp in enumerate(comps):
        xx_fluxes = []
        yy_fluxes = []
        for j, widefreq in enumerate(widefreqs):
            stokes = comp.flux(widefreq) # Model flux per Stokes paramter

            # XX = I + V; XY = U + iV; YY = Q - iU; YY = I -Q
            linear = np.array([
                [stokes[0] + stokes[3], stokes[2] + 1j * stokes[3]],
                [stokes[1] - 1j * stokes[2], stokes[0] - stokes[1]],
            ])

            # apparent = JBeam x linear x (JBeam)^H ..... where H is the Hermitian transpose
            JBeam = JBeams[j][i]
            apparent = np.matmul(np.matmul(JBeam, linear), np.conj(JBeam.T))

            # For now (FIX?) we just take the real part
            xx_fluxes.append(np.real(apparent[0, 0]))
            yy_fluxes.append(np.real(apparent[1, 1]))

        xx_fluxes, yy_fluxes = np.array(xx_fluxes), np.array(yy_fluxes)

        # Estimate initial parameters
        log_widefreqs = np.log(widefreqs)
        log_xx_fluxes = np.log(xx_fluxes)
        log_yy_fluxes = np.log(yy_fluxes)
        xx3 = np.polyfit(log_widefreqs, log_xx_fluxes, 0)
        yy3 = np.polyfit(log_widefreqs, log_yy_fluxes, 0)

        sources.append(
            #Point(0, 0, xx3, 0, 0, yy3, comp.ra, comp.dec),
            Gaussian(0, 0, xx3, 0, 0, yy3, 0.1, 0.1, 0, comp.ra, comp.dec),
        )

    # Group sources by a spatial threshold
    threshold = (4 / 60) * np.pi / 180
    partitions = spatial_partition(sources, threshold)

    # Read data minus flagged rows
    tbl = taql("select * from $ms where not FLAG_ROW")
    uvw = tbl.getcol('UVW')
    uvw.flags.writeable = False
    times = tbl.getcol('TIME_CENTROID')
    times.flags.writeable = False
    ant1 = tbl.getcol('ANTENNA1')
    ant1.flags.writeable = False
    ant2 = tbl.getcol('ANTENNA2')
    ant2.flags.writeable = False
    data = tbl.getcol(args.datacolumn)[:, :, [True, False, False, True]].copy() # Just XX, YY

    # Handle flags by setting entries that are flagged as NaN
    flags = tbl.getcol('FLAG')[:, :, [True, False, False, True]]
    data[flags] = np.nan

    # For some reason, it is necessary to rotate onto
    # the current phase direction. Somehow this makes future offsets
    # internally self-consistent.
    dm = measures()
    phasecentre = dm.direction(
        'j2000',
        quantity(ra0, 'rad'),
        quantity(dec0, 'rad'),
    )

    uvw, data = phase_rotate(
        uvw,
        times,
        data,
        ant1,
        ant2,
        obspos,
        phasecentre,
        antennas,
        speed_of_light / freqs,
    )
    # tbl.putcol('UVW', uvw)
    # d = tbl.getcol('DATA')
    # d[:, :, [True, False, False, True]] = data
    # tbl.putcol('DATA', d)

    if args.workers > 0:
        pool = Pool(args.workers)

    for passno in range(args.passes):
        i = 0

        # Order sources by apparent flux at midfreq
        partitions = sorted(
            partitions, reverse=True, key=lambda xs: sum([x.flux(midfreq) for x in xs])
        )

        print("Beginning pass %d...   0%%" % (passno + 1), end="")
        sys.stdout.flush()
        while i < len(partitions):
            # TODO: use prior partitions to estimate updated values for l,m of this partition

            # Find the next batch of partitions that are within some threshold
            # of the currently brightest partition due to process.
            fluxlimit = args.threshold * sum([
                x.flux(midfreq) for x in partitions[i]
            ])
            for n, partition in enumerate(partitions[i:] + [None]):
                if partition is None:
                    break
                elif sum([x.flux(midfreq) for x in partition]) < fluxlimit:
                    break

            batch = partitions[i:i+n]

            data.flags.writeable = False
            if args.workers:
                diffs = pool.imap_unordered(
                    peel_star,
                    zip(
                        [uvw] * len(batch),
                        [times] * len(batch),
                        [data] * len(batch),
                        [ant1] * len(batch),
                        [ant2] * len(batch),
                        batch,
                        [antennas] * len(batch),
                        [freqs] * len(batch),
                        [obspos] * len(batch),
                        [ra0] * len(batch),
                        [dec0] * len(batch),
                        [args] * len(batch),
                        [passno] * len(batch),
                    )
                )
            else:
                diffs = imap(
                    peel,
                    [uvw] * len(batch),
                    [times] * len(batch),
                    [data] * len(batch),
                    [ant1] * len(batch),
                    [ant2] * len(batch),
                    batch,
                    [antennas] * len(batch),
                    [freqs] * len(batch),
                    [obspos] * len(batch),
                    [ra0] * len(batch),
                    [dec0] * len(batch),
                    [args] * len(batch),
                    [passno] * len(batch),
                )
            data.flags.writeable = True

            data = data.copy()  # Avoid changing data for running threads
            for j, diff in enumerate(diffs):
                data += diff
                print("\b\b\b\b% 3d%%" % ((i + j + 1) / len(partitions) * 100), end="")
                sys.stdout.flush()

            i += n

        print("")

    print("\n Finishing peeling. Writing data back to disk...", end=" ")
    sys.stdout.flush()
    peeled = tbl.getcol(args.datacolumn)
    peeled[:, :, 0] = data[:, :, 0]
    peeled[:, :, 3] = data[:, :, 1]
    tbl.putcol('CORRECTED_DATA', peeled)
    ms.close()
    with open('peeled.reg', 'w') as f:
        to_ds9_regions(f, partitions)
    print("Done")
コード例 #11
0
        Vij = np.array([[data_yy, data_xy + 1j * data_xyi],
                        [data_xy - 1j * data_xyi, data_xx]])
    # delays = beam_tools.gridpoint2delays(gridpoint, os.path.join(MWAtools_pb_dir, 'MWA_sweet_spot_gridpoints.csv'))

    print("delays = %s , frequency = %.2f Hz" % (delays, target_freq_Hz))

    sign_uv = 1
    sign_q = 1
    if model == 'full_EE' or model == '2016' or model == 'FEE' or model == 'Full_EE':
        logger.info("Correcting with full_EE(%s) model at frequency %.2f Hz" %
                    (model, target_freq_Hz))
        # print "DEBUG = %s" % (az)
        Jones = primary_beam.MWA_Tile_full_EE(za,
                                              az,
                                              target_freq_Hz,
                                              delays=delays,
                                              zenithnorm=options.zenithnorm,
                                              jones=True,
                                              interp=True)

        if options.wsclean_image:
            sign_uv = -1
    elif model == 'avg_EE' or model == 'advanced' or model == '2015' or model == 'AEE':
        logger.info("Correcting with AEE(%s) model at frequency %.2f Hz" %
                    (model, target_freq_Hz))
        # logging.getLogger("mwa_tile").setLevel(logging.DEBUG)
        Jones = primary_beam.MWA_Tile_advanced(za,
                                               az,
                                               target_freq_Hz,
                                               delays=delays,
                                               zenithnorm=options.zenithnorm,
コード例 #12
0
def get_beam_power(obsid_data,
                   sources,
                   beam_model="analytic",
                   centeronly=True):

    obsid, _, _, duration, delays, centrefreq, channels = obsid_data

    # Figure out GPS times to evaluate the beam in order to map the drift scan
    midtimes = np.array([
        float(obsid) + 0.5 * duration
    ])  # although only includes one element, could in future be extended
    Ntimes = len(midtimes)

    # Make an EarthLocation for the MWA
    MWA_LAT = -26.7033  # degrees
    MWA_LON = 116.671  # degrees
    MWA_HEIGHT = 377.827  # metres
    mwa_location = EarthLocation(lat=MWA_LAT * u.deg,
                                 lon=MWA_LON * u.deg,
                                 height=MWA_HEIGHT * u.m)

    # Pre-allocate arrays for the beam patterns
    if not centeronly:
        PowersX = np.zeros((len(sources), Ntimes, len(channels)))
        PowersY = np.zeros((len(sources), Ntimes, len(channels)))
        frequencies = np.array(channels) * 1.28e6
    else:
        PowersX = np.zeros((len(sources), Ntimes, 1))
        PowersY = np.zeros((len(sources), Ntimes, 1))
        frequencies = [centrefreq]

    # Create arrays of the RAs and DECs to be sampled (already in degrees)
    #print "Constructing RA and DEC arrays for beam model..."
    logger.info("Constructing RA and DEC arrays for beam model...")
    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

    # Turn RAs and DECs into SkyCoord objects that are to be fed to Alt/Az conversion
    coords = SkyCoord(RAs, Decs, unit=(u.deg, u.deg))

    # Make times to feed to Alt/Az conversion
    obstimes = Time(midtimes, format='gps', scale='utc')

    #print "Converting RA and DEC to Alt/Az and computing beam pattern..."
    logger.info(
        "Converting RA and DEC to Alt/Az and computing beam pattern...")
    for t, time in enumerate(obstimes):
        # Convert to Alt/Az given MWA position and observing time
        altaz = coords.transform_to(AltAz(obstime=time, location=mwa_location))

        # Change Altitude to Zenith Angle
        theta = np.pi / 2 - altaz.alt.rad
        phi = altaz.az.rad

        # Calculate beam pattern for each frequency, and store the results in a ndarray
        for f, freq in enumerate(frequencies):
            if beam_model == "analytic":
                rX, rY = primary_beam.MWA_Tile_analytic(theta,
                                                        phi,
                                                        freq=freq,
                                                        delays=delays,
                                                        zenithnorm=True,
                                                        power=True)
            elif beam_model == "FEE":
                rX, rY = primary_beam.MWA_Tile_full_EE(theta,
                                                       phi,
                                                       freq=freq,
                                                       delays=delays,
                                                       zenithnorm=True,
                                                       power=True)
            else:
                #print "Unrecognised beam model '{0}'. Defaulting to 'analytic'."
                logger.warning(
                    "Unrecognised beam model '{0}'. Defaulting to 'analytic'.")
                rX, rY = primary_beam.MWA_Tile_analytic(theta,
                                                        phi,
                                                        freq=freq,
                                                        delays=delays,
                                                        zenithnorm=True,
                                                        power=True)

            PowersX[:, t, f] = rX
            PowersY[:, t, f] = rY

    # Convert X and Y powers into total intensity
    Powers = 0.5 * (PowersX + PowersY)

    return Powers
コード例 #13
0
def createArrayFactor(za, az, pixel_area, data):
    """
    Primary function to calculate the array factor with the given information.

    Input:
      delays - the beamformer delays required for point tile beam (should be a set of 16 numbers)
      time -  the time at which to evaluate the target position (as we need Azimuth and Zenith angle, which are time dependent)
      obsfreq - the centre observing frequency for the observation
      eff - the array efficiency (frequency and pointing dependent, currently require engineers to calculate for us...)
      flagged_tiles - the flagged tiles from the calibration solution (in the RTS format)
      xpos - x position of the tiles
      ypos - y position of the tiles
      zpos - z position of the tiles
      theta_res - the zenith angle resolution in degrees
      phi_res - the azimuth resolution in degrees
      za_chunk - list of ZA to compute array factor for
      write -  whether to actually write a file to disk
      rank - mpi rank (thread index)
    Return:
      results -  a list of lists cotaining [ZA, Az, beam power], for all ZA and Az in the given band
    """
    obsid = data['obsid']
    ra = data['ra']
    dec = data['dec']
    times = data['time']
    delays = data['delays']
    xpos = data['x']
    ypos = data['y']
    zpos = data['z']
    cable_delays = data['cd']
    theta_res = data['tres']
    phi_res = data['pres']
    beam_model = data['beam']
    coplanar = data['coplanar']
    ord_version = data['ord_version']
    no_delays = data['no_delays']
    plot_jobid = data['plot_jobid']

    # work out core depent part of data to process
    nfreq = len(data['freqs'])
    ifreq = rank % nfreq
    ichunk = rank // nfreq
    obsfreq = data['freqs'][ifreq]

    logger.info( "rank {:3d} Calculating phase of each sky position for each tile".format(rank))
    # calculate the relevent wavenumber for (theta,phi)
    #logger.info( "rank {:3d} Calculating wavenumbers".format(rank))
    if ord_version:
        #gx, gy, gz = calc_geometric_delay_distance((np.pi / 2) - az, za)
        gx, gy, gz = calc_geometric_delay_distance(az, za)
        logger.debug("rank {:3d} Wavenumbers shapes: {} {} {}".format(rank, gx.shape, gy.shape, gz.shape))

        # phase of each sky position for each tile
        ph_tile = cal_phase_ord(xpos, ypos, zpos, cable_delays, gx, gy, gz, obsfreq,
                                coplanar=coplanar, no_delays=no_delays)
        gx = gy = gz = None # Dereference for garbage collection
    else:
        kx, ky, kz = calcWaveNumbers(obsfreq, (np.pi / 2) - az, za)
        #logger.debug("kx[0] {} ky[0] {} kz[0] {}".format(kx[0], ky[0], kz[0]))
        logger.debug("rank {:3d} Wavenumbers shapes: {} {} {}".format(rank, kx.shape, ky.shape, kz.shape))

        # phase of each sky position for each tile
        ph_tile = calcSkyPhase(xpos, ypos, zpos, kx, ky, kz, coplanar=coplanar)
        kx = ky = kz = None # Dereference for garbage collection


    requests.get('https://ws.mwatelescope.org/progress/update',
                 params={'jobid':plot_jobid,
                         'workid':rank,
                         'current':2,
                         'total':5,
                         'desc':'Tile beam'})

    # calculate the tile beam at the given Az,ZA pixel
    logger.info( "rank {:3d} Calculating tile beam".format(rank))
    if beam_model == 'hyperbeam':
        # This method is no longer needed as mwa_pb uses hyperbeam
        jones = beam.calc_jones_array(az, za, obsfreq, delays, [1.0] * 16, True)
        jones = jones.reshape(za.shape[0], 1, 2, 2)
        vis = pb.mwa_tile.makeUnpolInstrumentalResponse(jones, jones)
        jones = None # Dereference for garbage collection
        tile_xpol, tile_ypol = (vis[:, :, 0, 0].real, vis[:, :, 1, 1].real)
        vis = None # Dereference for garbage collection
    elif beam_model == 'analytic':
        tile_xpol, tile_ypol = pb.MWA_Tile_analytic(za, az,
                                                freq=obsfreq, delays=[delays, delays],
                                                zenithnorm=True,
                                                power=True)
    elif beam_model == 'advanced':
        tile_xpol, tile_ypol = pb.MWA_Tile_advanced(za, az,
                                                freq=obsfreq, delays=[delays, delays],
                                                zenithnorm=True,
                                                power=True)
    elif beam_model == 'full_EE':
        tile_xpol, tile_ypol = pb.MWA_Tile_full_EE(za, az,
                                                freq=obsfreq, delays=np.array([delays, delays]),
                                                zenithnorm=True,
                                                power=True,
                                                interp=False)
    #logger.info("rank {:3d} Combining tile pattern".format(rank))
    tile_pattern = np.divide(np.add(tile_xpol, tile_ypol), 2.0)
    tile_pattern = tile_pattern.flatten()
    logger.debug("max(tile_pattern) {}".format(max(tile_pattern)))


    omega_A_times = []
    sum_B_T_times = []
    sum_B_times   = []
    phased_array_pattern_times = []
    for ti, time in enumerate(times):
        requests.get('https://ws.mwatelescope.org/progress/update',
                    params={'jobid':plot_jobid,
                            'workid':rank,
                            'current':3+ti,
                            'total'  :3+len(times),
                            'desc':'{}/{} array factor'.format(1+ti, len(times))})
        # get the target azimuth and zenith angle in radians and degrees
        # these are defined in the normal sense: za = 90 - elevation, az = angle east of North (i.e. E=90)
        logger.info( "rank {:3d} Calculating phase of each sky position for the target at time {}".format(rank, time))
        srcAz, srcZA, _, _ = getTargetAZZA(ra, dec, time)# calculate the target (kx,ky,kz)

        if ord_version:
            #t_gx, t_gy, t_gz = calc_geometric_delay_distance((np.pi / 2) - srcAz, srcZA)
            t_gx, t_gy, t_gz = calc_geometric_delay_distance(srcAz, srcZA)

            # phase of each sky position for each tile
            ph_target = cal_phase_ord(xpos, ypos, zpos, cable_delays, t_gx, t_gy, t_gz, obsfreq,
                                      coplanar=coplanar, no_delays=no_delays)
        else:
            target_kx, target_ky, target_kz = calcWaveNumbers(obsfreq, (np.pi / 2) - srcAz, srcZA)

            # Get phase of target for each tile phase of each sky position for each tile
            ph_target = calcSkyPhase(xpos, ypos, zpos, target_kx, target_ky, target_kz)

        # determine the interference pattern seen for each tile
        logger.info( "rank {:3d} Calculating array_factor".format(rank))
        #logger.debug("rank {:3d} ti: {} ph_tile {}".format(rank, ti, ph_tile))
        #logger.debug("rank {:3d} ti: {} ph_target {}".format(rank, ti, ph_target))
        array_factor, array_factor_power = calcArrayFactor(ph_tile, ph_target)
        ph_target = None # Dereference for garbage collection

        #logger.debug("array_factor_power[0] {}".format(array_factor_power[0]))
        logger.debug("rank {:3d} array_factor[0] {}".format(rank, array_factor[0]))
        logger.debug("rank {:3d} array_factor shapes: {}".format(rank, array_factor.shape))
        logger.debug("rank {:3d} array factor maximum = {}".format(rank, np.amax(array_factor_power)))

        # calculate the phased array power pattern
        logger.info( "rank {:3d} Calculating phased array pattern".format(rank))
        logger.debug("rank {:3d} tile_pattern.shape {} array_factor_power.shape {}".format(rank, tile_pattern.shape, array_factor_power.shape))
        phased_array_pattern = np.multiply(tile_pattern, array_factor_power)
        #phased_array_pattern = tile_pattern[0][0] * np.abs(array_factor)**2 # indexing due to tile_pattern now being a 2-D array
        phased_array_pattern_times.append(phased_array_pattern)

        # add this contribution to the beam solid angle
        logger.info( "rank {:3d} Calculating omega_A".format(rank))
        #omega_A_array = np.sin(za) * array_factor_power * np.radians(theta_res) * np.radians(phi_res)
        #omega_A_array = np.multiply(np.multiply(np.multiply(np.sin(za), array_factor_power), np.radians(theta_res)), np.radians(phi_res))
        omega_A_array = np.multiply(array_factor_power, pixel_area)
        logger.debug("rank {:3d} omega_A_array shapes: {}".format(rank, omega_A_array.shape))
        omega_A = np.sum(omega_A_array)
        logger.debug("rank {:3d} freq {:.2f}MHz beam_area: {}".format(rank, obsfreq/1e6, omega_A))
        omega_A_times.append(omega_A)
        #logger.debug("omega_A[1] vals: za[1] {}, array_factor_power[1] {}, theta_res {}, phi_res {}".format(za[1], array_factor_power[1], theta_res, phi_res))
        #logger.debug("omega_A[1] {}".format(omega_A_array[1]))

        # Do a partial sum over the sky and frequency to be finished outside of the function
        sum_B_T, sum_B = partial_convolve_sky_map(az, za, pixel_area, phased_array_pattern, obsfreq, time)
        sum_B_T_times.append(sum_B_T)
        sum_B_times.append(sum_B)
    ph_tile = None # Dereference for garbage collection

    # Average over time
    #omega_A = np.average(omega_A_times)
    #sum_B_T = np.average(sum_B_T_times)
    #sum_B   = np.average(sum_B_times)
    #phased_array_pattern = np.average(phased_array_pattern_times, axis=0)
    logger.debug("rank {:3d} phased_array_pattern: {}".format(rank, phased_array_pattern))
    logger.debug("rank {:3d} omega_A_times: {}".format(rank, omega_A_times))
    logger.info("rank {:3d} done".format(rank))

    # return lists of results for each time step
    return np.array(omega_A_times), np.array(sum_B_T_times), np.array(sum_B_times), np.array(phased_array_pattern_times)
コード例 #14
0
def test_hyperbeam_vs_pb():
    """Compares the results of the FEE beam model using mwa_pb and mwa_hyperbeam."""
    beam = mwa_hyperbeam.FEEBeam(config.h5file)

    # Set up fake data.
    n = 100000
    az = np.linspace(0, 0.9 * np.pi, n)
    za = np.linspace(0.1, 0.9 * np.pi / 2, n)
    freq = 167000000
    delays = [0] * 16
    amps = [1.0] * 16
    test_decimals = 4

    # Jones --------------------------------------------------
    print("Jones benchmarks")
    # mwa_pb method
    start_time = time.perf_counter()
    pb_jones = primary_beam.MWA_Tile_full_EE(za,
                                             az,
                                             freq=freq,
                                             delays=np.array(delays),
                                             zenithnorm=True,
                                             power=True,
                                             jones=True,
                                             interp=False)
    print("mwa_pb:    {:6.3f} s".format(time.perf_counter() - start_time))

    # hyperbeam method
    #print(freq, delays, amps)
    start_time = time.perf_counter()
    hb_jones = beam.calc_jones_array(az, za, freq, delays, amps, True)
    print("hyperbeam: {:6.3f} s".format(time.perf_counter() - start_time))
    hb_jones = hb_jones.reshape(n, 2, 2)

    # Compare Jones
    assert_almost_equal(pb_jones, hb_jones, decimal=test_decimals)

    # Power ---------------------------------------------------
    print("\nPower benchmarks")
    # mwa_pb method
    start_time = time.perf_counter()
    pb_xx, pb_yy = primary_beam.MWA_Tile_full_EE(za,
                                                 az,
                                                 freq=freq,
                                                 delays=np.array(delays),
                                                 zenithnorm=True,
                                                 power=True)
    print("mwa_pb:    {:6.3f} s".format(time.perf_counter() - start_time))

    # hyperbeam method
    start_time = time.perf_counter()
    hb_jones = beam.calc_jones_array(az, za, freq, delays, amps, True)
    hb_jones = hb_jones.reshape(1, n, 2, 2)
    vis = primary_beam.mwa_tile.makeUnpolInstrumentalResponse(
        hb_jones, hb_jones)
    hb_xx, hb_yy = (vis[:, :, 0, 0].real, vis[:, :, 1, 1].real)
    print("hyperbeam: {:6.3f} s".format(time.perf_counter() - start_time))

    # Compare power
    assert_almost_equal(pb_xx, hb_xx[0], decimal=test_decimals)
    assert_almost_equal(pb_yy, hb_yy[0], decimal=test_decimals)
コード例 #15
0
def mwapbeam(za, az, frequencies, fluxes, metafits=None, jones=False):
    """Calculate MWA beam response using MWAPB package

    Parameters
    ----------
    za : array-like
        Zenith angles in radians
    az : array-like
        Azimuth angles in radians
    frequencies : array-like
        frequency channels
    fluxes : array-like
        Source flux densities in Jys
    metafits : string, optional
        Path to observation ID metafits file, by default None
    jones : bool, optional
        True calculates beam jones else XX and YY attenuaton values directly, by default False

    Returns
    -------
    [type]
        [description]
    """
    with fits.open(metafits) as hdu:
        delays = list(map(int, hdu[0].header["DELAYS"].split(",")))
        delays = [delays, delays]

    if jones:
        pjones = np.zeros((len(za), len(frequencies), 4), dtype=np.complex64)
        for chan in range(len(frequencies)):
            pjones[:, chan, :] = np.reshape(
                primary_beam.MWA_Tile_full_EE(za,
                                              az,
                                              freq=frequencies[chan],
                                              delays=delays,
                                              jones=True),
                (len(az), 4),
            )
        fluxes[:, :, 0] = (
            pjones[:, :, 0] * np.conj(pjones[:, :, 0]) * fluxes[:, :, 0] +
            pjones[:, :, 1] * np.conj(pjones[:, :, 1]) * fluxes[:, :, 0])
        fluxes[:, :, 3] = (
            pjones[:, :, 2] * np.conj(pjones[:, :, 2]) * fluxes[:, :, 3] +
            pjones[:, :, 3] * np.conj(pjones[:, :, 3]) * fluxes[:, :, 3])
    else:
        attenuations = np.zeros((len(za), len(frequencies), 4),
                                dtype=np.float32)
        for chan in range(len(frequencies)):
            XX, YY = primary_beam.MWA_Tile_full_EE(
                za,
                az,
                freq=frequencies[chan],
                delays=delays,
                zenithnorm=True,
                power=True,
                interp=False,
            )

            attenuations[:, chan, 0] = XX
            attenuations[:, chan, 3] = YY
        fluxes *= attenuations
    return fluxes
コード例 #16
0
def get_beam_power_over_time(names_ra_dec,
                             common_metadata=None,
                             dt=296,
                             centeronly=True,
                             verbose=False,
                             option='analytic',
                             degrees=False,
                             start_time=0):
    """Calculates the zenith normalised power for each source over time.

    Parameters
    ----------
    names_ra_dec : `list`
        An array in the format [[source_name, RAJ, DecJ]]
    common_metadata : `list`, optional
        The list of common metadata generated from :py:meth:`vcstools.metadb_utils.get_common_obs_metadata`
    dt : `int`, optional
        The time interval of how often powers are calculated. |br| Default: 296.
    centeronly : `boolean`, optional
        Only calculates for the centre frequency. |br| Default: `True`.
    verbose : `boolean`, optional
        If `True` will not supress the output from mwa_pb. |br| Default: `False`.
    option : `str`, optional
        The primary beam model to use out of [analytic, advanced, full_EE, hyperbeam]. |br| Default: analytic.
    degrees : `boolean`, optional
        If true assumes RAJ and DecJ are in degrees. |br| Default: `False`.
    start_time : `int`, optional
        The time in seconds from the begining of the observation to start calculating at. |br| Default: 0.

    Returns
    -------
    Powers : `numpy.array`, (len(names_ra_dec), ntimes, nfreqs)
        The zenith normalised power for each source over time.
    """
    if common_metadata is None:
        common_metadata = get_common_obs_metadata(obsid)
    obsid, _, _, time, delays, centrefreq, channels = common_metadata
    names_ra_dec = np.array(names_ra_dec)
    amps = [1.0] * 16
    logger.debug("Calculating beam power for OBS ID: {0}".format(obsid))

    if option == 'hyperbeam':
        if "mwa_hyperbeam" not in sys.modules:
            logger.error(
                "mwa_hyperbeam not installed so can not use hyperbeam to create a beam model. Exiting"
            )
            sys.exit(1)
        beam = mwa_hyperbeam.FEEBeam(config.h5file)

    # Work out time steps to calculate over
    starttimes = np.arange(start_time, time + start_time, dt)
    stoptimes = starttimes + dt
    stoptimes[stoptimes > time] = time
    ntimes = len(starttimes)
    midtimes = float(obsid) + 0.5 * (starttimes + stoptimes)

    # Work out frequency steps
    if centeronly:
        if centrefreq > 1e6:
            logger.warning(
                "centrefreq is greater than 1e6, assuming input with units of Hz."
            )
            frequencies = np.array([centrefreq])
        else:
            frequencies = np.array([centrefreq]) * 1e6
        nfreqs = 1
    else:
        # in Hz
        frequencies = np.array(channels) * 1.28e6
        nfreqs = len(channels)

    # Set up np power array
    PowersX = np.zeros((len(names_ra_dec), ntimes, nfreqs))
    PowersY = np.zeros((len(names_ra_dec), ntimes, nfreqs))

    # Convert RA and Dec to desired units
    if degrees:
        RAs = np.array(names_ra_dec[:, 1], dtype=float)
        Decs = np.array(names_ra_dec[:, 2], dtype=float)
    else:
        RAs, Decs = sex2deg(names_ra_dec[:, 1], names_ra_dec[:, 2])
    # Then check if they're valid
    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

    if verbose is False:
        #Supress print statements of the primary beam model functions
        sys.stdout = open(os.devnull, 'w')
    for itime in range(ntimes):
        # this differ's from the previous ephem_utils method by 0.1 degrees
        _, Azs, Zas = mwa_alt_az_za(midtimes[itime],
                                    ra=RAs,
                                    dec=Decs,
                                    degrees=True)
        # go from altitude to zenith angle
        theta = np.radians(Zas)
        phi = np.radians(Azs)
        for ifreq in range(nfreqs):
            #Decide on beam model
            if option == 'analytic':
                rX, rY = primary_beam.MWA_Tile_analytic(
                    theta,
                    phi,
                    freq=frequencies[ifreq],
                    delays=delays,
                    zenithnorm=True,
                    power=True)
            elif option == 'advanced':
                rX, rY = primary_beam.MWA_Tile_advanced(
                    theta,
                    phi,
                    freq=frequencies[ifreq],
                    delays=delays,
                    zenithnorm=True,
                    power=True)
            elif option == 'full_EE':
                rX, rY = primary_beam.MWA_Tile_full_EE(theta,
                                                       phi,
                                                       freq=frequencies[ifreq],
                                                       delays=delays,
                                                       zenithnorm=True,
                                                       power=True)
            elif option == 'hyperbeam':
                jones = beam.calc_jones_array(phi, theta,
                                              int(frequencies[ifreq]),
                                              delays[0], amps, True)
                jones = jones.reshape(1, len(phi), 2, 2)
                vis = primary_beam.mwa_tile.makeUnpolInstrumentalResponse(
                    jones, jones)
                rX, rY = (vis[:, :, 0, 0].real, vis[:, :, 1, 1].real)
        PowersX[:, itime, ifreq] = rX
        PowersY[:, itime, ifreq] = rY
    if verbose is False:
        sys.stdout = sys.__stdout__
    Powers = 0.5 * (PowersX + PowersY)
    return Powers