Exemple #1
0
    def test_rate_tags_to_global(self):
        '''Test to ensure that rate tags go to the global segment
        and not to the capture segment'''
        src = analog.sig_source_c(0, analog.GR_CONST_WAVE, 0, 0, (1 + 1j))
        data_file, json_file = self.temp_file_names()

        file_sink = sigmf.sink("cf32_le", data_file)

        # Set a value that will get overridden by the tags
        file_sink.set_global_meta("core:sample_rate", 20)

        injector = simple_tag_injector()
        tb = gr.top_block()
        tb.connect(src, injector)
        tb.connect(injector, file_sink)
        tb.start()

        samp_rate = 1000.5
        injector.inject_tag = {"rx_rate": samp_rate}
        sleep(.2)
        tb.stop()
        tb.wait()
        meta = json.load(open(json_file, "r"))
        # Samp rate should have been set by the tag
        assert meta["global"]["core:sample_rate"] == samp_rate
        # And should not be in the captures segment
        assert "core:sample_rate" not in meta["captures"][0]
Exemple #2
0
    def test_rx_time_conversion(self):
        '''Test that rx_time tags are correctly converted to iso8601 strings'''

        src = analog.sig_source_c(0, analog.GR_CONST_WAVE, 0, 0, (1 + 1j))
        data_file, json_file = self.temp_file_names()

        file_sink = sigmf.sink("cf32_le",
                               data_file)
        seconds = 1520551983
        frac_seconds = 0.09375
        frac_seconds_2 = 0.25
        correct_str_1 = datetime.utcfromtimestamp(
            seconds).strftime('%Y-%m-%dT%H:%M:%S')
        correct_str_1 += str(frac_seconds).lstrip('0') + "Z"
        correct_str_2 = datetime.utcfromtimestamp(
            seconds).strftime('%Y-%m-%dT%H:%M:%S')
        correct_str_2 += str(frac_seconds_2).lstrip('0') + "Z"
        injector = simple_tag_injector()
        # first sample should have a rx_time tag
        injector.inject_tag = {"rx_time": (seconds, frac_seconds)}
        tb = gr.top_block()
        tb.connect(src, injector)
        tb.connect(injector, file_sink)
        tb.start()
        sleep(.2)
        # Also test the case where a tag arives while writing
        injector.inject_tag = {"rx_time": (seconds, frac_seconds_2)}
        sleep(.1)
        tb.stop()
        tb.wait()

        with open(json_file, "r") as f:
            meta = json.load(f)
            assert meta["captures"][0]["core:datetime"] == correct_str_1
            assert meta["captures"][1]["core:datetime"] == correct_str_2
Exemple #3
0
    def test_tags_to_capture_segment(self):
        src = analog.sig_source_c(0, analog.GR_CONST_WAVE, 0, 0, (1 + 1j))
        data_file, json_file = self.temp_file_names()
        file_sink = sigmf.sink("cf32_le",
                               data_file)

        injector = simple_tag_injector()
        tb = gr.top_block()
        tb.connect(src, injector)
        tb.connect(injector, file_sink)
        tb.start()

        # Inject a bunch of tags that should make capture segments
        for i in range(100):
            sleep(.01)
            frac, int_part = math.modf(time.time())
            injector.inject_tag = {
                "rx_freq": i * 1000,
                "rx_rate": i * 500,
                "rx_time": (int(int_part), frac)
            }
        tb.stop()
        tb.wait()
        metadata = json.load(open(json_file, "r"))

        # There should be 100 capture segments
        self.assertEqual(len(metadata["captures"]), 100)

        # And the data in them should match the tags we created
        for i in range(99):
            self.assertEqual(
                metadata["captures"][i + 1]["core:frequency"],
                i * 1000)
Exemple #4
0
    def test_tags_to_annotation_segments(self):
        '''Test that tags correctly convert to annotation segments'''
        # FIXME: this test is occasionally flaky, as the flowgraph is shutdown
        # before all the messages get to the sink
        src = analog.sig_source_c(0, analog.GR_CONST_WAVE, 0, 0, (1 + 1j))
        data_file, json_file = self.temp_file_names()
        file_sink = sigmf.sink("cf32_le", data_file)

        injector = simple_tag_injector()
        tb = gr.top_block()
        tb.connect(src, injector)
        tb.connect(injector, file_sink)
        tb.start()

        # Inject a bunch of tags that should make annotation segments
        for i in range(100):
            sleep(.001)
            frac, int_part = math.modf(time.time())
            injector.inject_tag = {"test:a": i, "test:b": True, "test:c": 2.33}
        sleep(.5)

        tb.stop()
        tb.wait()
        metadata = json.load(open(json_file, "r"))

        # There should be 100 annotation segments
        self.assertEqual(len(metadata["annotations"]), 100)
        for i in range(100):
            self.assertEqual(metadata["annotations"][i]["test:a"], i)
            self.assertEqual(metadata["annotations"][i]["test:b"], True)
            self.assertEqual(metadata["annotations"][i]["test:c"], 2.33)
Exemple #5
0
    def test_relative_time_mode(self):
        # Example of Relative Mode Opertation
        # The following events happen:

        # Sample 0: rx_time: (2, 0.50000) at host time
        # of 2018-03-12T11:36:00.20000
        # 10,000 samples follow
        # Sample 10,000: rx_time: (4, 0.80000)
        # 20,000 samples follow
        # Note that the relative time difference between the two
        # capture segments is precisely 2.3 seconds.
        # This should create two capture segments:

        # Capture Segment 1 core:datetime: 2018-03-12T11:36:00.20000

        # Capture Segment 2 core:datetime: 2018-03-12T11:36:02.50000
        limit_event = Event()
        continue_event = Event()
        samp_rate = 10000.0
        limit_samples = samp_rate
        print(limit_samples)
        src = sample_producer(limit_samples, limit_event, continue_event)

        data_file, json_file = self.temp_file_names()
        file_sink = sigmf.sink("cf32_le", data_file,
                               sigmf.sigmf_time_mode_relative)
        file_sink.set_global_meta("core:sample_rate", samp_rate)

        injector = simple_tag_injector()
        # first sample should have a rx_time tag
        injector.inject_tag = {"rx_time": (2, 0.500000)}
        tb = gr.top_block()
        tb.connect(src, injector)
        tb.connect(injector, file_sink)
        tb.start()
        print("waiting")
        limit_event.wait()
        # sleep to let the last samples get to the sink block
        sleep(.1)
        # set the rx_time tag for the next section
        injector.inject_tag = {"rx_time": (4, 0.80000)}
        continue_event.set()
        sleep(.1)
        tb.stop()
        tb.wait()

        with open(json_file, "r") as f:
            meta = json.load(f)
            capture_one_dt = parse_iso_ts(meta["captures"][0]["core:datetime"])
            capture_two_dt = parse_iso_ts(meta["captures"][1]["core:datetime"])
            diff_time = capture_two_dt - capture_one_dt
            assert diff_time.seconds == 2
            assert diff_time.microseconds == 300000
Exemple #6
0
    def test_not_intially_open_capture_tag_offsets(self):
        '''Test that if a sink is created without a file initially open,
        and then a file is opened, that capture stream tags will have the
        correct offsets, i.e. they should be set from when the
        file was opened, not when the flowgraph started'''
        samp_rate = 200000
        src = analog.sig_source_c(0, analog.GR_CONST_WAVE, 0, 0, (1 + 1j))

        description = "This is a test of the sigmf sink."
        author = "Just some person"
        file_license = "CC-0"
        hardware = "Sig Source"
        data_file, json_file = self.temp_file_names()
        file_sink = sigmf.sink("cf32_le", "")
        file_sink.set_global_meta("core:sample_rate", samp_rate)
        file_sink.set_global_meta("core:description", description)
        file_sink.set_global_meta("core:author", author)
        file_sink.set_global_meta("core:sample_rate", author)
        file_sink.set_global_meta("core:license", file_license)
        file_sink.set_global_meta("core:hw", hardware)

        injector = simple_tag_injector()
        # build flowgraph here
        tb = gr.top_block()
        tb.connect(src, injector)
        tb.connect(injector, file_sink)
        tb.start()
        time.sleep(.1)
        file_sink.open(data_file)
        time.sleep(.1)
        injector.inject_tag = {"rx_freq": 900e6}
        time.sleep(.1)
        tb.stop()
        tb.wait()
        injected_offset = injector.injected_offset

        with open(json_file, "r") as f:
            meta_str = f.read()
            meta = json.loads(meta_str)

            # Check global meta
            assert meta["global"]["core:description"] == description
            assert meta["global"]["core:author"] == author
            assert meta["global"]["core:license"] == file_license
            assert meta["global"]["core:hw"] == hardware

            # Check capture meta
            # The sample_start should be less than what it was injected
            # at, since no file was open at first, so the internal offsets
            # were off
            assert (meta["captures"][0]
                    ["core:sample_start"] < injected_offset)
Exemple #7
0
    def test_stream_tags_before_file(self):
        '''Test that stream tags received before a file is opened will
        get correctly set as metadata'''
        samp_rate = 200000
        src = analog.sig_source_c(0, analog.GR_CONST_WAVE, 0, 0, (1 + 1j))

        description = "This is a test of the sigmf sink."
        author = "Just some person"
        file_license = "CC-0"
        hardware = "Sig Source"
        data_file, json_file = self.temp_file_names()
        file_sink = sigmf.sink("cf32_le",
                               "")
        file_sink.set_global_meta("core:sample_rate", samp_rate)
        file_sink.set_global_meta("core:description", description)
        file_sink.set_global_meta("core:author", author)
        file_sink.set_global_meta("core:sample_rate", author)
        file_sink.set_global_meta("core:license", file_license)
        file_sink.set_global_meta("core:hw", hardware)

        injector = simple_tag_injector()
        # build flowgraph here
        tb = gr.top_block()
        tb.connect(src, injector)
        tb.connect(injector, file_sink)
        tb.start()
        time.sleep(.1)
        injector.inject_tag = {"test:a": 1}
        time.sleep(.1)
        injector.inject_tag = {"rx_freq": 900e6}
        time.sleep(.2)
        file_sink.open(data_file)
        time.sleep(.5)
        tb.stop()
        tb.wait()

        with open(json_file, "r") as f:
            meta_str = f.read()
            meta = json.loads(meta_str)

            # Check global meta
            assert meta["global"]["core:description"] == description
            assert meta["global"]["core:author"] == author
            assert meta["global"]["core:license"] == file_license
            assert meta["global"]["core:hw"] == hardware

            print(meta)
            # Check captures meta
            assert meta["captures"][0]["core:frequency"] == 900e6
            # Check annotations meta, should be empty, since annotations are
            # meant for specific samples and shouldn't be saved
            assert len(meta["annotations"]) == 0
Exemple #8
0
    def test_pmt_to_annotation(self):
        src = analog.sig_source_c(0, analog.GR_CONST_WAVE, 0, 0, (1 + 1j))
        data_file, json_file = self.temp_file_names()
        file_sink = sigmf.sink("cf32_le", data_file)

        injector = simple_tag_injector()
        sender = msg_sender()
        counter = sample_counter()
        tb = gr.top_block()
        tb.connect(src, injector)
        tb.connect(injector, counter)
        tb.connect(counter, file_sink)
        tb.msg_connect(sender, "out", file_sink, "command")

        tb.start()
        # sleep so the streamed annotation isn't the first one
        sleep(.1)
        # Inject one tag
        injector.inject_tag = {"test:a": 1}
        # Wait again so that we know the tag got processed
        sleep(.1)
        # Then tell it to add 2 more via pmts,
        # one before the injected tag
        sender.send_msg({
            "command": "set_annotation_meta",
            "sample_start": 1,
            "sample_count": 10,
            "key": "test:b",
            "val": 22
        })
        # and one after
        sender.send_msg({
            "command": "set_annotation_meta",
            "sample_start": counter.count + 1,
            "sample_count": 10,
            "key": "test:c",
            "val": True
        })
        sleep(.25)
        tb.stop()
        tb.wait()
        metadata = json.load(open(json_file, "r"))
        # should be 3 annotations
        self.assertEqual(len(metadata["annotations"]), 3)
        # And they should be these and in this order
        self.assertEqual(metadata["annotations"][0]["test:b"], 22)
        self.assertEqual(metadata["annotations"][1]["test:a"], 1)
        self.assertEqual(metadata["annotations"][2]["test:c"], True)
Exemple #9
0
    def test_relative_time_mode_initial_closed(self):
        '''Test relative time mode when the sink is initially not recording'''
        # limit_event = Event()
        # continue_event = Event()

        samp_rate = 100e6
        limit_samples = samp_rate
        print(limit_samples)
        # src = sample_producer(limit_samples, limit_event, continue_event)
        src = analog.sig_source_c(0, analog.GR_CONST_WAVE, 0, 0, (1 + 1j))

        data_file, json_file = self.temp_file_names()
        file_sink = sigmf.sink("cf32_le", "",
                               sigmf.sigmf_time_mode_relative)
        file_sink.set_global_meta("core:sample_rate", samp_rate)

        injector = simple_tag_injector()
        # first sample should have a rx_time tag
        injector.inject_tag = {"rx_time": (65000, 0.500000)}
        tb = gr.top_block()
        tb.connect(src, injector)
        tb.connect(injector, file_sink)
        tb.start()
        # sleep to let some samples get to the sink block
        sleep(.1)
        # set the rx_time tag for the next section
        file_sink.open(data_file)
        # Let some stuff get recorded
        sleep(.1)
        tb.stop()
        tb.wait()

        with open(json_file, "r") as f:
            meta = json.load(f)
            capture_one_dt = parse_iso_ts(meta["captures"][0]["core:datetime"])
            now = datetime.utcnow()
            print(capture_one_dt)
            print(now)
            self.assertEqual(now.year, capture_one_dt.year,
                             "Bad year in first capture segment")
            self.assertEqual(now.month, capture_one_dt.month,
                             "Bad month in first capture segment")
            self.assertEqual(now.day, capture_one_dt.day,
                             "Bad day in first capture segment")
Exemple #10
0
        def run_iteration(wait_full, wait_frac):
            limit_event = Event()
            continue_event = Event()
            samp_rate = 10000.0
            limit_samples = (samp_rate * wait_full) + (samp_rate * wait_frac)
            print(limit_samples)
            src = sample_producer(limit_samples, limit_event, continue_event)

            data_file, json_file = self.temp_file_names()
            file_sink = sigmf.sink("cf32_le", "")
            file_sink.set_global_meta("core:sample_rate", samp_rate)

            seconds = 1520551983
            frac_seconds = 0.09375
            end_seconds = seconds + wait_full
            end_frac = frac_seconds + wait_frac
            if (end_frac > 1):
                end_seconds += 1
                end_frac -= 1
            correct_str = datetime.utcfromtimestamp(
                end_seconds).strftime('%Y-%m-%dT%H:%M:%S')
            correct_str += str(end_frac).lstrip('0') + "Z"
            injector = simple_tag_injector()
            # first sample should have a rx_time tag
            injector.inject_tag = {"rx_time": (seconds, frac_seconds)}
            tb = gr.top_block()
            tb.connect(src, injector)
            tb.connect(injector, file_sink)
            tb.start()
            print("waiting")
            limit_event.wait()
            # sleep to let the last samples get to the sink block
            sleep(.1)
            file_sink.open(data_file)
            continue_event.set()
            sleep(.1)
            tb.stop()
            tb.wait()

            with open(json_file, "r") as f:
                meta = json.load(f)
                print(meta)
                assert meta["captures"][0]["core:datetime"] == correct_str