-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Generalize and Improve Annotation Handling #32
Conversation
Saving as draft for now- let's save this for after the incoming SigMF-NS-NTIA updates happen, and make all the corresponding SigMF-related updates in one PR. |
Leaving out |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. I think we need to revisit the metadata handling, but I'll create issues to do it at a later date.
@@ -99,11 +97,19 @@ def execute(self, schedule_entry, task_id) -> dict: | |||
measurement_result["description"] = self.description | |||
measurement_result["sigan_cal"] = self.sigan.sigan_calibration_data | |||
measurement_result["sensor_cal"] = self.sigan.sensor_calibration_data | |||
measurement_result["classification"] = "UNCLASSIFIED" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would this be better to pull from YAML?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, definitely better than hard-coding this in.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Commenting here to keep this traceable: #41 is this issue
@@ -115,6 +115,7 @@ def __call__(self, schedule_entry_json, task_id): | |||
measurement_result["name"] = self.name | |||
measurement_result["sigan_cal"] = self.sigan.sigan_calibration_data | |||
measurement_result["sensor_cal"] = self.sigan.sensor_calibration_data | |||
measurement_result["classification"] = "UNCLASSIFIED" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would this be better to pull from YAML?
@@ -191,6 +188,7 @@ def execute(self, schedule_entry, task_id) -> dict: | |||
measurement_result["measurement_type"] = MeasurementType.SINGLE_FREQUENCY.value | |||
measurement_result["sigan_cal"] = self.sigan.sigan_calibration_data | |||
measurement_result["sensor_cal"] = self.sigan.sensor_calibration_data | |||
measurement_result["classification"] = "UNCLASSIFIED" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be better to pull from YAML, but we can add an issue to do that.
@@ -243,8 +241,19 @@ def description(self): | |||
def get_sigmf_builder(self, measurement_result) -> SigMFBuilder: | |||
sigmf_builder = super().get_sigmf_builder(measurement_result) | |||
for i, detector in enumerate(self.fft_detector): | |||
fft_annotation = FrequencyDomainDetectionAnnotation( | |||
detector.value, i * self.fft_size, self.fft_size | |||
fft_annotation = FrequencyDomainDetection( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a lot of arguments. I agree that it helps to make it explicit what it requires but I think we need to revisit this later. Maybe later we move to a builder or fluent interface.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed that we should improve this later. Hopefully along with more metadata handling improvements overall (maybe tied to addressing #29?)
@@ -99,11 +97,19 @@ def execute(self, schedule_entry, task_id) -> dict: | |||
measurement_result["description"] = self.description | |||
measurement_result["sigan_cal"] = self.sigan.sigan_calibration_data | |||
measurement_result["sensor_cal"] = self.sigan.sensor_calibration_data | |||
measurement_result["classification"] = "UNCLASSIFIED" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above, but we don't need to fix now.
@@ -39,15 +36,50 @@ def __call__(self, schedule_entry, task_id): | |||
def get_sigmf_builder(self, measurement_result) -> SigMFBuilder: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is still relying on measuremen_result containing everything. Don't need to fix now, but we should create an issue and revisit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Figuring out how/when to rely on measurement_result
should be a main priority of #40
assert ( | ||
self.freq_lower_edge is not None and self.freq_upper_edge is not None | ||
), err_msg | ||
# Define SigMF key names |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably move to using a json schema in the future, but not needed for now.
Overview
This update enhances the implementation of SigMF annotation segments and measurement metadata. Hard-coded metadata values are removed to ensure that actions provide accurate metadata as required by the SigMF specifications. In general, metadata is no longer pulled by the annotation classes directly from a
measurement_result
dictionary, which makes annotation use more explicit. Additionally, actions no longer need to store metadata in themeasurement_result
.These changes extend the functionality of the annotation classes, allowing better support for future actions. For example, the annotation class
TimeDomainDetection
can now support time domain captures other than raw IQ captures.All existing actions are updated to make use of the refactored metadata classes.
Changelog
scos_actions/metadata/annotations/__init__.py
so that all annotations are importable fromscos_actions.metadata.annotations
measurement_result
dictionaries, instead requiring each metadata value to be specified as a parameter for the annotation instanceAnnotationSegment
base dataclass, which annotations can be built from. This base class implements the required and optional keys associated with any possible SigMF annotation segment. This replaces the oldMetadata
base class.MeasurementMetadata
class to a dataclass, and implement previously missing keys which are part of the SigMF specification. Also adds checks that required values are specified.AnnotationSegment
CalibrationAnnotation
:gain_sensor
key, which is actually not a part of thentia-sensor
specificationFrequencyDomainDetection
annotation:../fft_annotation.py
to../frequency_domain_detection.py
"fft_"
to thedetector
parameter, to make it easy to use with the new generalized detector implementationTimeDomainDetection
:../time_domain_annotation.py
to../time_domain_detection.py
acquire_single_freq_fft
,acquire_single_freq_tdomain_iq
, andacquire_stepped_freq_tdomain_iq
) andsigm_builder
for the above changes. Note that the changes now require aclassification
key in the measurement metadata (required by the SigMF specification), and all three actions are hard-coded to record their results as"UNCLASSIFIED"