Beispiel #1
0
def save_output(maindirmeta, outdict, e):
    """
        This function saves the output of the relative TEC measurement processing.

        Args:
            maindir (:obj:`str`): Path for data.
            outdict (dict[str, obj]): Output data dictionary::

                {
                           "rTEC": Relative TEC in TECU,
                           "rTEC_sig":Relative TEC STD in TECU,
                           "S4": The S4 parameter,
                           "snr0":snr0,
                           "snr1":snr1,
                           "time": Time for each measurement in posix format,
                }
        """

    if not os.path.exists(maindirmeta):
        os.mkdir(maindirmeta)

    mdo = drf.DigitalMetadataWriter(
        metadata_dir=maindirmeta,
        subdir_cadence_secs=3600,
        file_cadence_secs=1,
        sample_rate_numerator=1,
        sample_rate_denominator=1,
        file_name='Outputparams',
    )
    # get rid of doppler residual
    if 'doppler_residual' in outdict['resid']:
        del outdict['resid']['doppler_residual']
    mdo.write(e['tsave'], outdict)
metadata_dir = os.path.join(tempfile.gettempdir(), "example_metadata")
subdirectory_cadence_seconds = 3600
file_cadence_seconds = 60
samples_per_second_numerator = 10
samples_per_second_denominator = 9
file_name = "rideout"
stime = 1447082580

shutil.rmtree(metadata_dir, ignore_errors=True)
os.makedirs(metadata_dir)

dmw = digital_rf.DigitalMetadataWriter(
    metadata_dir,
    subdirectory_cadence_seconds,
    file_cadence_seconds,
    samples_per_second_numerator,
    samples_per_second_denominator,
    file_name,
)
print("first create okay")

data_dict = {}
start_idx = int(np.uint64(stime * dmw.get_samples_per_second()))
# To save an array of data, make sure the first axis has the same length
# as the samples index
idx_arr = np.arange(70, dtype=np.int64) + start_idx

int_data = np.arange(70, dtype=np.int32)
data_dict["int_data"] = int_data
# can even do multi-dimensional arrays!
int_mat = np.arange(70 * 3 * 2, dtype=np.int32).reshape(70, 3, 2)
Beispiel #3
0
 metadataFiles = glob.glob(
     os.path.join(
         args.source,
         channel,
         'metadata*.h5',
     ))
 metadataFiles.sort()
 if metadataFiles:
     # create metadata dir, dmd object, and write channel metadata
     mddir = os.path.join(subdir, 'metadata')
     if not os.path.exists(mddir):
         os.makedirs(mddir)
     mdo = digital_rf.DigitalMetadataWriter(
         metadata_dir=mddir,
         subdir_cadence_secs=args.dir_secs,
         file_cadence_secs=1,
         sample_rate_numerator=sample_rate_numerator,
         sample_rate_denominator=sample_rate_denominator,
         file_name='metadata',
     )
     for filepath in metadataFiles:
         try:
             with h5py.File(filepath, 'r') as mdfile:
                 md = dict(
                     uuid_str=uuid_str,
                     sample_rate_numerator=sample_rate_numerator,
                     sample_rate_denominator=sample_rate_denominator,
                     # put in a list because we want the data to be a
                     # 1-D array and it would be a single value o/w
                     center_frequencies=[
                         mdfile['center_frequencies'][()].reshape(
                             (-1, ))
Beispiel #4
0
    def run(self, starttime=None, endtime=None, duration=None, period=10):
        op = self.op

        # print current time and NTP status
        if op.verbose:
            call(('timedatectl', 'status'))

        # parse time arguments
        if starttime is None:
            st = None
        else:
            dtst = dateutil.parser.parse(starttime)
            epoch = datetime.datetime(1970, 1, 1, tzinfo=pytz.utc)
            st = int((dtst - epoch).total_seconds())

            # find next suitable start time by cycle repeat period
            soon = int(math.ceil(time.time())) + 5
            periods_until_next = (max(soon - st, 0) - 1) // period + 1
            st = st + periods_until_next * period

            if op.verbose:
                dtst = datetime.datetime.utcfromtimestamp(st)
                dtststr = dtst.strftime('%a %b %d %H:%M:%S %Y')
                print('Start time: {0} ({1})'.format(dtststr, st))

        if endtime is None:
            et = None
        else:
            dtet = dateutil.parser.parse(endtime)
            epoch = datetime.datetime(1970, 1, 1, tzinfo=pytz.utc)
            et = int((dtet - epoch).total_seconds())

            if op.verbose:
                dtetstr = dtet.strftime('%a %b %d %H:%M:%S %Y')
                print('End time: {0} ({1})'.format(dtetstr, et))

        if et is not None:
            if (et < time.time() + 5) or (st is not None and et <= st):
                raise ValueError('End time is before launch time!')

        if op.realtime:
            r = gr.enable_realtime_scheduling()

            if op.verbose:
                if r == gr.RT_OK:
                    print('Realtime scheduling enabled')
                else:
                    print('Note: failed to enable realtime scheduling')

        # create data directory so ringbuffer code can be started while waiting
        # to launch
        if not os.path.isdir(op.datadir):
            os.makedirs(op.datadir)

        # wait for the start time if it is not past
        while (st is not None) and (st - time.time()) > 10:
            ttl = int(math.floor(st - time.time()))
            if (ttl % 10) == 0:
                print('Standby {0} s remaining...'.format(ttl))
                sys.stdout.flush()
            time.sleep(1)

        # get UHD USRP source
        u = self._usrp_setup()

        # force creation of the RX streamer ahead of time with a finite
        # acquisition (after setting time/clock sources, before setting the
        # device time)
        # this fixes timing with the B210
        u.finite_acquisition_v(16384)

        # wait until time 0.2 to 0.5 past full second, then latch
        # we have to trust NTP to be 0.2 s accurate
        tt = time.time()
        while tt - math.floor(tt) < 0.2 or tt - math.floor(tt) > 0.3:
            time.sleep(0.01)
            tt = time.time()
        if op.verbose:
            print('Latching at ' + str(tt))
        if op.sync:
            # waits for the next pps to happen
            # (at time math.ceil(tt))
            # then sets the time for the subsequent pps
            # (at time math.ceil(tt) + 1.0)
            u.set_time_unknown_pps(uhd.time_spec(math.ceil(tt) + 1.0))
        else:
            u.set_time_now(uhd.time_spec(tt))
        # reset device stream and flush buffer to clear leftovers from finite
        # acquisition
        u.stop()

        # get output settings that depend on decimation rate
        samplerate_out = op.samplerate / op.dec
        samplerate_num_out = op.samplerate_num
        samplerate_den_out = op.samplerate_den * op.dec
        if op.dec > 1:
            sample_size = gr.sizeof_gr_complex
            sample_dtype = '<f4'

            taps = firdes.low_pass_2(1.0,
                                     float(op.samplerate),
                                     float(samplerate_out / 2.0),
                                     float(0.2 * samplerate_out),
                                     80.0,
                                     window=firdes.WIN_BLACKMAN_hARRIS)
        else:
            sample_size = 2 * gr.sizeof_short
            sample_dtype = '<i2'

        # set launch time
        # (at least 1 second out so USRP time is set, time to set up flowgraph)
        if st is not None:
            lt = st
        else:
            lt = int(math.ceil(time.time() + 1.0))
        # adjust launch time forward so it falls on an exact sample since epoch
        lt_samples = np.ceil(lt * samplerate_out)
        lt = lt_samples / samplerate_out
        if op.verbose:
            dtlt = datetime.datetime.utcfromtimestamp(lt)
            dtltstr = dtlt.strftime('%a %b %d %H:%M:%S.%f %Y')
            print('Launch time: {0} ({1})'.format(dtltstr, repr(lt)))
        # command time
        ct_samples = lt_samples
        # splitting ct into secs/frac lets us set a more accurate time_spec
        ct_secs = ct_samples // samplerate_out
        ct_frac = (ct_samples % samplerate_out) / samplerate_out
        u.set_start_time(
            uhd.time_spec(float(ct_secs)) + uhd.time_spec(float(ct_frac)))

        # populate flowgraph one channel at a time
        fg = gr.top_block()
        for k in range(op.nchs):
            # create digital RF sink
            chdir = os.path.join(op.datadir, op.chs[k])
            dst = gr_drf.digital_rf_sink(
                dir=chdir,
                sample_size=sample_size,
                subdir_cadence_s=op.subdir_cadence_s,
                file_cadence_ms=op.file_cadence_ms,
                sample_rate_numerator=samplerate_num_out,
                sample_rate_denominator=samplerate_den_out,
                uuid=op.uuid,
                is_complex=True,
                num_subchannels=1,
                stop_on_dropped_packet=op.stop_on_dropped,
                start_sample_index=int(lt * samplerate_out),
                ignore_tags=False,
            )

            if op.dec > 1:
                # create low-pass filter
                lpf = filter.freq_xlating_fir_filter_ccf(
                    op.dec, taps, 0.0, float(op.samplerate))

                # connections for usrp->lpf->drf
                connections = ((u, k), (lpf, 0), (dst, 0))
            else:
                # connections for usrp->drf
                connections = ((u, k), (dst, 0))

            # make channel connections in flowgraph
            fg.connect(*connections)

        # start to receive data
        fg.start()

        # write metadata one channel at a time
        for k in range(op.nchs):
            mbnum = op.mboardnum_bychan[k]
            # create metadata dir, dmd object, and write channel metadata
            mddir = os.path.join(op.datadir, op.chs[k], 'metadata')
            if not os.path.exists(mddir):
                os.makedirs(mddir)
            mdo = drf.DigitalMetadataWriter(
                metadata_dir=mddir,
                subdir_cadence_secs=op.subdir_cadence_s,
                file_cadence_secs=1,
                sample_rate_numerator=samplerate_num_out,
                sample_rate_denominator=samplerate_den_out,
                file_name='metadata',
            )
            md = op.metadata.copy()
            md.update(
                # standard metadata by convention
                uuid_str=op.uuid,
                sample_rate_numerator=samplerate_num_out,
                sample_rate_denominator=samplerate_den_out,
                # put in a list because we want the data to be a 1-D array
                # and it would be a single value if we didn't
                center_frequencies=[np.array([op.centerfreqs[k]])],

                # additional receiver metadata for USRP
                receiver=dict(
                    description='UHD USRP source using GNU Radio',
                    info=dict(u.get_usrp_info(chan=k)),
                    antenna=op.antennas[k],
                    bandwidth=op.bandwidths[k],
                    center_freq=op.centerfreqs[k],
                    clock_rate=u.get_clock_rate(mboard=mbnum),
                    clock_source=u.get_clock_source(mboard=mbnum),
                    gain=op.gains[k],
                    id=op.mboards_bychan[k],
                    lo_offset=op.lo_offsets[k],
                    otw_format=op.otw_format,
                    samp_rate=u.get_samp_rate(),
                    stream_args=','.join(op.stream_args),
                    subdev=op.subdevs_bychan[k],
                    time_source=u.get_time_source(mboard=mbnum),
                ),
            )
            mdo.write(
                samples=int(lt * samplerate_out),
                data_dict=md,
            )

        # wait until end time or until flowgraph stops
        if et is None and duration is not None:
            et = lt + duration
        try:
            if et is None:
                fg.wait()
            else:
                # sleep until end time nears
                while (time.time() < et - 1):
                    time.sleep(1)
                else:
                    # issue stream stop command at end time
                    ct_secs = et // 1
                    ct_frac = et % 1
                    u.set_command_time(
                        (uhd.time_spec(float(ct_secs)) +
                         uhd.time_spec(float(ct_frac))),
                        uhd.ALL_MBOARDS,
                    )
                    stop_enum = uhd.stream_cmd.STREAM_MODE_STOP_CONTINUOUS
                    u.issue_stream_cmd(uhd.stream_cmd(stop_enum))
                    u.clear_command_time(uhd.ALL_MBOARDS)
                    # sleep until after end time
                    time.sleep(1)
        except KeyboardInterrupt:
            # catch keyboard interrupt and simply exit
            pass
        fg.stop()
        print('done')
        sys.stdout.flush()