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)
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, ))
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()