def acquire_data(self, fc, parent_entry, task_id): tuning_parameters = self.tuning_parameters[fc] self.configure_usrp(fc, **tuning_parameters) # Use the radio's actual reported sample rate instead of requested rate sample_rate = self.usrp.radio.sample_rate # Build global metadata sigmf_md = SigMFFile() sigmf_md.set_global_info(GLOBAL_INFO) sigmf_md.set_global_field("core:sample_rate", sample_rate) sigmf_md.set_global_field("core:description", self.description) sensor_def = capabilities['sensor_definition'] sigmf_md.set_global_field("ntia:sensor_definition", sensor_def) sigmf_md.set_global_field("ntia:sensor_id", settings.FQDN) sigmf_md.set_global_field("scos:version", SCOS_TRANSFER_SPEC_VER) # Acquire data and build per-capture metadata data = np.array([], dtype=np.complex64) nsamps = int(sample_rate * tuning_parameters['duration_ms'] * 1e-3) dt = utils.get_datetime_str_now() acq = self.usrp.radio.acquire_samples(nsamps).astype(np.complex64) data = np.append(data, acq) capture_md = {"core:frequency": fc, "core:datetime": dt} sigmf_md.add_capture(start_index=0, metadata=capture_md) annotation_md = {"applied_scale_factor": self.usrp.radio.scale_factor} sigmf_md.add_annotation(start_index=0, length=nsamps, metadata=annotation_md) return data, sigmf_md
def build_sigmf_md(self): logger.debug("Building SigMF metadata file") sigmf_md = SigMFFile() sigmf_md.set_global_info(GLOBAL_INFO) sigmf_md.set_global_field("core:sample_rate", self.sample_rate) sigmf_md.set_global_field("core:description", self.description) try: sensor_def_obj = SensorDefinition.objects.get() sensor_def = SensorDefinitionSerializer(sensor_def_obj).data sigmf_md.set_global_field("scos:sensor_definition", sensor_def) except SensorDefinition.DoesNotExist: pass try: fqdn = settings.ALLOWED_HOSTS[1] except IndexError: fqdn = 'not.set' sigmf_md.set_global_field("scos:sensor_id", fqdn) sigmf_md.set_global_field("scos:version", SCOS_TRANSFER_SPEC_VER) capture_md = { "core:frequency": self.frequency, "core:time": utils.get_datetime_str_now() } sigmf_md.add_capture(start_index=0, metadata=capture_md) for i, detector in enumerate(M4sDetector): single_frequency_fft_md = { "number_of_samples_in_fft": self.fft_size, "window": "blackman", "equivalent_noise_bandwidth": self.enbw, "detector": detector.name + "_power", "number_of_ffts": self.nffts, "units": "dBm", "reference": "not referenced" } annotation_md = { "scos:measurement_type": { "single_frequency_fft_detection": single_frequency_fft_md, } } sigmf_md.add_annotation(start_index=(i * self.fft_size), length=self.fft_size, metadata=annotation_md) return sigmf_md
def build_sigmf_md(self): logger.debug("Building SigMF metadata file") sigmf_md = SigMFFile() sigmf_md.set_global_info(GLOBAL_INFO) sigmf_md.set_global_field("core:sample_rate", self.sample_rate) sigmf_md.set_global_field("core:description", self.description) sensor_def = capabilities['sensor_definition'] sigmf_md.set_global_field("ntia:sensor_definition", sensor_def) sigmf_md.set_global_field("ntia:sensor_id", settings.FQDN) sigmf_md.set_global_field("scos:version", SCOS_TRANSFER_SPEC_VER) capture_md = { "core:frequency": self.frequency, "core:time": utils.get_datetime_str_now() } sigmf_md.add_capture(start_index=0, metadata=capture_md) for i, detector in enumerate(M4sDetector): single_frequency_fft_md = { "number_of_samples_in_fft": self.fft_size, "window": "blackman", "equivalent_noise_bandwidth": self.enbw, "detector": detector.name + "_power", "number_of_ffts": self.nffts, "units": "dBm", "reference": "not referenced" } annotation_md = { "scos:measurement_type": { "single_frequency_fft_detection": single_frequency_fft_md, } } sigmf_md.add_annotation(start_index=(i * self.fft_size), length=self.fft_size, metadata=annotation_md) return sigmf_md
def acquire_data(self, parent_entry, task_id): # Build global metadata sigmf_md = SigMFFile() sigmf_md.set_global_info(GLOBAL_INFO) sigmf_md.set_global_field("core:sample_rate", self.sample_rate) sigmf_md.set_global_field("core:description", self.description) try: sensor_def_obj = SensorDefinition.objects.get() sensor_def = SensorDefinitionSerializer(sensor_def_obj).data sigmf_md.set_global_field("scos:sensor_definition", sensor_def) except SensorDefinition.DoesNotExist: pass try: fqdn = settings.ALLOWED_HOSTS[1] except IndexError: fqdn = 'not.set' sigmf_md.set_global_field("scos:sensor_id", fqdn) sigmf_md.set_global_field("scos:version", SCOS_TRANSFER_SPEC_VER) # Acquire data and build per-capture metadata data = np.array([], dtype=np.complex64) nsamps = self.nsamples for idx, fc in enumerate(self.fcs): self.usrp.radio.tune_frequency(fc) dt = utils.get_datetime_str_now() acq = self.usrp.radio.acquire_samples(nsamps).astype(np.complex64) data = np.append(data, acq) start_idx = idx * nsamps capture_md = {"core:frequency": fc, "core:datetime": dt} sigmf_md.add_capture(start_index=start_idx, metadata=capture_md) annotation_md = { "applied_scale_factor": self.usrp.radio.scale_factor } sigmf_md.add_annotation(start_index=start_idx, length=nsamps, metadata=annotation_md) return data, sigmf_md
def build_sigmf_md(self, task_id, measurement_params, data): # Build global metadata sigmf_md = SigMFFile() sigmf_md.set_global_info(GLOBAL_INFO) sample_rate = self.sdr.radio.sample_rate sigmf_md.set_global_field("core:sample_rate", sample_rate) sensor_def = capabilities["sensor_definition"] sensor_def["id"] = settings.FQDN sigmf_md.set_global_field("ntia-sensor:sensor", sensor_def) action_def = { "name": self.name, "description": self.description, "type": ["TimeDomain"], } sigmf_md.set_global_field("ntia-scos:action", action_def) sigmf_md.set_global_field("ntia-scos:task_id", task_id) dt = utils.get_datetime_str_now() num_samples = measurement_params.get_num_samples() capture_md = { "core:frequency": self.sdr.radio.frequency, "core:datetime": dt } sigmf_md.add_capture(start_index=0, metadata=capture_md) calibration_annotation_md = self.sdr.radio.create_calibration_annotation( ) sigmf_md.add_annotation(start_index=0, length=num_samples, metadata=calibration_annotation_md) time_domain_detection_md = { "ntia-core:annotation_type": "TimeDomainDetection", "ntia-algorithm:detector": "sample_iq", "ntia-algorithm:detection_domain": "time", "ntia-algorithm:number_of_samples": num_samples, "ntia-algorithm:units": "volts", "ntia-algorithm:reference": "not referenced", } sigmf_md.add_annotation(start_index=0, length=num_samples, metadata=time_domain_detection_md) # Recover the sigan overload flag sigan_overload = self.sdr.radio.sigan_overload # Check time domain average power versus calibrated compression time_domain_avg_power = 10 * np.log10(np.mean(np.abs(data)**2)) time_domain_avg_power += (10 * np.log10(1 / (2 * 50)) + 30 ) # Convert log(V^2) to dBm sensor_overload = ( time_domain_avg_power > self.sdr.radio.sensor_calibration_data["1db_compression_sensor"]) # Create SensorAnnotation and add gain setting and overload indicators sensor_annotation_md = { "ntia-core:annotation_type": "SensorAnnotation", "ntia-sensor:overload_sensor": sensor_overload, "ntia-sensor:overload_sigan": sigan_overload, "ntia-sensor:gain_setting_sigan": measurement_params.gain, } location = get_location() if location: sensor_annotation_md["core:latitude"] = (location.latitude, ) sensor_annotation_md["core:longitude"] = location.longitude sigmf_md.add_annotation(start_index=0, length=num_samples, metadata=sensor_annotation_md) return sigmf_md
def build_sigmf_md( self, task_id, measurement_params, data, schedule_entry, recording_id, start_time, end_time, ): frequency = self.sdr.radio.frequency sample_rate = self.sdr.radio.sample_rate # Build global metadata sigmf_md = SigMFFile() sigmf_md.set_global_info( GLOBAL_INFO.copy() ) # prevent GLOBAL_INFO from being modified by sigmf sigmf_md.set_global_field( "core:datatype", "cf32_le" ) # 2x 32-bit float, Little Endian sigmf_md.set_global_field("core:sample_rate", sample_rate) measurement_object = { "time_start": start_time, "time_stop": end_time, "domain": "Time", "measurement_type": "survey" if self.is_multirecording else "single-frequency", "frequency_tuned_low": frequency, "frequency_tuned_high": frequency, } sigmf_md.set_global_field("ntia-core:measurement", measurement_object) sensor = capabilities["sensor"] sensor["id"] = settings.FQDN get_sensor_location_sigmf(sensor) sigmf_md.set_global_field("ntia-sensor:sensor", sensor) from status.views import get_last_calibration_time sigmf_md.set_global_field( "ntia-sensor:calibration_datetime", get_last_calibration_time() ) action_def = { "name": self.name, "description": self.description, "summary": self.description.splitlines()[0], } sigmf_md.set_global_field("ntia-scos:action", action_def) if self.is_multirecording: sigmf_md.set_global_field("ntia-scos:recording", recording_id) sigmf_md.set_global_field("ntia-scos:task", task_id) from schedule.serializers import ScheduleEntrySerializer serializer = ScheduleEntrySerializer( schedule_entry, context={"request": schedule_entry.request} ) schedule_entry_json = serializer.to_sigmf_json() schedule_entry_json["id"] = schedule_entry.name sigmf_md.set_global_field("ntia-scos:schedule", schedule_entry_json) sigmf_md.set_global_field( "ntia-location:coordinate_system", get_coordinate_system_sigmf() ) num_samples = measurement_params.get_num_samples() capture_md = { "core:frequency": frequency, "core:datetime": self.sdr.radio.capture_time, } sigmf_md.add_capture(start_index=0, metadata=capture_md) calibration_annotation_md = self.sdr.radio.create_calibration_annotation() sigmf_md.add_annotation( start_index=0, length=num_samples, metadata=calibration_annotation_md ) time_domain_detection_md = { "ntia-core:annotation_type": "TimeDomainDetection", "ntia-algorithm:detector": "sample_iq", "ntia-algorithm:number_of_samples": num_samples, "ntia-algorithm:units": "volts", "ntia-algorithm:reference": "preselector input", } sigmf_md.add_annotation( start_index=0, length=num_samples, metadata=time_domain_detection_md ) # Recover the sigan overload flag sigan_overload = self.sdr.radio.sigan_overload # Check time domain average power versus calibrated compression time_domain_avg_power = 10 * np.log10(np.mean(np.abs(data) ** 2)) time_domain_avg_power += ( 10 * np.log10(1 / (2 * 50)) + 30 ) # Convert log(V^2) to dBm sensor_overload = False # explicitly check is not None since 1db compression could be 0 if self.sdr.radio.sensor_calibration_data["1db_compression_sensor"] is not None: sensor_overload = ( time_domain_avg_power > self.sdr.radio.sensor_calibration_data["1db_compression_sensor"] ) # Create SensorAnnotation and add gain setting and overload indicators sensor_annotation_md = { "ntia-core:annotation_type": "SensorAnnotation", "ntia-sensor:overload": sensor_overload or sigan_overload, "ntia-sensor:gain_setting_sigan": measurement_params.gain, } sigmf_md.add_annotation( start_index=0, length=num_samples, metadata=sensor_annotation_md ) return sigmf_md
def build_sigmf_md(self, task_id, data, schedule_entry, start_time, end_time): logger.debug("Building SigMF metadata file") # Use the radio's actual reported sample rate instead of requested rate sample_rate = self.sdr.radio.sample_rate frequency = self.sdr.radio.frequency sigmf_md = SigMFFile() sigmf_md.set_global_info(GLOBAL_INFO.copy( )) # prevent GLOBAL_INFO from being modified by sigmf sigmf_md.set_global_field("core:datatype", "rf32_le") # 32-bit float, Little Endian sigmf_md.set_global_field("core:sample_rate", sample_rate) measurement_object = { "time_start": start_time, "time_stop": end_time, "domain": "Frequency", "measurement_type": "single-frequency", "frequency_tuned_low": frequency, "frequency_tuned_high": frequency, } sigmf_md.set_global_field("ntia-core:measurement", measurement_object) sensor = capabilities["sensor"] sensor["id"] = settings.FQDN get_sensor_location_sigmf(sensor) sigmf_md.set_global_field("ntia-sensor:sensor", sensor) from status.views import get_last_calibration_time sigmf_md.set_global_field("ntia-sensor:calibration_datetime", get_last_calibration_time()) sigmf_md.set_global_field("ntia-scos:task", task_id) action_def = { "name": self.name, "description": self.description, "summary": self.description.splitlines()[0], } sigmf_md.set_global_field("ntia-scos:action", action_def) from schedule.serializers import ScheduleEntrySerializer serializer = ScheduleEntrySerializer( schedule_entry, context={"request": schedule_entry.request}) schedule_entry_json = serializer.to_sigmf_json() schedule_entry_json["id"] = schedule_entry.name sigmf_md.set_global_field("ntia-scos:schedule", schedule_entry_json) sigmf_md.set_global_field("ntia-location:coordinate_system", get_coordinate_system_sigmf()) capture_md = { "core:frequency": frequency, "core:datetime": self.sdr.radio.capture_time, } sigmf_md.add_capture(start_index=0, metadata=capture_md) frequencies = get_fft_frequencies(self.measurement_params.fft_size, sample_rate, frequency).tolist() for i, detector in enumerate(M4sDetector): frequency_domain_detection_md = { "ntia-core:annotation_type": "FrequencyDomainDetection", "ntia-algorithm:number_of_samples_in_fft": self.measurement_params.fft_size, "ntia-algorithm:window": "flattop", "ntia-algorithm:equivalent_noise_bandwidth": self.enbw, "ntia-algorithm:detector": "fft_" + detector.name + "_power", "ntia-algorithm:number_of_ffts": self.measurement_params.num_ffts, "ntia-algorithm:units": "dBm", "ntia-algorithm:reference": "preselector input", "ntia-algorithm:frequency_start": frequencies[0], "ntia-algorithm:frequency_stop": frequencies[-1], "ntia-algorithm:frequency_step": frequencies[1] - frequencies[0], } sigmf_md.add_annotation( start_index=(i * self.measurement_params.fft_size), length=self.measurement_params.fft_size, metadata=frequency_domain_detection_md, ) calibration_annotation_md = self.sdr.radio.create_calibration_annotation( ) sigmf_md.add_annotation( start_index=0, length=self.measurement_params.fft_size * len(M4sDetector), metadata=calibration_annotation_md, ) # Recover the sigan overload flag sigan_overload = self.sdr.radio.sigan_overload # Check time domain average power versus calibrated compression flattened_data = data.flatten() time_domain_avg_power = 10 * np.log10( np.mean(np.abs(flattened_data)**2)) time_domain_avg_power += (10 * np.log10(1 / (2 * 50)) + 30 ) # Convert log(V^2) to dBm sensor_overload = False # explicitly check is not None since 1db compression could be 0 if self.sdr.radio.sensor_calibration_data[ "1db_compression_sensor"] is not None: sensor_overload = ( time_domain_avg_power > self.sdr.radio. sensor_calibration_data["1db_compression_sensor"]) # Create SensorAnnotation and add gain setting and overload indicators sensor_annotation_md = { "ntia-core:annotation_type": "SensorAnnotation", "ntia-sensor:overload": sensor_overload or sigan_overload, "ntia-sensor:gain_setting_sigan": self.measurement_params.gain, } sigmf_md.add_annotation( start_index=0, length=self.measurement_params.fft_size * len(M4sDetector), metadata=sensor_annotation_md, ) return sigmf_md
def build_sigmf_md(self, task_id, data): logger.debug("Building SigMF metadata file") # Use the radio's actual reported sample rate instead of requested rate sample_rate = self.sdr.radio.sample_rate sigmf_md = SigMFFile() sigmf_md.set_global_info(GLOBAL_INFO) sigmf_md.set_global_field("core:sample_rate", sample_rate) sensor_def = capabilities["sensor_definition"] sensor_def["id"] = settings.FQDN sigmf_md.set_global_field("ntia-sensor:sensor", sensor_def) action_def = { "name": self.name, "description": self.description, "type": ["FrequencyDomain"], } sigmf_md.set_global_field("ntia-scos:action", action_def) sigmf_md.set_global_field("ntia-scos:task_id", task_id) capture_md = { "core:frequency": self.sdr.radio.frequency, "core:datetime": utils.get_datetime_str_now(), } sigmf_md.add_capture(start_index=0, metadata=capture_md) for i, detector in enumerate(M4sDetector): frequency_domain_detection_md = { "ntia-core:annotation_type": "FrequencyDomainDetection", "ntia-algorithm:number_of_samples_in_fft": self.measurement_params.fft_size, "ntia-algorithm:window": "flattop", "ntia-algorithm:equivalent_noise_bandwidth": self.enbw, "ntia-algorithm:detector": detector.name + "_power", "ntia-algorithm:number_of_ffts": self.measurement_params.num_ffts, "ntia-algorithm:units": "dBm", "ntia-algorithm:reference": "not referenced", "nita-algorithm:detection_domain": "frequency", } sigmf_md.add_annotation( start_index=(i * self.measurement_params.fft_size), length=self.measurement_params.fft_size, metadata=frequency_domain_detection_md, ) calibration_annotation_md = self.sdr.radio.create_calibration_annotation( ) sigmf_md.add_annotation( start_index=0, length=self.measurement_params.fft_size * len(M4sDetector), metadata=calibration_annotation_md, ) # Recover the sigan overload flag sigan_overload = self.sdr.radio.sigan_overload # Check time domain average power versus calibrated compression flattened_data = data.flatten() time_domain_avg_power = 10 * np.log10( np.mean(np.abs(flattened_data)**2)) time_domain_avg_power += (10 * np.log10(1 / (2 * 50)) + 30 ) # Convert log(V^2) to dBm sensor_overload = ( time_domain_avg_power > self.sdr.radio.sensor_calibration_data["1db_compression_sensor"]) # Create SensorAnnotation and add gain setting and overload indicators sensor_annotation_md = { "ntia-core:annotation_type": "SensorAnnotation", "ntia-sensor:overload_sensor": sensor_overload, "ntia-sensor:overload_sigan": sigan_overload, "ntia-sensor:gain_setting_sigan": self.measurement_params.gain, } location = get_location() if location: sensor_annotation_md["core:latitude"] = (location.latitude, ) sensor_annotation_md["core:longitude"] = location.longitude sigmf_md.add_annotation( start_index=0, length=self.measurement_params.fft_size * len(M4sDetector), metadata=sensor_annotation_md, ) return sigmf_md