Exemplo n.º 1
0
    def test_baseline_ind(self):
        """Test that the baselines generated with indicies do return indicies and vice
        versa."""

        standList = numpy.array([100, 101, 102, 103])

        bl = uvutils.get_baselines(standList,
                                   include_auto=False,
                                   indicies=False)
        bl = numpy.array(bl)
        self.assertTrue(bl.min() == 100)
        bl = uvutils.get_baselines(standList,
                                   include_auto=True,
                                   indicies=False)
        bl = numpy.array(bl)
        self.assertTrue(bl.min() == 100)

        bl = uvutils.get_baselines(standList,
                                   include_auto=False,
                                   indicies=True)
        bl = numpy.array(bl)
        self.assertTrue(bl.max() < 100)
        bl = uvutils.get_baselines(standList, include_auto=True, indicies=True)
        bl = numpy.array(bl)
        self.assertTrue(bl.max() < 100)
Exemplo n.º 2
0
    def test_baseline_gen(self):
        """Test that the generated baselines contain the correct numbers of elements."""

        standList = numpy.array([100, 101, 102, 103])

        bl = uvutils.get_baselines(standList,
                                   include_auto=False,
                                   indicies=False)
        self.assertEqual(len(bl), 6)
        bl = uvutils.get_baselines(standList,
                                   include_auto=True,
                                   indicies=False)
        self.assertEqual(len(bl), 10)
Exemplo n.º 3
0
    def test_baseline_lookup(self):
        """Test antennas to baseline lookup function."""

        standList = numpy.array([100, 101, 102, 103])
        bl = uvutils.get_baselines(standList,
                                   include_auto=False,
                                   indicies=False)

        ind = uvutils.antennas_to_baseline(100,
                                           101,
                                           standList,
                                           include_auto=False,
                                           indicies=False)
        self.assertEqual(ind, 0)

        ind = uvutils.antennas_to_baseline(100,
                                           102,
                                           standList,
                                           baseline_list=bl)
        self.assertEqual(ind, 1)

        ind = uvutils.antennas_to_baseline(0,
                                           3,
                                           standList,
                                           include_auto=False,
                                           indicies=True)
        self.assertEqual(ind, 2)
Exemplo n.º 4
0
    def __initData(self):
        """Private function to generate a random set of data for writing a FITS
        IDI file.  The data is returned as a dictionary with keys:
        * freq - frequency array in Hz
        * site - lwa.common.stations object
        * stands - array of stand numbers
        * bl - list of baseline pairs in real stand numbers
        * vis - array of visibility data in baseline x freq format
        """

        # Frequency range
        freq = numpy.arange(0, 512) * 20e6 / 512 + 40e6
        # Site and stands
        site = lwa_common.lwa1
        antennas = site.antennas[0:40:2]

        # Set baselines and data
        blList = uvutils.get_baselines(antennas,
                                       include_auto=True,
                                       indicies=False)
        visData = numpy.random.rand(len(blList), len(freq))
        visData = visData.astype(numpy.complex64)

        return {
            'freq': freq,
            'site': site,
            'antennas': antennas,
            'bl': blList,
            'vis': visData
        }
Exemplo n.º 5
0
    def test_antenna_lookup(self):
        """Test baseline number to antenna lookup function."""

        standList = numpy.array([100, 101, 102, 103])

        bl = uvutils.get_baselines(standList,
                                   include_auto=False,
                                   indicies=False)
        ind = uvutils.baseline_to_antennas(0, standList)
        self.assertEqual(ind[0], 100)
        self.assertEqual(ind[1], 101)

        ind = uvutils.baseline_to_antennas(1, standList, baseline_list=bl)
        self.assertEqual(ind[0], 100)
        self.assertEqual(ind[1], 102)
Exemplo n.º 6
0
def main(args):
    # Build up the station
    site = stations.lwa1
    observer = site.get_observer()

    # Load in the file file to figure out what to do
    dataDict = numpy.load(args.filename[0])
    tStart = dataDict['tStart'].item()
    tInt = dataDict['tInt']
    freq = dataDict['freq1']
    junk0, refSrc, junk1, junk2, junk3, readers, antennas = read_correlator_configuration(
        dataDict)
    dataDict.close()

    # Prune down to a single polarization
    antennas = [ant for ant in antennas if ant.pol == 0]

    # Build up the list of baselines
    blList = uvutils.get_baselines(antennas)

    # Loop through the files and do what we need to do
    t = []
    uvw = []
    for filename in args.filename:
        ## Load in the integration
        dataDict = numpy.load(filename)

        tStart = dataDict['tStart'].item()
        tInt = dataDict['tInt'].item()

        dataDict.close()

        ## Update the observation
        observer.date = datetime.utcfromtimestamp(tStart).strftime(
            '%Y/%m/%d %H:%M:%S.%f')
        refSrc.compute(observer)
        HA = (observer.sidereal_time() - refSrc.ra) * 12 / numpy.pi
        dec = refSrc.dec * 180 / numpy.pi

        ## Compute u, v, and w
        t.append(datetime.utcfromtimestamp(tStart))
        uvw.append(
            uvutils.compute_uvw(antennas,
                                HA=HA,
                                dec=dec,
                                freq=freq.mean(),
                                site=observer))
    uvw = numpy.array(uvw) / 1e3

    # Compute the baseline lengths
    blLength = numpy.sqrt((uvw**2).sum(axis=2))
    print(len(blList), uvw.shape, blLength.shape)

    # Report
    print("Phase Center:")
    print("  Name: %s" % refSrc.name)
    print("  RA: %s" % refSrc._ra)
    print("  Dec: %s" % refSrc._dec)
    print("Antennas:")
    print("  Total: %i" % len(readers))
    print("  VDIF: %i" % sum([1 for rdr in readers if rdr is vdif]))
    print("  DRX: %i" % sum([1 for rdr in readers if rdr is drx]))
    print("Baselines:")
    print("  Total: %i" % (uvw.shape[0] * uvw.shape[1]))
    ## Minimum basline length
    m = numpy.argmin(blLength)
    b = m % uvw.shape[1]
    bl0 = blList[b][0].stand.id
    if bl0 < 50:
        bl0 = 'EA%02i' % bl0
    else:
        bl0 = 'LWA%i' % (bl0 - 50)
    bl1 = blList[b][1].stand.id
    if bl1 < 50:
        bl1 = 'EA%02i' % bl1
    else:
        bl1 = 'LWA%i' % (bl1 - 50)
    print("  Minimum: %.2f klambda (%s <-> %s)" % (blLength.min(), bl0, bl1))
    print("  Median: %.2f klambda" % numpy.median(blLength))
    ## Maximum baseline length
    m = numpy.argmax(blLength)
    b = m % uvw.shape[1]
    bl0 = blList[b][0].stand.id
    if bl0 < 50:
        bl0 = 'EA%02i' % bl0
    else:
        bl0 = 'LWA%i' % (bl0 - 50)
    bl1 = blList[b][1].stand.id
    if bl1 < 50:
        bl1 = 'EA%02i' % bl1
    else:
        bl1 = 'LWA%i' % (bl1 - 50)
    print("  Maximum %.2f klambda (%s <-> %s)" % (blLength.max(), bl0, bl1))

    # Plot
    fig = plt.figure()
    ax = fig.gca()
    for i in xrange(uvw.shape[0]):
        l, = ax.plot(uvw[i, :, 0],
                     uvw[i, :, 1],
                     linestyle='',
                     marker='o',
                     ms=3.0,
                     alpha=0.2)
        ax.plot(-uvw[i, :, 0],
                -uvw[i, :, 1],
                linestyle='',
                marker='o',
                ms=3.0,
                alpha=0.2,
                color=l.get_color())
    ax.set_xlabel('u [$k\\lambda$]')
    ax.set_ylabel('v [$k\\lambda$]')
    ax.set_title('%s\n%s to %s' %
                 (refSrc.name, min(t).strftime("%m/%d %H:%M:%S"),
                  max(t).strftime("%m/%d %H:%M:%S")))
    plt.show()
def main(args):

    h5fi = h5py.File(args.input_file, 'r')
    h5fo = h5py.File(args.output_file,'w')

    # Copy over important attributes
    for key in h5fi.attrs.keys():
        h5fo.attrs[key]=h5fi.attrs[key]
    
    # Copy over important datasets
    for key in h5fi.keys():
        temp_arr = h5fi[key]
        h5fo.create_dataset('vis_{}'.format(key),data=temp_arr)
    h5fo.attrs['grid_size']=args.size
    h5fo.attrs['grid_res']=args.res
    h5fo.attrs['grid_wres']=args.wres
    h5fo.create_dataset('l_est', (len(h5fo['vis_l_est']),))
    h5fo.create_dataset('m_est', (len(h5fo['vis_l_est']),))
    h5fo.create_dataset('extent', (len(h5fo['vis_l_est']),4))
    h5fo.create_dataset('elevation', (len(h5fo['vis_l_est']),))
    h5fo.create_dataset('azimuth', (len(h5fo['vis_l_est']),))
    h5fo.create_dataset('height', (len(h5fo['vis_l_est']),))

    
    h5fi.close() # done with input data now

    ## Begin doing stuff
    antennas = station.antennas
    valid_ants, n_baselines = select_antennas(antennas, h5fo.attrs['use_pol'], exclude=[256]) # to exclude outrigger

    tx_coords = h5fo.attrs['tx_coordinates']
    rx_coords = [station.lat * 180/np.pi, station.lon * 180/np.pi]

    ## Build freqs (same for every 'integration')
    freqs = np.empty((h5fo.attrs['fft_len'],),dtype=np.float64)
    #! Need to think of intelligent way of doing this.
    #! target_bin will probably not matter since all vis is the same
    freqs5 =   [5284999.9897182, 5291249.9897182, 5297499.9897182, 5303749.9897182,
                5309999.9897182, 5316249.9897182, 5322499.9897182, 5328749.9897182,
                5334999.9897182, 5341249.9897182, 5347499.9897182, 5353749.9897182,
                5359999.9897182, 5366249.9897182, 5372499.9897182, 5378749.9897182]
    for i in range(len(freqs)):
        freqs[i]=freqs5[i]

    ## Build bl (same for every 'integration')
    pol_string = 'xx' if h5fo.attrs['use_pol'] == 0 else 'yy'
    pol1, pol2 = pol_to_pols(pol_string)
    antennas1 = [a for a in valid_ants if a.pol == pol1]
    antennas2 = [a for a in valid_ants if a.pol == pol2]

    nStands = len(antennas1)
    baselines = uvutils.get_baselines(antennas1, antennas2=antennas2, include_auto=False, indicies=True)

    antennaBaselines = []
    for bl in range(len(baselines)):
            antennaBaselines.append( (antennas1[baselines[bl][0]], antennas2[baselines[bl][1]]) )
    bl = antennaBaselines

    uvw_m = np.array([np.array([b[0].stand.x - b[1].stand.x, b[0].stand.y - b[1].stand.y, b[0].stand.z - b[1].stand.z]) for b in bl])
    uvw = np.empty((len(bl), 3, len(freqs)))
    for i, f in enumerate(freqs):
        # wavelength = 3e8/f # TODO this should be fixed. What is currently happening is not true. Well it is, but only if you're looking for a specific transmitter frequency. Which I guess we are. I just mean it's not generalized.
        wavelength = 3e8/h5fo.attrs['tx_freq']
        uvw[:,:,i] = uvw_m/wavelength


    # Build antenna array (gets used in the VisibilityDataSet)
    # jd can't matter, right?
    jd = 2458847.2362531545
    antenna_array = simVis.build_sim_array(station, valid_ants, freqs/1e9, jd=jd, force_flat=True)
    # we only want the bin nearest to our frequency
    target_bin = np.argmin([abs(h5fo.attrs['tx_freq'] - f) for f in freqs])


    # Needed for PolarizationDataSet
    if h5fo.attrs['use_pol'] == 0:
        pol_string = 'XX'
        p=0 # this is related to the enumerate in lsl.imaging.utils.CorrelatedIDI().get_data_set() (for when there are multiple pols in a single dataset)
    else:
        raise RuntimeError("Only pol. XX supported right now.")


    if args.all_sky:
        fig, ax = plt.subplots()

    for k in np.arange(len(h5fo['vis_l_est'])):
        l_in = h5fo['vis_l_est'][k]
        m_in = h5fo['vis_m_est'][k]

        ## Build vis
        vismodel = point_source_visibility_model_uv(uvw[:,0,0],uvw[:,1,0],l_in,m_in)
        vis = np.empty((len(vismodel), len(freqs)), dtype=np.complex64)
        for i in np.arange(vis.shape[1]):
            vis[:,i] = vismodel

        if args.export_npy:
            print(args.export_npy)
            print("Exporting modelled u, v, w, and visibility")
            np.save('model-uvw{}.npy'.format(k), uvw)
            np.save('model-vis{}.npy'.format(k), vis)

        ## Start to build up the data structure for VisibilityDataSet

        dataSet = VisibilityDataSet(jd=jd, freq=freqs, baselines=bl, uvw=uvw, antennarray=antenna_array)
        polDataSet = PolarizationDataSet(pol_string, data=vis)
        dataSet.append(polDataSet)


        print('| Gridding and imaging with size={}, res={}, wres={}'.format(args.size, args.res, args.wres))

        gridded_image = build_gridded_image(dataSet, pol=pol_string,
            chan=target_bin, size=args.size,
            res=args.res, wres=args.wres)
        
        if args.export_npy:
            print("Exporting gridded u, v, and visibility")
            u,v = gridded_image.get_uv()
            np.save('gridded-u{}.npy'.format(k), u)
            np.save('gridded-v{}.npy'.format(k), v)
            np.save('gridded-vis{}.npy'.format(k), gridded_image.uv)


        l,m,img,extent=get_gimg_max(gridded_image, return_img=True)

        # Compute other values of interest
        elev, az = lm_to_ea(l, m)
        height = flatmirror_height(tx_coords, rx_coords, elev)

        h5fo['l_est'][k] = l
        h5fo['m_est'][k] = m

        h5fo['extent'][k] = extent

        h5fo['elevation'][k] = elev
        h5fo['azimuth'][k] = az
        h5fo['height'][k] = height

        if args.all_sky:
            ax.imshow(img, extent=extent, origin='lower', interpolation='nearest')
            ax.set_title('size={}, res={}, wres={}, iteration={}'.format(args.size,args.res,args.wres,k))
            ax.set_xlabel('l')
            ax.set_ylabel('m')
            ax.plot(l,m,marker='o', color='k', label='Image Max.')
            ax.plot(l_in,m_in,marker='x', color='r', label='Model (input)')
            plt.legend(loc='lower right')
            plt.savefig('allsky{}.png'.format(k))
            plt.cla()

        save_pkl_gridded = args.pkl_gridded and k in args.pkl_gridded
        if save_pkl_gridded:
            quickDict={'image':img, 'extent':extent}
            with open('gridded{}.pkl'.format(k), 'wb') as f:
                pickle.dump(quickDict, f, protocol=pickle.HIGHEST_PROTOCOL)

    h5fo.close()
Exemplo n.º 8
0
def __build_sim_data(aa,
                     srcs,
                     pols=['xx', 'yy', 'xy', 'yx'],
                     jd=None,
                     chan=None,
                     phase_center='z',
                     baselines=None,
                     mask=None,
                     verbose=False,
                     count=None,
                     max=None,
                     flat_response=False,
                     resolve_src=False):
    """
    Helper function for build_sim_data so that build_sim_data can be called with 
    a list of Julian Dates and reconstruct the data appropriately.
    
    .. versionchanged:: 1.0.1
        * Moved the simulation code over from AIPY to the new _simFast module.  
          This should be much faster but under the caveats that the bandpass
          and antenna gain patterns are the same for all antennas.  This 
          should be a reasonable assumption for large-N arrays.
        * Added a 'flat_response' keyword to make it easy to toggle on and off
          the spectral and spatial response of the array for the simulation
        * Added a 'resolve_src' keyword to turn on source resolution effects
    """

    rawFreqs = aa.get_afreqs()

    if len(rawFreqs.shape) == 2:
        nFreq = rawFreqs.shape[1]
    else:
        nFreq = rawFreqs.size
    if chan is None:
        chanMin = 0
        chanMax = -1
    else:
        chanMin = chan[0]
        chanMax = chan[-1]

    # Update the JD if necessary
    if jd is None:
        jd = aa.get_jultime()
    else:
        if verbose:
            if count is not None and max is not None:
                print("Setting Julian Date to %.5f (%i of %i)" %
                      (jd, count, max))
            else:
                print("Setting Julian Date to %.5f" % jd)
        aa.set_jultime(jd)
    Gij_sf = aa.passband(0, 1)

    def Bij_sf(xyz, pol):
        Bi = aa[0].bm_response(xyz, pol=pol[0]).transpose()
        Bj = aa[1].bm_response(xyz, pol=pol[1]).transpose()
        Bij = numpy.sqrt(Bi * Bj.conj())
        return Bij.squeeze()

    if flat_response:
        Gij_sf *= 0.0
        Gij_sf += 1.0

    # Compute the source parameters
    srcs_tp = []
    srcs_eq = []
    srcs_ha = []
    srcs_dc = []
    srcs_jy = []
    srcs_fq = []
    srcs_sh = []
    if verbose:
        print("Sources Used for Simulation:")
    for name in srcs:
        ## Update the source's coordinates
        src = srcs[name]
        src.compute(aa)

        ## Remove sources below the horizon
        srcTop = src.get_crds(crdsys='top', ncrd=3)
        srcAzAlt = aipy.coord.top2azalt(srcTop)
        if srcAzAlt[1] < 0:
            if verbose:
                print("  %s: below horizon" % name)
            continue

        ## Topocentric coordinates for the gain pattern calculations
        srcTop.shape = (1, 3)
        srcs_tp.append(srcTop)

        ## RA/dec -> equatorial
        srcEQ = src.get_crds(crdsys='eq', ncrd=3)
        srcEQ.shape = (3, 1)
        srcs_eq.append(srcEQ)

        ## HA/dec
        srcRA, srcDec = aipy.coord.eq2radec(srcEQ)
        srcHA = aa.sidereal_time() - srcRA
        srcs_ha.append(srcHA)
        srcs_dc.append(srcDec)

        ## Source flux over the bandpass - corrected for the bandpass
        jys = src.get_jys()
        jys.shape = (1, nFreq)
        jys = Gij_sf * jys
        srcs_jy.append(jys)

        ## Frequencies that the fluxes correspond to
        frq = aa.get_afreqs()
        frq.shape = (1, nFreq)
        srcs_fq.append(frq)

        ## Source shape parameters
        shp = numpy.array(src.srcshape)
        shp.shape = (3, 1)
        srcs_sh.append(shp)

    # Build the simulation cache
    aa.sim_cache(numpy.concatenate(srcs_eq, axis=1),
                 jys=numpy.concatenate(srcs_jy, axis=0),
                 mfreqs=numpy.concatenate(srcs_fq, axis=0),
                 srcshapes=numpy.concatenate(srcs_sh, axis=1))
    aa._cache['s_top'] = numpy.concatenate(srcs_tp, axis=0)
    aa._cache['s_ha'] = numpy.concatenate(srcs_ha, axis=0)
    aa._cache['s_dec'] = numpy.concatenate(srcs_dc, axis=0)

    # Build the simulated data.  If no baseline list is provided, build all
    # baselines available
    if baselines is None:
        baselines = uvutils.get_baselines(numpy.zeros(len(aa.ants)),
                                          indicies=True)

    # Define output data structure
    freq = aa.get_afreqs() * 1e9
    if len(freq.shape) == 2:
        freq = freq[0, :]
    UVData = VisibilityDataSet(jd,
                               freq,
                               baselines, [],
                               antennaarray=aa,
                               phase_center=phase_center)

    # Go!
    if phase_center != 'z':
        phase_center.compute(aa)
        pcAz = phase_center.az * 180 / numpy.pi
        pcEl = phase_center.alt * 180 / numpy.pi
    else:
        pcAz = 0.0
        pcEl = 90.0

    for p, pol in enumerate(pols):
        ## Apply the antenna gain pattern for each source
        if not flat_response:
            if p == 0:
                for i in range(aa._cache['jys'].shape[0]):
                    aa._cache['jys'][i, :] *= Bij_sf(aa._cache['s_top'][i, :],
                                                     pol)
            else:
                for i in range(aa._cache['jys'].shape[0]):
                    aa._cache['jys'][i, :] /= Bij_sf(
                        aa._cache['s_top'][i, :],
                        pols[p - 1])  # Remove the old pol
                    aa._cache['jys'][i, :] *= Bij_sf(aa._cache['s_top'][i, :],
                                                     pol)

        ## Simulate
        if not flat_response:
            uvw1, vis1 = FastVis(aa,
                                 baselines,
                                 chanMin,
                                 chanMax,
                                 pcAz,
                                 pcEl,
                                 resolve_src=resolve_src)
        else:
            currentVars = locals().keys()
            if 'uvw1' not in currentVars or 'vis1' not in currentVars:
                uvw1, vis1 = FastVis(aa,
                                     baselines,
                                     chanMin,
                                     chanMax,
                                     pcAz,
                                     pcEl,
                                     resolve_src=resolve_src)

        ## Unpack the data and add it to the data set
        if p == 0:
            UVData.uvw = uvw1
        pds = PolarizationDataSet(pol, data=vis1)
        UVData.append(pds)

    # Cleanup
    if not flat_response:
        for i in range(aa._cache['jys'].shape[0]):
            aa._cache['jys'][i, :] /= Bij_sf(aa._cache['s_top'][i, :],
                                             pols[-1])  # Remove the old pol
            aa._cache['jys'][i, :] /= Gij_sf  # Remove the bandpass

    # Return
    return UVData
Exemplo n.º 9
0
def process_chunk(idf,
                  site,
                  good,
                  filename,
                  int_time=5.0,
                  pols=[
                      'xx',
                  ],
                  chunk_size=100):
    """
    Given a lsl.reader.ldp.TBNFile instances and various parameters for the 
    cross-correlation, write cross-correlate the data and save it to a file.
    """

    # Get antennas
    antennas = site.antennas

    # Get the metadata
    sample_rate = idf.get_info('sample_rate')
    freq = idf.get_info('freq1')

    # Create the list of good digitizers and a digitizer to Antenna instance mapping.
    # These are:
    #  toKeep  -> mapping of digitizer number to array location
    #  mapper -> mapping of Antenna instance to array location
    toKeep = [antennas[i].digitizer - 1 for i in good]
    mapper = [antennas[i] for i in good]

    # Create a list of unqiue stands to know what style of IDI file to create
    stands = set([antennas[i].stand.id for i in good])

    # Main loop over the input file to read in the data and organize it.  Several control
    # variables are defined for this:
    #  ref_time -> time (in seconds since the UNIX epoch) for the first data set
    #  setTime -> time (in seconds since the UNIX epoch) for the current data set
    ref_time = 0.0
    setTime = 0.0
    wallTime = time.time()
    for s in range(chunk_size):
        try:
            readT, t, data = idf.read(int_time)
        except Exception as e:
            print("Error: %s" % str(e))
            continue

        ## Prune out what we don't want
        data = data[toKeep, :, :]

        ## Split the polarizations
        antennasX, antennasY = [
            a for i, a in enumerate(antennas) if a.pol == 0 and i in toKeep
        ], [a for i, a in enumerate(antennas) if a.pol == 1 and i in toKeep]
        dataX, dataY = data[0::2, :, :], data[1::2, :, :]
        validX = numpy.ones((dataX.shape[0], dataX.shape[2]),
                            dtype=numpy.uint8)
        validY = numpy.ones((dataY.shape[0], dataY.shape[2]),
                            dtype=numpy.uint8)

        ## Apply the cable delays as phase rotations
        for i in range(dataX.shape[0]):
            gain = numpy.sqrt(antennasX[i].cable.gain(freq))
            phaseRot = numpy.exp(2j*numpy.pi*freq*(antennasX[i].cable.delay(freq) \
                                                   -antennasX[i].stand.z/speedOfLight))
            for j in range(dataX.shape[2]):
                dataX[i, :, j] *= phaseRot / gain
        for i in range(dataY.shape[0]):
            gain = numpy.sqrt(antennasY[i].cable.gain(freq))
            phaseRot = numpy.exp(2j*numpy.pi*freq*(antennasY[i].cable.delay(freq)\
                                                   -antennasY[i].stand.z/speedOfLight))
            for j in range(dataY.shape[2]):
                dataY[i, :, j] *= phaseRot / gain

        setTime = t
        if s == 0:
            ref_time = setTime

        # Setup the set time as a python datetime instance so that it can be easily printed
        setDT = setTime.datetime
        print("Working on set #%i (%.3f seconds after set #1 = %s)" %
              ((s + 1),
               (setTime - ref_time), setDT.strftime("%Y/%m/%d %H:%M:%S.%f")))

        # Loop over polarization products
        for pol in pols:
            print("->  %s" % pol)
            if pol[0] == 'x':
                a1, d1, v1 = antennasX, dataX, validX
            else:
                a1, d1, v1 = antennasY, dataY, validY
            if pol[1] == 'x':
                a2, d2, v2 = antennasX, dataX, validX
            else:
                a2, d2, v2 = antennasY, dataY, validY

            ## Get the baselines
            baselines = uvutils.get_baselines(a1,
                                              antennas2=a2,
                                              include_auto=True,
                                              indicies=True)
            blList = []
            for bl in range(len(baselines)):
                blList.append((a1[baselines[bl][0]], a2[baselines[bl][1]]))

            ## Run the cross multiply and accumulate
            vis = XEngine2(d1, d2, v1, v2)

            # Select the right range of channels to save
            toUse = numpy.where((freq > 5.0e6) & (freq < 93.0e6))
            toUse = toUse[0]

            # If we are in the first polarazation product of the first iteration,  setup
            # the FITS IDI file.
            if s == 0 and pol == pols[0]:
                pol1, pol2 = fxc.pol_to_pols(pol)

                if len(stands) > 255:
                    fits = fitsidi.ExtendedIdi(filename, ref_time=ref_time)
                else:
                    fits = fitsidi.Idi(filename, ref_time=ref_time)
                fits.set_stokes(pols)
                fits.set_frequency(freq[toUse])
                fits.set_geometry(site, [a for a in mapper if a.pol == pol1])

            # Convert the setTime to a MJD and save the visibilities to the FITS IDI file
            obsTime = astro.unix_to_taimjd(setTime)
            fits.add_data_set(obsTime, readT, blList, vis[:, toUse], pol=pol)
        print("->  Cummulative Wall Time: %.3f s (%.3f s per integration)" %
              ((time.time() - wallTime), (time.time() - wallTime) / (s + 1)))

    # Cleanup after everything is done
    fits.write()
    fits.close()
    del (fits)
    del (data)
    del (vis)
    return True
Exemplo n.º 10
0
def main(args):
    # Parse the command line
    filenames = args.filename
    if args.regex:
        filenames = []
        for regex in args.filename:
            filenames.extend(glob.glob(regex))
    try:
        filenames.sort(cmp=cmpNPZ)
    except TypeError:
        filenames.sort(key=cmp_to_key(cmpNPZ))
    if args.limit != -1:
        filenames = filenames[:args.limit]

    # Build up the station
    site = stations.lwa1
    observer = site.get_observer()

    # Load in the file file to figure out what to do
    dataDict = numpy.load(filenames[0])
    tStart = dataDict['tStart'].item()
    tInt = dataDict['tInt']

    freq = dataDict['freq1']

    config, refSrc, junk1, junk2, junk3, junk4, antennas = read_correlator_configuration(
        dataDict)
    try:
        if config['basis'] == 'linear':
            args.linear = True
            args.circular = False
            args.stokes = False
        elif config['basis'] == 'circular':
            args.linear = False
            args.circular = True
            args.stokes = False
        elif config['basis'] == 'stokes':
            args.linear = False
            args.circular = False
            args.stokes = True
        print(
            "NOTE:  Set output polarization basis to '%s' per user defined configuration"
            % config['basis'])
    except (TypeError, KeyError):
        pass

    visXX = dataDict['vis1XX'].astype(numpy.complex64)
    visXY = dataDict['vis1XY'].astype(numpy.complex64)
    visYX = dataDict['vis1YX'].astype(numpy.complex64)
    visYY = dataDict['vis1YY'].astype(numpy.complex64)
    dataDict.close()

    # Build up the master list of antennas and report
    master_antennas = antennas
    obs_groups = [
        os.path.basename(filenames[0]).split('-vis2', 1)[0],
    ]
    for filename in filenames:
        group = os.path.basename(filename).split('-vis2', 1)[0]
        if group not in obs_groups:
            dataDict = numpy.load(filename)
            config, refSrc, junk1, junk2, junk3, junk4, antennas = read_correlator_configuration(
                dataDict)
            del dataDict

            for ant in antennas:
                ## The FITS IDI writer only cares about the stand ID
                if (ant.stand.id, ant.pol) not in [(ma.stand.id, ma.pol)
                                                   for ma in master_antennas]:
                    master_antennas.append(ant)
            obs_groups.append(group)
    master_antennas.sort(key=lambda x: (x.stand.id, x.pol))
    for i in range(len(master_antennas)):
        master_antennas[i].id = i + 1

    print("Antennas:")
    for ant in master_antennas:
        print("  Antenna %i: Stand %i, Pol. %i" %
              (ant.id, ant.stand.id, ant.pol))

    nchan = visXX.shape[1]
    master_blList = uvutils.get_baselines(
        [ant for ant in master_antennas if ant.pol == 0], include_auto=True)

    if args.decimate > 1:
        to_trim = (freq.size / args.decimate) * args.decimate
        to_drop = freq.size - to_trim
        if to_drop != 0:
            print("Warning: Dropping %i channels (%.1f%%; %.3f kHz)" %
                  (to_drop, 100.0 * to_drop / freq.size, to_drop *
                   (freq[1] - freq[0]) / 1e3))

        nchan //= args.decimate
        if to_drop != 0:
            freq = freq[:to_trim]
        freq.shape = (freq.size // args.decimate, args.decimate)
        freq = freq.mean(axis=1)

    # Figure out the visibility conjugation problem in LSL, pre-1.1.4
    conjugateVis = False
    if float(fitsidi.__version__) < 0.9:
        print("Warning: Applying conjugate to visibility data")
        conjugateVis = True

    # Figure out our revision
    try:
        repo = git.Repo(os.path.dirname(os.path.abspath(__file__)))
        try:
            branch = repo.active_branch.name
            hexsha = repo.active_branch.commit.hexsha
        except TypeError:
            branch = '<detached>'
            hexsha = repo.head.commit.hexsha
        shortsha = hexsha[-7:]
        dirty = ' (dirty)' if repo.is_dirty() else ''
    except git.exc.GitError:
        branch = 'unknown'
        hexsha = 'unknown'
        shortsha = 'unknown'
        dirty = ''

    # Fill in the data
    for i, filename in enumerate(filenames):
        ## Load in the integration
        group = os.path.basename(filename).split('-vis2', 1)[0]
        dataDict = numpy.load(filename)
        junk0, refSrc, junk1, junk2, junk3, junk4, antennas = read_correlator_configuration(
            dataDict)
        try:
            refSrc.name = refSrc.name.upper()  # For AIPS
            if refSrc.name[:12] == 'ELWA_SESSION':
                ## Convert ELWA_SESSION names to "real" source names
                refSrc.name = getSourceName(refSrc).replace(' ', '').upper()
        except AttributeError:
            ## Moving sources cannot have their names changed
            pass
        blList = uvutils.get_baselines(
            [ant for ant in antennas if ant.pol == 0], include_auto=True)

        ## Make sure the frequencies are compatible
        cFreq = dataDict['freq1']
        if cFreq.size != freq.size:
            error_msg = "Incompatible frequencies at %s: %i != %i" % (
                group, cFreq.size, freq.size)
            if args.ignore_incompatible:
                warnings.warn(error_msg, RuntimeWarning)
                continue
            else:
                raise RuntimeError(error_msg)
        elif cFreq[0] != freq[0] or cFreq[-1] != freq[-1]:
            error_msg = "Incompatible frequencies at %s: %.3f MHz != %.3f MHz or %.3f MHz != %.3f MHz" % (
                group, cFreq[0] / 1e6, freq[0] / 1e6, cFreq[-1] / 1e6,
                freq[-1] / 1e6)
            if args.ignore_incompatible:
                warnings.warn(error_msg, RuntimeWarning)
                continue
            else:
                raise RuntimeError(error_msg)

        tStart = dataDict['tStart'].item()
        tInt = dataDict['tInt'].item()
        visXX = dataDict['vis1XX'].astype(numpy.complex64)
        visXY = dataDict['vis1XY'].astype(numpy.complex64)
        visYX = dataDict['vis1YX'].astype(numpy.complex64)
        visYY = dataDict['vis1YY'].astype(numpy.complex64)

        dataDict.close()

        if args.decimate > 1:
            if to_drop != 0:
                visXX = visXX[:, :to_trim]
                visXY = visXY[:, :to_trim]
                visYX = visYX[:, :to_trim]
                visYY = visYY[:, :to_trim]

            visXX.shape = (visXX.shape[0], visXX.shape[1] // args.decimate,
                           args.decimate)
            visXX = visXX.mean(axis=2)
            visXY.shape = (visXY.shape[0], visXY.shape[1] // args.decimate,
                           args.decimate)
            visXY = visXY.mean(axis=2)
            visYX.shape = (visYX.shape[0], visYX.shape[1] // args.decimate,
                           args.decimate)
            visYX = visYX.mean(axis=2)
            visYY.shape = (visYY.shape[0], visYY.shape[1] // args.decimate,
                           args.decimate)
            visYY = visYY.mean(axis=2)

        if conjugateVis:
            visXX = visXX.conj()
            visXY = visXY.conj()
            visYX = visYX.conj()
            visYY = visYY.conj()

        if args.circular or args.stokes:
            visI = visXX + visYY
            visQ = visXX - visYY
            visU = visXY + visYX
            visV = (visXY - visYX) / 1.0j

            if args.circular:
                visRR = visI + visV
                visRL = visQ + 1j * visU
                visLR = visQ - 1j * visU
                visLL = visI - visV

        if i % args.split == 0:
            ## Clean up the previous file
            try:
                fits.write()
                fits.close()
            except NameError:
                pass

            ## Create the FITS-IDI file as needed
            ### What to call it
            if args.tag is None:
                outname = 'buildIDI.FITS_%i' % (i // args.split + 1, )
            else:
                outname = 'buildIDI_%s.FITS_%i' % (
                    args.tag,
                    i // args.split + 1,
                )

            ### Does it already exist or not
            if os.path.exists(outname):
                if not args.force:
                    yn = raw_input("WARNING: '%s' exists, overwrite? [Y/n] " %
                                   outname)
                else:
                    yn = 'y'

                if yn not in ('n', 'N'):
                    os.unlink(outname)
                else:
                    raise RuntimeError("Output file '%s' already exists" %
                                       outname)

            ### Create the file
            fits = fitsidi.Idi(outname, ref_time=tStart)
            if args.circular:
                fits.set_stokes(['RR', 'RL', 'LR', 'LL'])
            elif args.stokes:
                fits.set_stokes(['I', 'Q', 'U', 'V'])
            else:
                fits.set_stokes(['XX', 'XY', 'YX', 'YY'])
            fits.set_frequency(freq)
            fits.set_geometry(stations.lwa1,
                              [a for a in master_antennas if a.pol == 0])
            if config['context'] is not None:
                mode = 'LSBI'
                if min([ma.stand.id for ma in master_antennas]) < 50 \
                   and max([ma.stand.id for ma in master_antennas]) > 50:
                    mode = 'ELWA'
                elif min([ma.stand.id for ma in master_antennas]) < 50:
                    mode = 'VLA'

                fits.set_observer(config['context']['observer'],
                                  config['context']['project'], 'eLWA')
                if config['context']['session'] is not None:
                    fits.add_header_keyword('session',
                                            config['context']['session'])
                if config['context']['vlaref'] is not None:
                    fits.add_header_keyword('vlaref',
                                            config['context']['vlaref'])
                fits.add_header_keyword('instrume', mode)
            fits.add_history(
                'Created with %s, revision %s.%s%s' %
                (os.path.basename(__file__), branch, shortsha, dirty))
            print("Opening %s for writing" % outname)

        if i % 10 == 0:
            print(i)

        ## Update the observation
        observer.date = datetime.utcfromtimestamp(tStart).strftime(
            '%Y/%m/%d %H:%M:%S.%f')
        refSrc.compute(observer)

        ## Convert the setTime to a MJD and save the visibilities to the FITS IDI file
        obsTime = astro.unix_to_taimjd(tStart)
        if args.circular:
            fits.add_data_set(obsTime,
                              tInt,
                              blList,
                              visRR,
                              pol='RR',
                              source=refSrc)
            fits.add_data_set(obsTime,
                              tInt,
                              blList,
                              visRL,
                              pol='RL',
                              source=refSrc)
            fits.add_data_set(obsTime,
                              tInt,
                              blList,
                              visLR,
                              pol='LR',
                              source=refSrc)
            fits.add_data_set(obsTime,
                              tInt,
                              blList,
                              visLL,
                              pol='LL',
                              source=refSrc)
        elif args.stokes:
            fits.add_data_set(obsTime,
                              tInt,
                              blList,
                              visI,
                              pol='I',
                              source=refSrc)
            fits.add_data_set(obsTime,
                              tInt,
                              blList,
                              visQ,
                              pol='Q',
                              source=refSrc)
            fits.add_data_set(obsTime,
                              tInt,
                              blList,
                              visU,
                              pol='U',
                              source=refSrc)
            fits.add_data_set(obsTime,
                              tInt,
                              blList,
                              visV,
                              pol='V',
                              source=refSrc)
        else:
            fits.add_data_set(obsTime,
                              tInt,
                              blList,
                              visXX,
                              pol='XX',
                              source=refSrc)
            fits.add_data_set(obsTime,
                              tInt,
                              blList,
                              visXY,
                              pol='XY',
                              source=refSrc)
            fits.add_data_set(obsTime,
                              tInt,
                              blList,
                              visYX,
                              pol='YX',
                              source=refSrc)
            fits.add_data_set(obsTime,
                              tInt,
                              blList,
                              visYY,
                              pol='YY',
                              source=refSrc)

    # Cleanup the last file
    fits.write()
    fits.close()
Exemplo n.º 11
0
def FXStokes(signals,
             antennas,
             LFFT=64,
             overlap=1,
             include_auto=False,
             verbose=False,
             window=null_window,
             pfb=False,
             sample_rate=None,
             central_freq=0.0,
             gain_correct=False,
             return_baselines=False,
             clip_level=0,
             phase_center='z'):
    """
    A more advanced version of FXCorrelator for TBW and TBN data.  Given an 
    2-D array of signals (stands, time-series) and an array of stands, compute 
    the cross-correlation of the data for all baselines.  Return the frequencies 
    and visibilities as a two-elements tuple.
    
    .. versionchanged:: 2.0.1
        Added support for phase_center to be an astropy.coordinates.AltAz instance
    
    .. versionchanged:: 1.0.0
        Added a phase_center keyword that accept a two-element tuple of 
        azimuth and elelvation (in degrees) to change where the 
        correlations are phased to
        
    .. versionchanged:: 1.1.0
        Made the 'phase_center' keyword more flexible.  It can now be either:
         * 'z' to denote the zenith,
         * a ephem.Body instances which has been computed for the observer, or
         * a two-element tuple of azimuth, elevation in degrees.
         
    .. versionchanged:: 1.2.5
        Added the 'pfb' keyword.
    """

    # Since we want to compute Stokes parameters, we need both pols
    pol1 = 0
    pol2 = 1

    antennas1 = [a for a in antennas if a.pol == pol1]
    signalsIndex1 = [i for (i, a) in enumerate(antennas) if a.pol == pol1]
    antennas2 = [a for a in antennas if a.pol == pol2]
    signalsIndex2 = [i for (i, a) in enumerate(antennas) if a.pol == pol2]

    nStands = len(antennas1)
    baselines = uvutils.get_baselines(antennas1,
                                      antennas2=antennas2,
                                      include_auto=include_auto,
                                      indicies=True)

    # Figure out if we are working with complex (I/Q) data or only real.  This
    # will determine how the FFTs are done since the real data mirrors the pos-
    # itive and negative Fourier frequencies.
    if signals.dtype.kind == 'c':
        lFactor = 1
        doFFTShift = True
        central_freq = float(central_freq)
    else:
        lFactor = 2
        doFFTShift = False

    if sample_rate is None:
        sample_rate = dp_common.fS
    freq = numpy.fft.fftfreq(lFactor * LFFT, d=1.0 / sample_rate)
    if doFFTShift:
        freq += central_freq
        freq = numpy.fft.fftshift(freq)
    freq = freq[:LFFT]

    # Get the location of the phase center in radians and create a
    # pointing vector
    if phase_center == 'z':
        azPC = 0.0
        elPC = numpy.pi / 2.0
    else:
        if isinstance(phase_center, ephem.Body):
            azPC = phase_center.az * 1.0
            elPC = phase_center.alt * 1.0
        elif isinstance(phase_center, AstroAltAz):
            azPC = phase_center.az.radian
            elPC = phase_center.alt.radian
        else:
            azPC = phase_center[0] * numpy.pi / 180.0
            elPC = phase_center[1] * numpy.pi / 180.0
    source = numpy.array([
        numpy.cos(elPC) * numpy.sin(azPC),
        numpy.cos(elPC) * numpy.cos(azPC),
        numpy.sin(elPC)
    ])

    # Define the cable/signal delay caches to help correlate along and compute
    # the delays that we need to apply to align the signals
    dlyRef = len(freq) // 2
    delays1 = numpy.zeros((nStands, LFFT))
    delays2 = numpy.zeros((nStands, LFFT))
    for i in list(range(nStands)):
        xyz1 = numpy.array(
            [antennas1[i].stand.x, antennas1[i].stand.y, antennas1[i].stand.z])
        xyz2 = numpy.array(
            [antennas2[i].stand.x, antennas2[i].stand.y, antennas2[i].stand.z])

        delays1[i, :] = antennas1[i].cable.delay(freq) - numpy.dot(
            source, xyz1) / speedOfLight
        delays2[i, :] = antennas2[i].cable.delay(freq) - numpy.dot(
            source, xyz2) / speedOfLight
    if not numpy.isfinite(delays1.max()):
        delays1[numpy.where(~numpy.isfinite(delays1))] = delays1[numpy.where(
            numpy.isfinite(delays1))].max()
    if not numpy.isfinite(delays2.max()):
        delays2[numpy.where(~numpy.isfinite(delays2))] = delays2[numpy.where(
            numpy.isfinite(delays2))].max()
    if delays1[:, dlyRef].min() < delays2[:, dlyRef].min():
        minDelay = delays1[:, dlyRef].min()
    else:
        minDelay = delays2[:, dlyRef].min()
    delays1 -= minDelay
    delays2 -= minDelay

    if window is null_window:
        window = None
    if window is not None and pfb:
        raise RuntimeError(
            "Cannot use a seperate window function with the PFB")

    # F - defaults to running parallel in C via OpenMP
    if pfb:
        func = _core.PFBEngine
    else:
        func = _core.FEngine
    signalsF1, validF1 = func(signals[signalsIndex1, :],
                              freq,
                              delays1,
                              LFFT=LFFT,
                              overlap=overlap,
                              sample_rate=sample_rate,
                              clip_level=clip_level,
                              window=window)

    signalsF2, validF2 = func(signals[signalsIndex2, :],
                              freq,
                              delays2,
                              LFFT=LFFT,
                              overlap=overlap,
                              sample_rate=sample_rate,
                              clip_level=clip_level,
                              window=window)

    # X
    output = _stokes.XEngine3(signalsF1, signalsF2, validF1, validF2)
    if not include_auto:
        # Remove auto-correlations from the output of the X engine if we don't
        # need them.  To do this we need to first build the full list of baselines
        # (including auto-correlations) and then prune that.
        baselinesFull = uvutils.get_baselines(antennas1,
                                              antennas2=antennas2,
                                              include_auto=True,
                                              indicies=True)
        fom = numpy.array([a1 - a2 for (a1, a2) in baselinesFull])
        nonAuto = numpy.where(fom != 0)[0]
        output = output[:, nonAuto, :]

    # Apply cable gain corrections (if needed)
    if gain_correct:
        for bl in range(output.shape[0]):
            cableGain1 = antennas1[baselines[bl][0]].cable.gain(freq)
            cableGain2 = antennas2[baselines[bl][1]].cable.gain(freq)

            output[:, bl, :] /= numpy.sqrt(cableGain1 * cableGain2)

    # Create antenna baseline list (if needed)
    if return_baselines:
        antennaBaselines = []
        for bl in range(output.shape[1]):
            antennaBaselines.append(
                (antennas1[baselines[bl][0]], antennas2[baselines[bl][1]]))
        returnValues = (antennaBaselines, freq, output)
    else:
        returnValues = (freq, output)

    return returnValues
Exemplo n.º 12
0
def main(args):

    ## Check we should bother doing anything

    if not args.export_npy and not args.export_h5 and not args.all_sky and not args.pkl_gridded:
        raise RuntimeError(
            "You have not selected a data output of any type. Read the docstring and pick something for me to do."
        )

    # Normalize all inputs to the same length
    sizes = [int(item) for item in args.size.split(',')]
    reses = [float(item) for item in args.res.split(',')]
    wreses = [float(item) for item in args.wres.split(',')]
    maxinputlen = max(len(sizes), len(reses), len(wreses))
    if len(sizes) not in [1, maxinputlen] or len(reses) not in [
            1, maxinputlen
    ] or len(wreses) not in [1, maxinputlen]:
        raise RuntimeError(" \
        For size, res and wres you must pass either the same number of values as the max or a single value.\n \
        For example:\n \
        ALLOWED     -> sizes=175,180,190, res=0.5, wres=0.5\n \
                    -> sizes=175,180,190, res=0.5, wres=0.5,0.6,0.7\n \
        NOT ALLOWED -> sizes=175,180,190, res=0.5, wres=0.5,0.6 \
        ")
    if len(
            sizes
    ) != maxinputlen:  # You'd think there must be a good way to do this with list comprehension.
        sizes = sizes * maxinputlen
    if len(reses) != maxinputlen:
        reses = reses * maxinputlen
    if len(wreses) != maxinputlen:
        wreses = wreses * maxinputlen
    all_grid_params = []
    while len(sizes) > 0:
        all_grid_params.append({
            'size': sizes.pop(),
            'res': reses.pop(),
            'wres': wreses.pop()
        })

    ## Begin doing stuff
    tx_coords = known_transmitters.parse_args(args)
    if not transmitter_coords:
        print("Please specify a transmitter location")
        return
    rx_coords = [station.lat * 180 / np.pi, station.lon * 180 / np.pi]

    antennas = station.antennas

    valid_ants, n_baselines = select_antennas(antennas, args.use_pol)

    if args.export_h5:
        h5fname = "simulation-results.h5"
        print("Output will be written to {}".format(h5fname))
        h5f = h5py.File(h5fname, 'w')

        ats = h5f.attrs
        ats['transmitter'] = args.transmitter
        ats['tx_freq'] = args.tx_freq
        ats['valid_ants'] = [a.id for a in valid_ants]
        ats['n_baselines'] = n_baselines
        ats['fft_len'] = args.fft_len
        ats['use_pol'] = args.use_pol
        ats['int_length'] = args.integration_length
        ats['l_model'] = args.l_model
        ats['m_model'] = args.m_model

        h5f.create_dataset('l_est', (len(all_grid_params), ))
        h5f.create_dataset('m_est', (len(all_grid_params), ))
        h5f.create_dataset('wres', (len(all_grid_params), ))
        h5f.create_dataset('res', (len(all_grid_params), ))
        h5f.create_dataset('size', (len(all_grid_params), ))
        h5f.create_dataset('extent', (len(all_grid_params), 4))
        h5f.create_dataset('elevation', (len(all_grid_params), ))
        h5f.create_dataset('azimuth', (len(all_grid_params), ))
        h5f.create_dataset('height', (len(all_grid_params), ))

    ## Build freqs
    freqs = np.empty((args.fft_len, ), dtype=np.float64)
    #! Need to think of intelligent way of doing this.
    #! target_bin will probably not matter since all vis is the same
    freqs5 = [
        5284999.9897182, 5291249.9897182, 5297499.9897182, 5303749.9897182,
        5309999.9897182, 5316249.9897182, 5322499.9897182, 5328749.9897182,
        5334999.9897182, 5341249.9897182, 5347499.9897182, 5353749.9897182,
        5359999.9897182, 5366249.9897182, 5372499.9897182, 5378749.9897182
    ]
    for i in range(len(freqs)):
        freqs[i] = freqs5[i]

    ## Build bl
    pol_string = 'xx' if args.use_pol == 0 else 'yy'
    pol1, pol2 = pol_to_pols(pol_string)
    antennas1 = [a for a in valid_ants if a.pol == pol1]
    antennas2 = [a for a in valid_ants if a.pol == pol2]

    nStands = len(antennas1)
    baselines = uvutils.get_baselines(antennas1,
                                      antennas2=antennas2,
                                      include_auto=False,
                                      indicies=True)

    antennaBaselines = []
    for bl in range(len(baselines)):
        antennaBaselines.append(
            (antennas1[baselines[bl][0]], antennas2[baselines[bl][1]]))
    bl = antennaBaselines

    uvw_m = np.array([
        np.array([
            b[0].stand.x - b[1].stand.x, b[0].stand.y - b[1].stand.y,
            b[0].stand.z - b[1].stand.z
        ]) for b in bl
    ])
    uvw = np.empty((len(bl), 3, len(freqs)))
    for i, f in enumerate(freqs):
        # wavelength = 3e8/f # TODO this should be fixed. What is currently happening is not true. Well it is, but only if you're looking for a specific transmitter frequency. Which I guess we are. I just mean it's not generalized.
        wavelength = 3e8 / args.tx_freq
        uvw[:, :, i] = uvw_m / wavelength

    ## Build vis
    vismodel = point_source_visibility_model_uv(uvw[:, 0, 0], uvw[:, 1, 0],
                                                args.l_model, args.m_model)
    vis = np.empty((len(vismodel), len(freqs)), dtype=np.complex64)
    for i in np.arange(vis.shape[1]):
        vis[:, i] = vismodel

    if args.export_npy:
        print(args.export_npy)
        print("Exporting modelled u, v, w, and visibility")
        np.save('model-uvw.npy', uvw)
        np.save('model-vis.npy', vis)

    ## Start to build up the data structure for VisibilityDataSet
    # we only want the bin nearest to our frequency
    target_bin = np.argmin([abs(args.tx_freq - f) for f in freqs])

    # This can't matter, right?
    # jd = tbnf.get_info('start_time').jd
    jd = 2458847.2362531545

    # Build antenna array
    antenna_array = simVis.build_sim_array(station,
                                           antennas,
                                           freqs / 1e9,
                                           jd=jd,
                                           force_flat=True)

    dataSet = VisibilityDataSet(jd=jd,
                                freq=freqs,
                                baselines=bl,
                                uvw=uvw,
                                antennarray=antenna_array)
    if args.use_pol == 0:
        pol_string = 'XX'
        p = 0  # this is related to the enumerate in lsl.imaging.utils.CorrelatedIDI().get_data_set() (for when there are multiple pols in a single dataset)
    else:
        raise RuntimeError("Only pol. XX supported right now.")
    polDataSet = PolarizationDataSet(pol_string, data=vis)
    dataSet.append(polDataSet)

    if args.all_sky:
        fig, ax = plt.subplots()

    # Iterate over size/res/wres and generate multiple grids/images
    k = 0
    for grid_params in all_grid_params:
        print('| Gridding and imaging with size={}, res={}, wres={}'.format(
            grid_params['size'], grid_params['res'], grid_params['wres']))

        gridded_image = build_gridded_image(dataSet,
                                            pol=pol_string,
                                            chan=target_bin,
                                            size=grid_params['size'],
                                            res=grid_params['res'],
                                            wres=grid_params['wres'])

        if args.export_npy:
            print("Exporting gridded u, v, and visibility")
            u, v = gridded_image.get_uv()
            np.save(
                'gridded-u-size-{}-res-{}-wres-{}.npy'.format(
                    grid_params['size'], grid_params['res'],
                    grid_params['wres']), u)
            np.save(
                'gridded-v-size-{}-res-{}-wres-{}.npy'.format(
                    grid_params['size'], grid_params['res'],
                    grid_params['wres']), v)
            np.save(
                'gridded-vis-size-{}-res-{}-wres-{}.npy'.format(
                    grid_params['size'], grid_params['res'],
                    grid_params['wres']), gridded_image.uv)

        l, m, img, extent = get_gimg_max(gridded_image, return_img=True)

        # Compute other values of interest
        elev, az = lm_to_ea(l, m)
        height = flatmirror_height(tx_coords, rx_coords, elev)

        if args.export_h5:
            h5f['l_est'][k] = l
            h5f['m_est'][k] = m
            h5f['wres'][k] = grid_params['wres']
            h5f['res'][k] = grid_params['res']
            h5f['size'][k] = grid_params['size']

            h5f['extent'][k] = extent

            h5f['elevation'][k] = elev
            h5f['azimuth'][k] = az
            h5f['height'][k] = height

        if args.all_sky:
            ax.imshow(img,
                      extent=extent,
                      origin='lower',
                      interpolation='nearest')
            ax.set_title('size={}, res={}, wres={}'.format(
                grid_params['size'], grid_params['res'], grid_params['wres']))
            ax.set_xlabel('l')
            ax.set_ylabel('m')
            ax.plot(l, m, marker='o', color='k', label='Image Max.')
            ax.plot(args.l_model,
                    args.m_model,
                    marker='x',
                    color='r',
                    label='Model (input)')
            plt.legend(loc='lower right')
            plt.savefig('allsky_size_{}_res_{}_wres_{}.png'.format(
                grid_params['size'], grid_params['res'], grid_params['wres']))
            plt.cla()

        save_pkl_gridded = args.pkl_gridded and k in args.pkl_gridded
        if save_pkl_gridded:
            quickDict = {'image': img, 'extent': extent}
            with open(
                    'gridded_size_{}_res_{}_wres_{}.pkl'.format(
                        grid_params['size'], grid_params['res'],
                        grid_params['wres']), 'wb') as f:
                pickle.dump(quickDict, f, protocol=pickle.HIGHEST_PROTOCOL)
        k += 1

    if args.export_h5:
        h5f.close()
Exemplo n.º 13
0
def simulate_visibilities_gen(model,
                              model_params,
                              freqs,
                              antennas=stations.lwasv.antennas,
                              pol='XX',
                              noise_sigma=None):
    '''
    Returns a generator which provides simulated visibilities according to a specified model.

    Parameters:
        model: a function that takes as arugments
            - u : a np.array of u coordinates
            - v : a np.array of v coordinates
            - some number of parameters (e.g. l, m)
        and returns an np.array the same size as the u and v coordinate vectors containing the 
        visibility samples from the model at the (u,v) points.

        model_params: a list of tuples, each containing values for the
        scalar parameters of model. Each tuple will be used to call model in a
        subsequent iteration of the generator.

        freqs: a list of frequencies. for now these are just used for baseline
        calculation and not passed into the model. TODO: pass freqs to the model

        ants: a list of lsl antenna objects the baselines of which will be
        used to generate the (u,v) coordinate vectors

    Returns:
        A generator yielding a tuple of (baselines, freqs, visibilities)
            - baselines: a list of pairs of antenna objects with each pair representing a baseline
            - freqs: same as the argument freqs
            - visibilities: a numpy array of visibility samples corresponding
              to the antenna pairs in baselines for each frequency in freqs
        The generator will yield a tuple for each set of parameters in model_params.
    '''
    print("Simulating visibilities")
    print(f"| using model {model.__name__}")
    print(
        f"| received {len(model_params)} sets of parameters, will emit that many sets of visibilities"
    )

    pol1, pol2 = fxc.pol_to_pols(pol)
    antennas1 = [a for a in antennas if a.pol == pol1]
    antennas2 = [a for a in antennas if a.pol == pol2]

    baseline_indices = uvutils.get_baselines(antennas1,
                                             antennas2=antennas2,
                                             include_auto=False,
                                             indicies=True)
    baselines = []
    for bl in range(len(baseline_indices)):
        baselines.append((antennas1[baseline_indices[bl][0]],
                          antennas2[baseline_indices[bl][1]]))

    for params in model_params:

        visibilities = np.empty((len(baselines), len(freqs)),
                                dtype=np.complex128)

        for k, freq in enumerate(freqs):
            wl = 3e8 / freq

            uvw = uvw_from_antenna_pairs(baselines, wl)

            u = uvw[:, 0]
            v = uvw[:, 1]
            w = uvw[:, 2]

            visibilities[:, k] = model(u, v, w, *params)

            if noise_sigma is not None:
                noise = np.random.normal(
                    0, noise_sigma, len(visibilities)) + 1j * np.random.normal(
                        0, noise_sigma, len(visibilities))
                visibilities[:, k] += noise

        yield baselines, freqs, visibilities

    return
Exemplo n.º 14
0
def main(args):
    # Setup the site information
    station = stations.lwasv
    ants = station.antennas
    nAnt = len([a for a in ants if a.pol == 0])
    
    phase_freq_range = [0, 0]
    for filename in args.filename:
        # Open the file and get ready to go
        idf = CORFile(filename)
        nBL = idf.get_info('nbaseline')
        nchan = idf.get_info('nchan')
        tInt = idf.get_info('tint')
        nFpO = nBL * nchan / 72
        nInts = idf.get_info('nframe') / nFpO
        
        jd = astro.unix_to_utcjd(idf.get_info('start_time'))
        date = idf.get_info('start_time').datetime
        central_freq = idf.get_info('freq1')
        central_freq = central_freq[len(central_freq)/2]
        
        print("Data type:  %s" % type(idf))
        print("Samples per observations: %i" % (nFpO,))
        print("Integration Time: %.3f s" % tInt)
        print("Tuning frequency: %.3f Hz" % central_freq)
        print("Captures in file: %i (%.1f s)" % (nInts, nInts*tInt))
        print("==")
        print("Station: %s" % station.name)
        print("Date observed: %s" % date)
        print("Julian day: %.5f" % jd)
        print(" ")
        
        # Offset into the file
        offset = idf.offset(args.skip)
        if offset != 0.0:
            print("Skipped %.3f s into the file" % offset)
            
        # Open the file and go
        nFiles = int(args.duration /  tInt)
        if nFiles == 0:
            nFiles = numpy.inf
            
        fileCount = 0
        while fileCount < nFiles:
            try:
                tInt, tStart, data = idf.read(tInt)
            except Exception as e:
                print("ERROR: %s" % str(e))
                break
                
            freqs = idf.get_info('freq1')
            beginJD = astro.unix_to_utcjd( tStart )
            beginTime = datetime.utcfromtimestamp( tStart )
            
            if freqs[0] != phase_freq_range[0] or freqs[-1] != phase_freq_range[1]:
                print("Updating phasing for %.3f to %.3f MHz" % (freqs[0]/1e6, freqs[-1]/1e6))
                phase_freq_range[0] = freqs[ 0]
                phase_freq_range[1] = freqs[-1]
                
                k = 0
                phase = numpy.zeros((nBL, nchan, 2, 2), dtype=numpy.complex64)
                gaix = [a.cable.gain(freqs) for a in ants if a.pol == 0]
                gaiy = [a.cable.gain(freqs) for a in ants if a.pol == 1]
                dlyx = [a.cable.delay(freqs) - a.stand.z / speedOfLight for a in ants if a.pol == 0]
                dlyy = [a.cable.delay(freqs) - a.stand.z / speedOfLight for a in ants if a.pol == 1]
                for i in xrange(nAnt):
                    for j in xrange(i, nAnt):
                        phase[k,:,0,0] = numpy.exp(2j*numpy.pi*freqs*(dlyx[i] - dlyx[j])) \
                                            / numpy.sqrt(gaix[i]*gaix[j])
                        phase[k,:,0,1] = numpy.exp(2j*numpy.pi*freqs*(dlyx[i] - dlyy[j])) \
                                            / numpy.sqrt(gaix[i]*gaiy[j])
                        phase[k,:,1,0] = numpy.exp(2j*numpy.pi*freqs*(dlyy[i] - dlyx[j])) \
                                            / numpy.sqrt(gaiy[i]*gaix[j])
                        phase[k,:,1,1] = numpy.exp(2j*numpy.pi*freqs*(dlyy[i] - dlyy[j])) \
                                            / numpy.sqrt(gaiy[i]*gaiy[j])
                        
                        k += 1
                        
            for i in xrange(data.shape[-1]):
                data[...,i] *= phase
                
            # Convert to a dataDict
            try:
                blList  # pylint: disable=used-before-assignment
            except NameError:
                blList = uvutils.get_baselines(ants[0::2], include_auto=True)
                
            if args.output is None:
                outname = os.path.basename(filename)
                outname = os.path.splitext(outname)[0]
                outname = "%s_%i_%s.ms" % (outname, int(beginJD-astro.MJD_OFFSET), beginTime.strftime("%H_%M_%S"))
            else:
                base, ext = os.path.splitext(args.output)
                if ext == '':
                    ext = '.ms'
                outname = "%s_%i_%s%s" % (base, int(beginJD-astro.MJD_OFFSET), beginTime.strftime("%H_%M_%S"), ext)
                
            fits = measurementset.Ms(outname, ref_time=tStart)
            fits.set_stokes(['xx', 'xy', 'yx', 'yy'])
            fits.set_frequency(freqs)
            fits.set_geometry(station, ants[0::2])
            
            obsTime = astro.unix_to_taimjd(tStart)
            fits.add_data_set(obsTime, tInt, blList, data[:,:,0,0,0], pol='xx')
            fits.add_data_set(obsTime, tInt, blList, data[:,:,0,1,0], pol='xy')
            fits.add_data_set(obsTime, tInt, blList, data[:,:,1,0,0], pol='yx')
            fits.add_data_set(obsTime, tInt, blList, data[:,:,1,1,0], pol='yy')
            fits.write()
            fits.close()
            fileCount += 1
            
        idf.close()