Example #1
0
    def test_calc_delay(self):
        """Check that the beamformer.calc_delay function actually runs"""

        station = stations.lwa1
        antennas = station.antennas

        out = beamformer.calc_delay(antennas[:3])
        self.assertEqual(len(out), 3)

        out = beamformer.calc_delay(antennas[:3], freq=49.0e6)
        self.assertEqual(len(out), 3)

        out = beamformer.calc_delay(antennas[:3],
                                    freq=49.0e6,
                                    azimuth=45,
                                    elevation=30)
        self.assertEqual(len(out), 3)
Example #2
0
def main(args):
    filename = args.filename

    station = parse_ssmif(filename)
    antennas = station.antennas

    digs    = numpy.array([ant.digitizer  for ant in antennas])
    ants    = numpy.array([ant.id         for ant in antennas])
    stands  = numpy.array([ant.stand.id   for ant in antennas])
    pols    = numpy.array([ant.pol        for ant in antennas])
    antStat = numpy.array([ant.status     for ant in antennas])
    feeStat = numpy.array([ant.fee.status for ant in antennas])

    badStands = numpy.where( antStat != 3 )[0]
    badFees   = numpy.where( feeStat != 3 )[0]
    bad = numpy.where( (stands > 256) | (antStat != 3) | (feeStat != 3) )[0]
    print("Number of bad stands:   %3i" % len(badStands))
    print("Number of bad FEEs:     %3i" % len(badFees))
    print("---------------------------")
    print("Total number bad inuts: %3i" % len(bad))
    print(" ")

    dftBase = 'beams_%iMHz_%iaz_%iel_%03ibg' % (args.frequency/1e6, args.azimuth, args.elevation, args.gain*100)
    gftBase = 'beams_%iMHz_%iaz_%iel_%03ibg' % (args.frequency/1e6, args.azimuth, args.elevation, args.gain*100)

    print("Calculating delays for az. %.2f, el. %.2f at %.2f MHz" % (args.azimuth, args.elevation, args.frequency/1e6))
    delays = beamformer.calc_delay(antennas, freq=args.frequency, azimuth=args.azimuth, elevation=args.elevation)
    delays *= 1e9
    delays = delays.max() - delays
    junk = delay.list2delayfile('.', dftBase, delays)

    print("Setting gains for %i good inputs, %i bad inputs" % (len(antennas)-len(bad), len(bad)))
    bgain = args.gain
    bgain_cross = 0.0000
    gains = [[bgain, bgain_cross, bgain_cross, bgain]]*260 # initialize gain list
    for d in digs[bad]:
        # Digitizers start at 1, list indicies at 0
        i = d - 1
        gains[i/2] = [0,0,0,0]
    junk = gain.list2gainfile('.', gftBase, gains)

    print("\nDelay and gain files are:\n %s.dft\n %s.gft" % (dftBase, gftBase))
Example #3
0
def main(args):
    # Divy up the command line arguments
    filename = args[0]
    source = args[1]
    startDate = args[2]
    startTime = args[3]
    duration  = float(args[4])
    
    year, month, day = startDate.split('/', 2)
    year = int(year)
    month = int(month)
    day = int(day)
    
    hour, minute, second = startTime.split(':', 2)
    hour = int(hour)
    minute = int(minute)
    second = int(second)
        
    tStart = _MST.localize(datetime(year, month, day, hour, minute, second))
    tStart = tStart.astimezone(_UTC)
    
    # Load the SSMIF
    station = stations.parse_ssmif(filename)

    # Gather the necessary information to figure out where things are
    observer = station.get_observer()
    antennas = station.antennas

    # Find the "good" antennas to use
    digs    = numpy.array([ant.digitizer  for ant in antennas])
    ants    = numpy.array([ant.id         for ant in antennas])
    stands  = numpy.array([ant.stand.id   for ant in antennas])
    pols    = numpy.array([ant.pol        for ant in antennas])
    antStat = numpy.array([ant.status     for ant in antennas])
    feeStat = numpy.array([ant.fee.status for ant in antennas])

    badStands = numpy.where( antStat != 3 )[0]
    badFees   = numpy.where( feeStat != 3 )[0]
    bad = numpy.where( (stands > 256) | (antStat != 3) | (feeStat != 3) )[0]
    ## print("Number of bad stands:   %3i" % len(badStands))
    ## print("Number of bad FEEs:     %3i" % len(badFees))
    ## print("---------------------------")
    ## print("Total number bad inuts: %3i" % len(bad))
    ## print(" ")
    
    # Build the source list
    srcs = [ephem.Sun(), ephem.Jupiter(),]
    for line in _srcs:
        srcs.append( ephem.readdb(line) )
        
    # Identify the source to track
    refSource  = None
    for i in xrange(len(srcs)):
        if srcs[i].name.lower() == source.lower():
            refSource = srcs[i]
            source = refSource.name
    
    # Make sure we have a source to track
    if refSource is None:
        print("Unknown source '%s', quitting" % source)
        sys.exit(1)
    
    print("""#!/bin/bash
    
#
# Source tracking script for %s starting at %s
# -> tuning frequency is %.3f Hz
# -> track duration is %.3f hours
# -> update interval is %.3f minutes
#

""" % (source, tStart.astimezone(_MST), central_freq, duration, tStep))
    
    # Create the DFT files and build the script
    nSteps = int(numpy.ceil(duration * 60 / 4))
    stepSize = timedelta(0, int(tStep*60), int((tStep*60*1000000) % 1000000))
    for s in xrange(nSteps):
        # Compute the source location half-way into the step
        tBeam = tStart + timedelta(0, int(tStep*60/2), int((tStep*60/2*1000000) % 1000000))
        observer.date = tBeam.strftime("%Y/%m/%d %H:%M:%S")
        refSource.compute(observer)
        
        pointingAz = refSource.az  * 180.0 / numpy.pi
        pointingEl = refSource.alt * 180.0 / numpy.pi
        
        # Compute the delays
        delays = calc_delay(antennas, freq=central_freq, azimuth=pointingAz, elevation=pointingEl)
        delays *= 1e9
        delays = delays.max() - delays
        
        # Save - delays
        import delay
        dftBase = 'delay_beam_%s_%03i_%0.fMHz' % (source, (s+1), central_freq/1e6,)
        junk = delay.list2delayfile('.', dftBase, delays)

        # Compute gains
        gains = [[1.0, 0.0, 0.0, 1.0]]*260 # initialize gain list
        for d in digs[bad]:
            # Digitizers start at 1, list indicies at 0
            i = d - 1
            gains[i/2] = [0,0,0,0]

        # Save - gains
        import gain
        gftBase = 'delay_beam_%s_%03i_%.0fMHz' % (source, (s+1), central_freq/1e6,)
        junk = gain.list2gainfile('.', gftBase, gains)
        
        # Output script command - step start
        print("""
#
# Begin step #%i at %s
# -> %s at %.3f az, %.3f el
#
tNow=`date -u +%%s `
tNow=$(($tNow*1))

## Wait for the right time
while [ $tNow -lt %s ]; do
    sleep 5
    tNow=`date -u +%%s `
    tNow=$(($tNow*1))
done

## Send BAM commands
tString=`date `
echo "Sending BAM commands for step #%i at $tString"
""" % ((s+1), tStart.astimezone(_MST), source, pointingAz, pointingEl, tStart.astimezone(_MST).strftime('%s'), (s+1)))

        # Output script command - BAM commands
        for beam in beamsToUse:
            print("""/home/joecraig/MCS/exec/mesix DP_ BAM "%i %s.df %s.gf 1"
sleep 1""" % (beam, dftBase, gftBase))

        # Output script command - step end
        print("""
#
# End step #%i
#
""" % ((s+1),))
        
        # Update time
        tStart = tStart + stepSize
def main(args):
    # Break out the files we need
    ssmif = args.ssmif
    filenames = args.filename

    # Setup the LWA station information
    station = parse_ssmif(ssmif)
    antennas = station.antennas

    # Get an observer reader for calculations
    obs = station.get_observer()

    # Setup the beamformer gain and delay variables
    course = numpy.zeros(520)
    fine = numpy.zeros(520)
    gains = numpy.zeros((260, 4))
    gains[:, 0] = 1.0
    gains[:, 3] = 1.0
    for ant in antennas:
        if ant.combined_status != 33:
            stand = (ant.digitizer - 1) / 2
            gains[stand, :] = 0.0

    # Setup the beamformer itself
    dp = SoftwareDP(mode='DRX', filter=7, central_freq=74e6)

    # Find the target azimuth/elevation to use
    idf = TBWFile(filenames[0])
    tStart = datetime.utcfromtimestamp(idf.get_info('start_time'))
    idf.close()

    obs.date = tStart.strftime("%Y/%m/%d %H:%M:%S")
    tTransit = obs.next_transit(args.source)
    obs.date = tTransit
    args.source.compute(obs)
    targetAz = args.source.az * 180 / numpy.pi
    targetEl = args.source.alt * 180 / numpy.pi

    # Preliminary report
    print("Working on %i TBW files using SSMIF '%s'" %
          (len(filenames), os.path.basename(ssmif)))
    print("  Source: '%s'" % args.source.name)
    print("    Transit time: %s" % str(tTransit))
    print("    Transit azimuth: %.2f degrees" % targetAz)
    print("    Transet elevation: %.2f degrees" % targetEl)
    print(" ")

    # Loop over input files
    unx, lst, pwrX, pwrY = [], [], [], []
    for filename in filenames:
        ## Get the file reader
        idf = TBWFile(filename)

        ## Pull out some metadata and update the observer
        jd = astro.unix_to_utcjd(idf.get_info('start_time'))
        obs.date = ephem.Date(jd - astro.DJD_OFFSET)
        sample_rate = idf.get_info('sample_rate')
        nInts = int(
            round(idf.get_info('nframe') / (30000.0 * len(antennas) / 2)))
        transitOffset = (obs.date - tTransit) * 86400.0

        ## Metadata report
        print("Filename: %s" % os.path.basename(filename))
        print("  Data type:  %s" % type(idf))
        print("  Captures in file: %i (%.3f s)" %
              (nInts, nInts * 30000 * 400 / sample_rate))
        print("  Station: %s" % station.name)
        print("  Date observed: %s" % str(obs.date))
        print("  MJD: %.5f" % (jd - astro.MJD_OFFSET, ))
        print("  LST: %s" % str(obs.sidereal_time()))
        print("    %.1f s %s transit" %
              (abs(transitOffset), 'before' if transitOffset < 0 else 'after'))
        print(" ")

        ## Load in the data
        readT, t, data = idf.read(time_in_samples=True)

        ## Build up a time array
        t = t + numpy.arange(data.shape[1], dtype=numpy.int64)

        ## Update the beamformer delays for the pointing center(s)
        unx.append(idf.get_info('start_time'))
        lst.append(obs.sidereal_time() * 12 / numpy.pi)
        pwrX.append([])
        pwrY.append([])

        for offset in (-1, 0, 1):
            ### Compute
            delays = beamformer.calc_delay(antennas,
                                           freq=74.0e6,
                                           azimuth=targetAz,
                                           elevation=targetEl + offset)
            delays *= fS * 16
            delays = delays.max() - delays
            ### Decompose into FIFO and FIR
            course = (delays // 16)
            fine = (delays % 16)

            ## Form the beams for both polarizations
            beamX, beamY = dp.form_beam(antennas, t, data, course, fine, gains)

            ## Compute the integrated spectra
            ### Convert to int16
            beam = numpy.zeros((2, beamX.size), dtype=numpy.int16)
            beam[0, :] = (numpy.round(beamX)).astype(data.dtype)
            beam[1, :] = (numpy.round(beamY)).astype(data.dtype)
            ### Move into the frequency domain
            freq, spec = fxc.SpecMaster(beam,
                                        LFFT=8192,
                                        window=fxc.null_window,
                                        verbose=False,
                                        sample_rate=fS,
                                        clip_level=0)

            ## Save
            pwrX[-1].append(spec[0, :])
            pwrY[-1].append(spec[1, :])

        ## Done
        idf.close()

    # Convert to arrays
    unx, lst = numpy.array(unx), numpy.array(lst)
    pwrX, pwrY = numpy.array(pwrX), numpy.array(pwrY)

    # Save for later (needed for debugging)
    outname = "estimateSEFD-%s-%04i%02i%02i.npz" % (os.path.splitext(
        os.path.basename(ssmif))[0], tTransit.tuple()[0], tTransit.tuple()[1],
                                                    tTransit.tuple()[2])
    print("Saving intermediate data to '%s'" % outname)
    print(" ")
    numpy.savez(outname,
                source=args.source.name,
                freq=freq,
                unx=unx,
                lst=lst,
                pwrX=pwrX,
                pwrY=pwrY)

    # Report
    print("%s" % (args.source.name, ))
    for i in xrange(lst.size):
        print("%s:  %s  %s" %
              (str(ephem.hours(str(lst[i]))), pwrX[i, :], pwrY[i, :]))

    # Plot
    if args.plots:
        fig = plt.figure()
        ax = fig.gca()
        ax.plot(lst, pwrX, linestyle='-', marker='+')
        ax.plot(lst, pwrY, linestyle='-', marker='x')
        plt.show()
Example #5
0
def main(args):
    filename = args.filename

    # Observation start time
    tStart = "%s %s" % (args.date, args.time)

    station = parse_ssmif(filename)
    #Import the right version of the sdf module for the desired station.
    if station.name == 'LWASV':
        sdf_module = sdfADP
    else:
        sdf_module = sdf

    antennas = station.antennas

    digs = numpy.array([ant.digitizer for ant in antennas])
    ants = numpy.array([ant.id for ant in antennas])
    stands = numpy.array([ant.stand.id for ant in antennas])
    pols = numpy.array([ant.pol for ant in antennas])
    antStat = numpy.array([ant.status for ant in antennas])
    feeStat = numpy.array([ant.fee.status for ant in antennas])

    badStands = numpy.where(antStat != 3)[0]
    badFees = numpy.where(feeStat != 3)[0]
    bad = numpy.where((stands > 256) | (antStat != 3) | (feeStat != 3))[0]
    print("Number of bad stands:   %3i" % len(badStands))
    print("Number of bad FEEs:     %3i" % len(badFees))
    print("---------------------------")
    print("Total number bad inputs: %3i" % len(bad))
    print(" ")

    # Adjust the gain so that it matches the outlier better
    if args.dipole == 0:
        bgain = 20.0 / (len(antennas) - len(bad))
    else:
        bgain = 1.0

    # Setup the base gain lists for the different scenarios
    baseEmptyGain = [0.0000, 0.0000, 0.0000, 0.0000]
    if not args.y_pol:
        baseBeamGain = [bgain, 0.0000, 0.0000, 0.0000]
        baseDipoleGain = [0.0000, 1.0000, 0.0000, 0.0000]
    else:
        baseBeamGain = [0.0000, 0.0000, bgain, 0.0000]
        baseDipoleGain = [0.0000, 0.0000, 0.0000, 1.0000]

    if (args.dipole == 0):
        freq = max([args.frequency1, args.frequency2])

        # Load in the pointing correction
        pcTerms = getPointingTerms(filename)
        print(
            "Applying Pointing Correction Terms: theta=%.2f, phi=%.2f, psi=%.2f"
            % pcTerms)
        az, el = apply_pointing_correction(args.azimuth, args.elevation,
                                           *pcTerms)
        print("-> az %.2f, el %.2f to az %.2f, el %.2f" %
              (args.azimuth, args.elevation, az, el))
        print(" ")

        print("Calculating delays for az. %.2f, el. %.2f at %.2f MHz" %
              (az, el, freq / 1e6))
        delays = beamformer.calc_delay(antennas,
                                       freq=freq,
                                       azimuth=az,
                                       elevation=el)
        delays *= 1e9
        delays = delays.max() - delays
        delays = [twoByteSwap(delay_to_dpd(d)) for d in delays]

        print("Setting gains for %i good inputs, %i bad inputs" %
              (len(antennas) - len(bad), len(bad)))
        print("-> Using gain setting of %.4f for the beam" % bgain)

        gains = [[twoByteSwap(gain_to_dpg(g)) for g in baseBeamGain]
                 for i in xrange(int(len(antennas) / 2))
                 ]  # initialize gain list

        for d in digs[bad]:
            # Digitizers start at 1, list indicies at 0
            i = d - 1
            gains[i //
                  2] = [twoByteSwap(gain_to_dpg(g)) for g in baseEmptyGain]

        for i in xrange(len(stands) // 2):
            # Put the reference stand in there all by itself
            if stands[2 * i] == args.reference:
                gains[i] = [
                    twoByteSwap(gain_to_dpg(g)) for g in baseDipoleGain
                ]
    else:
        print("Setting all delays to zero")
        delays = [0 for i in antennas]
        delays = [twoByteSwap(delay_to_dpd(d)) for d in delays]

        print("Setting gains for dipoles %i and %i" %
              (args.dipole, args.reference))

        gains = [[twoByteSwap(gain_to_dpg(g)) for g in baseEmptyGain]
                 for i in xrange(int(len(antennas) / 2))
                 ]  # initialize gain list
        for i in xrange(len(stands) // 2):
            # Put the fringing stand in there all by itself
            if stands[2 * i] == args.dipole:
                gains[i] = [twoByteSwap(gain_to_dpg(g)) for g in baseBeamGain]

            # Put the reference stand in there all by itself
            if stands[2 * i] == args.reference:
                gains[i] = [
                    twoByteSwap(gain_to_dpg(g)) for g in baseDipoleGain
                ]

    # Resort the gains into a list of 2x2 matrices
    newGains = []
    for gain in gains:
        newGains.append([[gain[0], gain[1]], [gain[2], gain[3]]])
    gains = newGains

    # Create the SDF
    sessionComment = 'Input Pol.: %s; Output Pol.: beam -> X, reference -> Y' % (
        'X' if not args.y_pol else 'Y', )
    observer = sdf_module.Observer("fringeSDF.py Observer", 99)
    session = sdf_module.Session("fringeSDF.py Session",
                                 1,
                                 comments=sessionComment)
    project = sdf_module.Project(observer, "fringeSDF.py Project", "FRINGSDF",
                                 [
                                     session,
                                 ])
    obs = sdf_module.Stepped("fringeSDF.py Target",
                             "Custom",
                             tStart,
                             args.filter,
                             is_radec=False)
    stp = sdf_module.BeamStep(args.azimuth,
                              args.elevation,
                              str(args.obs_length),
                              args.frequency1,
                              args.frequency2,
                              is_radec=False,
                              spec_delays=delays,
                              spec_gains=gains)
    obs.append(stp)
    obs.gain = 1
    project.sessions[0].observations.append(obs)
    project.sessions[0].drx_beam = args.dp_beam
    ## Spectrometer setup
    if args.spec_setup is not None:
        # Remove the ' marks
        args.spec_setup = args.spec_setup.replace("'", "")
        # Excise the metatags
        mtch = metaRE.search(args.spec_setup)
        if mtch is not None:
            metatag = mtch.group(0)
            args.spec_setup = metaRE.sub('', args.spec_setup)
        else:
            metatag = None

        project.sessions[0].spcSetup = [
            int(i) for i in args.spec_setup.lstrip().rstrip().split(None, 1)
        ]
        project.sessions[0].spcMetatag = metatag

    # Write it out
    if os.path.exists(args.output):
        raise RuntimeError("File '%s' already exists" % args.output)
    project.render(verbose=True)
    fh = open(args.output, 'w')
    fh.write(project.render())
    fh.close()