コード例 #1
0
def test_get_tr_data(serial_mock, raw):
    sw = SpotWave(serial_mock)

    lines = [
        b"TRAI = 1 T=43686000 NS=13\n",
        b"TRAI=2 T=43686983 NS=27\n",
        b"\n",
    ]
    data = [np.arange(samples, dtype=np.int16) for samples in (13, 27)]
    binary_data = [arr.tobytes() for arr in data]

    serial_mock.readline.side_effect = lines
    serial_mock.read.side_effect = binary_data

    tr_data = sw.get_tr_data(raw=raw)

    assert tr_data[0].trai == 1
    assert tr_data[0].time == pytest.approx(43686000 / 2e6)
    assert tr_data[0].samples == 13
    assert tr_data[0].raw == raw
    if raw:
        assert_allclose(tr_data[0].data, data[0])
    else:
        assert_allclose(tr_data[0].data, data[0] * ADC_TO_VOLTS)

    assert tr_data[1].trai == 2
    assert tr_data[1].time == pytest.approx(43686983 / 2e6)
    assert tr_data[1].samples == 27
    assert tr_data[1].raw == raw
    if raw:
        assert_allclose(tr_data[1].data, data[1])
    else:
        assert_allclose(tr_data[1].data, data[1] * ADC_TO_VOLTS)
コード例 #2
0
def main():
    port = SpotWave.discover()[0]

    with SpotWave(port) as sw:
        # apply settings
        sw.set_continuous_mode(True)
        sw.set_cct(0)
        sw.set_status_interval(0)
        sw.set_tr_enabled(True)
        sw.set_tr_decimation(4)  # 2 MHz / 4 = 500 kHz
        sw.set_ddt(100_000)  # 100 ms * 500 kHz = 50.000 samples
        sw.set_filter(50e3, 200e3, 4)  # 50-200 kHz bandpass

        # show settings
        print("Settings:")
        for key, value in asdict(sw.get_setup()).items():
            print(f"- {key}: {value}")
        print()

        for record in sw.stream():
            if isinstance(record, TRRecord):
                y = record.data
                y_max = np.max(y)

                # visualize max amplitude with "level meter"
                cols = int(80 * y_max / 0.05)  # 50 mV input range
                print(f"{y_max:<8f} V: " + "#" * cols + "-" * (80 - cols), end="\r")

            elif isinstance(record, AERecord):
                ...
コード例 #3
0
def main(basename: str, seconds_per_file: float):
    def get_filename():
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        return f"{basename}_{timestamp}.wav"

    port = SpotWave.discover()[0]
    print(port)

    with SpotWave(port) as sw:
        sw.set_datetime()
        sw.set_continuous_mode(True)
        sw.set_cct(0)
        sw.set_status_interval(0)
        sw.set_tr_enabled(True)
        sw.set_tr_decimation(1)  # 2 MHz
        sw.set_ddt(10_000)  # 10 ms
        sw.set_filter(None, None)  # deactivate IIR filter

        setup = sw.get_setup()
        samplerate = sw.CLOCK / setup.tr_decimation
        chunks_per_file = int(seconds_per_file / setup.ddt_seconds)

        def async_write():
            chunks = chunks_per_file  # create on first data
            while trqueue:
                try:
                    tr = trqueue.get(timeout=0.1)
                except:
                    continue
                if chunks >= chunks_per_file:
                    logger.info(f"{chunks_per_file} chunks acquired")
                    writer = WavWriter(get_filename(), samplerate)
                    chunks = 0
                writer.write(tr.data)
                chunks += 1

            print("Write finished")

        last_t = 0
        missed = 0
        trqueue = queue.SimpleQueue()
        threading.Thread(target=async_write).start()
        try:
            for record in sw.stream(
                    raw=True):  # return ADC values with enabled raw flag
                if isinstance(record, TRRecord):
                    trqueue.put(record)
                elif isinstance(record, AERecord):
                    if record.trai == 0 or record.flags > 0:
                        missed += 1

                if missed > 0 and time.monotonic() - last_t > 1:
                    logger.warning(f"Missed {missed} record(s)")
                    missed = 0
                    last_t = time.monotonic()
        finally:
            trqueue = None  # flag to stop
コード例 #4
0
ファイル: conftest.py プロジェクト: vallen-systems/pyWaveLine
def sw():
    devices = SpotWave.discover()
    if not devices:
        raise RuntimeError(
            "No spotWave devices found. Please connect a device to run the system tests"
        )
    with SpotWave(devices[0]) as sw:
        sw.set_datetime()  # set current date/time
        sw.clear_buffer()
        yield sw
コード例 #5
0
def test_get_data(serial_mock, samples, raw):
    sw = SpotWave(serial_mock)

    mock_data = (2**15 * np.random.randn(samples)).astype(np.int16)
    serial_mock.read.return_value = mock_data.tobytes()

    data = sw.get_data(samples, raw=raw)
    serial_mock.write.assert_called_with(f"get_data b {samples}\n".encode())
    serial_mock.read.assert_called_with(samples * 2)
    if raw:
        assert_allclose(data, mock_data)
    else:
        assert_allclose(data, mock_data * ADC_TO_VOLTS)
コード例 #6
0
def main():
    port = SpotWave.discover()[0]

    with SpotWave(port) as sw:
        sw.set_continuous_mode(False)  # -> hit-based
        sw.set_cct(0)  # disable pulser
        sw.set_ddt(10_000)  # 10.000 µs
        sw.set_status_interval(2)  # generate status data every 2 seconds
        sw.set_threshold(1000)  # 1000 µV = 60 dB(AE)
        sw.set_tr_enabled(True)  # enable transient data recording
        sw.set_tr_pretrigger(200)  # 200 pre-trigger samples
        sw.set_tr_postduration(0)  # 0 post-duration samples
        sw.set_filter(100e3, 450e3, 4)  # 100-450 kHz bandpass

        for record in merge_ae_tr_records(sw.stream()):
            print(record)
コード例 #7
0
def main():
    ports = SpotWave.discover()
    print(f"Discovered spotWave devices: {ports}")
    port = ports[0]

    with SpotWave(port) as sw:
        sw.set_datetime()
        sw.set_cct(0)  # disable cct/pulser
        sw.set_continuous_mode(True)  # enable continous mode
        sw.set_ddt(100_000)  # 100 ms block size
        sw.set_filter(highpass=50e3, lowpass=300e3,
                      order=4)  # 50-300 kHz bandpass
        sw.set_status_interval(0)  # disable status data
        sw.set_tr_enabled(False)  # disable transient data

        for record in sw.stream():
            # compute RMS from energy (in eu = 1e-14 V²s) and duration (in seconds)
            rms_volts = math.sqrt(record.energy / 1e14 / record.duration)
            print(f"RMS: {1e6 * rms_volts:0.2f} µV")
コード例 #8
0
def test_get_info(serial_mock):
    sw = SpotWave(serial_mock)

    response = [
        b"hw_id = 0019003A3438511539373231\n",
        b"fw_version=00.21\n",
        b"input_range=94 dBAE\n",
    ]
    serial_mock.readlines.return_value = response
    info = sw.get_info()
    serial_mock.write.assert_called_with(b"get_info\n")

    assert info.hardware_id == "0019003A3438511539373231"
    assert info.firmware_version == "00.21"
    assert info.input_range_decibel == 94

    # empty response
    serial_mock.readlines.return_value = []
    with pytest.raises(RuntimeError):
        sw.get_info()
コード例 #9
0
def main():
    port = SpotWave.discover()[0]

    # prepare plot
    plt.ion()
    _, ax = plt.subplots(figsize=(10, 3), tight_layout=True)

    with SpotWave(port) as sw:
        sw.set_cct(1, sync=True)
        sw.set_filter(90e3, 150e3, 4)  # 90-150 kHz bandpass

        while True:
            data = sw.get_data(2048)  # read snapshot -> trigger pulser
            t = np.arange(len(data)) / sw.CLOCK  # create time axis

            ax.clear()
            ax.plot(t * 1e6, data * 1e6)
            ax.set_xlabel("Time [µs]")
            ax.set_ylabel("Amplitude [µV]")
            plt.pause(1)
コード例 #10
0
def test_get_ae_data(serial_mock):
    sw = SpotWave(serial_mock)

    response = [
        b"2\n",
        b"S temp=27 T = 2010240 A=21 R=502689 D=2000000 C=0 E=38849818 TRAI=0 flags=0\n",
        b"H temp=27 T=3044759 A=3557 R=24 D=819 C=31 E=518280026 TRAI=1 flags=0\n",
    ]

    serial_mock.readline.side_effect = response
    ae_data = sw.get_ae_data()
    ADC_TO_EU = ADC_TO_VOLTS**2 * 1e14 / 2e6

    # status record
    s = ae_data[0]
    assert s.type_ == "S"
    assert s.time == pytest.approx(2010240 / 2e6)
    assert s.amplitude == pytest.approx(21 * ADC_TO_VOLTS)
    assert s.rise_time == pytest.approx(502689 / 2e6)
    assert s.duration == pytest.approx(2000000 / 2e6)
    assert s.counts == 0
    assert s.energy == pytest.approx(38849818 * ADC_TO_EU)
    assert s.trai == 0
    assert s.flags == 0

    # hit record
    h = ae_data[1]
    assert h.type_ == "H"
    assert h.time == pytest.approx(3044759 / 2e6)
    assert h.amplitude == pytest.approx(3557 * ADC_TO_VOLTS)
    assert h.rise_time == pytest.approx(24 / 2e6)
    assert h.duration == pytest.approx(819 / 2e6)
    assert h.counts == 31
    assert h.energy == pytest.approx(518280026 * ADC_TO_EU)
    assert h.trai == 1
    assert h.flags == 0
コード例 #11
0
def test_get_status(serial_mock):
    sw = SpotWave(serial_mock)

    response = [
        b"temp=24 \xc2\xb0C\n",
        b"acq_enabled=0\n",
        b"log_enabled=0\n",
        b"log_data_usage=13 %\n",
        b"date=2020-12-17 15:11:42.17\n",
    ]
    serial_mock.readlines.return_value = response
    status = sw.get_status()
    serial_mock.write.assert_called_with(b"get_status\n")

    assert status.temperature == 24
    assert status.acq_enabled == False
    assert status.log_enabled == False
    assert status.log_data_usage == 13
    assert status.datetime == datetime(2020, 12, 17, 15, 11, 42, 170_000)

    # empty response
    serial_mock.readlines.return_value = []
    with pytest.raises(RuntimeError):
        sw.get_status()
コード例 #12
0
def test_get_setup(serial_mock):
    sw = SpotWave(serial_mock)

    response = [
        b"acq_enabled=1\n",
        b"log_enabled=0\n",
        b"adc2uv=1.74\n",
        b"cct=-0.5 s\n",
        b"filter=10.5-350 kHz, order 4\n",
        b"cont=0\n",
        b"thr=3162.5 uV\n",
        b"ddt=250  us\n",
        b"dummy line without value",
        b" status_interval = 1000 ms ",
        b"tr_enabled=1\n",
        b"tr_decimation=2\n",
        b"tr_pre_trig=100\n",
        b"tr_post_dur=100\n",
        b"tr_max_samples=2097152\n",
    ]
    serial_mock.readlines.return_value = response
    setup = sw.get_setup()
    serial_mock.write.assert_called_with(b"get_setup\n")
    assert setup == Setup(
        acq_enabled=True,
        cont_enabled=False,
        log_enabled=False,
        adc_to_volts=1.74e-6,
        threshold_volts=3162.5e-6,
        ddt_seconds=250e-6,
        status_interval_seconds=1,
        filter_highpass_hz=10.5e3,
        filter_lowpass_hz=350e3,
        filter_order=4,
        tr_enabled=1,
        tr_decimation=2,
        tr_pretrigger_samples=100,
        tr_postduration_samples=100,
        cct_seconds=-0.5,
    )

    # test special filter outputs
    response[4] = b"filter=none-350 kHz, order 4\n"
    serial_mock.readlines.return_value = response
    setup = sw.get_setup()
    assert setup.filter_highpass_hz == None
    assert setup.filter_lowpass_hz == 350_000
    assert setup.filter_order == 4

    response[4] = b"filter=10.5-none kHz, order 4\n"
    serial_mock.readlines.return_value = response
    setup = sw.get_setup()
    assert setup.filter_highpass_hz == 10_500
    assert setup.filter_lowpass_hz == None
    assert setup.filter_order == 4

    response[4] = b"filter=none-none kHz, order 0\n"
    serial_mock.readlines.return_value = response
    setup = sw.get_setup()
    assert setup.filter_highpass_hz == None
    assert setup.filter_lowpass_hz == None
    assert setup.filter_order == 0

    # empty response
    serial_mock.readlines.return_value = []
    with pytest.raises(RuntimeError):
        sw.get_setup()
コード例 #13
0
def test_init_invalid_type():
    with pytest.raises(ValueError):
        SpotWave(123)
コード例 #14
0
def test_init_port():
    with pytest.raises(SerialException):
        SpotWave("invalid_port_id")
コード例 #15
0
def test_init_serial(serial_mock):
    sw = SpotWave(serial_mock)
    assert sw._ser == serial_mock  # pylint: disable=protected-access
    serial_mock.open.assert_called()
コード例 #16
0
def test_commands_without_response(serial_mock):
    sw = SpotWave(serial_mock)

    def assert_write(expected):
        serial_mock.write.assert_called_with(expected)

    sw.set_continuous_mode(True)
    assert_write(b"set_acq cont 1\n")

    sw.set_ddt(400)
    assert_write(b"set_acq ddt 400\n")

    sw.set_status_interval(2.2)
    assert_write(b"set_acq status_interval 2200\n")

    sw.set_tr_enabled(True)
    assert_write(b"set_acq tr_enabled 1\n")

    sw.set_tr_decimation(10)
    assert_write(b"set_acq tr_decimation 10\n")

    sw.set_tr_pretrigger(200)
    assert_write(b"set_acq tr_pre_trig 200\n")

    sw.set_tr_postduration(0)
    assert_write(b"set_acq tr_post_dur 0\n")

    sw.set_cct(0.1, sync=False)
    assert_write(b"set_cct 0.1\n")
    sw.set_cct(-0.1, sync=False)
    assert_write(b"set_cct -0.1\n")
    sw.set_cct(0.1, sync=True)
    assert_write(b"set_cct -0.1\n")

    sw.set_filter(highpass=100_000, lowpass=300_000, order=6)
    assert_write(b"set_filter 100.0 300.0 6\n")

    sw.set_datetime(datetime(2020, 12, 16, 17, 55, 13))
    assert_write(b"set_datetime 2020-12-16 17:55:13\n")

    sw.set_datetime()  # datetime.now() -> frozen time
    assert_write(b"set_datetime 2022-11-11 00:00:00\n")

    sw.set_threshold(100)
    assert_write(b"set_acq thr 100\n")

    sw.start_acquisition()
    assert_write(b"set_acq enabled 1\n")

    sw.stop_acquisition()
    assert_write(b"set_acq enabled 0\n")