From 99ccc8da127b29a3467760f03dacf35cf2bcdae7 Mon Sep 17 00:00:00 2001 From: Anthony Romaniello Date: Tue, 31 Oct 2023 10:08:11 -0600 Subject: [PATCH 01/45] Update scos-actions branch for testing --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 7fb77cd..6906899 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,7 +41,7 @@ classifiers = [ dependencies = [ "environs>=9.5.0", "tekrsa-api-wrap>=1.3.2", - "scos_actions @ git+https://github.com/NTIA/scos-actions@6.4.2", + "scos_actions @ git+https://github.com/NTIA/scos-actions@add-percentile-detector", ] [project.optional-dependencies] From ec8dc564b349909fa6035822b90834d4362551fe Mon Sep 17 00:00:00 2001 From: Anthony Romaniello Date: Tue, 31 Oct 2023 10:53:54 -0600 Subject: [PATCH 02/45] Add testing config --- .../A_TEST_CBRS_EXT_PercentilesData.yml | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 src/scos_tekrsa/configs/actions-500-600/A_TEST_CBRS_EXT_PercentilesData.yml diff --git a/src/scos_tekrsa/configs/actions-500-600/A_TEST_CBRS_EXT_PercentilesData.yml b/src/scos_tekrsa/configs/actions-500-600/A_TEST_CBRS_EXT_PercentilesData.yml new file mode 100644 index 0000000..69fda55 --- /dev/null +++ b/src/scos_tekrsa/configs/actions-500-600/A_TEST_CBRS_EXT_PercentilesData.yml @@ -0,0 +1,44 @@ +nasctn_sea_data_product: + name: A_TEST_CBRS_EXT_PercentilesData + rf_path: antenna +# IIR filter settings + iir_gpass_dB: 0.1 # Max passband ripple below unity gain + iir_gstop_dB: 40 # Minimum stopband attenuation + iir_pb_edge_Hz: 5e6 # Passband edge frequency + iir_sb_edge_Hz: 5.008e6 # Stopband edge frequency +# FFT settings + nffts: 320e3 +# PFP frame + pfp_frame_period_ms: 10 +# APD downsampling settings + apd_bin_size_dB: 1.0 # Set to 0 or negative for no downsampling + apd_max_bin_dBm: -30 + apd_min_bin_dBm: -180 +# Time domain power statistics settings + td_bin_size_ms: 10 +# Sigan Settings + preamp_enable: True + reference_level: -25 + attenuation: 0 + sample_rate: 14e6 +# Acquisition settings (3540-3710 MHz in 10 MHz steps, each 4s long) + duration_ms: 4000 + nskip: 0 + frequency: + - 3545e6 + - 3555e6 + - 3565e6 + - 3575e6 + - 3585e6 + - 3595e6 + - 3605e6 + - 3615e6 + - 3625e6 + - 3635e6 + - 3645e6 + - 3655e6 + - 3665e6 + - 3675e6 + - 3685e6 + - 3695e6 + - 3705e6 From d1202391b57c9791f573d07c83632a00c38ffe60 Mon Sep 17 00:00:00 2001 From: Doug Boulware Date: Mon, 11 Dec 2023 10:24:18 -0700 Subject: [PATCH 03/45] scos-actions branch testing. --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index d40e60a..d175665 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,7 +41,7 @@ classifiers = [ dependencies = [ "environs>=9.5.0", "tekrsa-api-wrap>=1.3.2", - "scos_actions @ git+https://github.com/NTIA/scos-actions@7.0.0", + "scos_actions @ git+https://github.com/NTIA/scos-actions@empty_calibration_params", ] [project.optional-dependencies] From 2cc4da9597c49a5c3ab886ca157a2359b9bcbb8e Mon Sep 17 00:00:00 2001 From: Anthony Romaniello Date: Thu, 14 Dec 2023 11:34:41 -0500 Subject: [PATCH 04/45] Add noise-diode-off testing config --- .../B_TEST_CBRS_EXT_PercentilesData.yml | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 src/scos_tekrsa/configs/actions-500-600/B_TEST_CBRS_EXT_PercentilesData.yml diff --git a/src/scos_tekrsa/configs/actions-500-600/B_TEST_CBRS_EXT_PercentilesData.yml b/src/scos_tekrsa/configs/actions-500-600/B_TEST_CBRS_EXT_PercentilesData.yml new file mode 100644 index 0000000..d15b6c6 --- /dev/null +++ b/src/scos_tekrsa/configs/actions-500-600/B_TEST_CBRS_EXT_PercentilesData.yml @@ -0,0 +1,44 @@ +nasctn_sea_data_product: + name: B_TEST_CBRS_EXT_PercentilesData + rf_path: noise_diode_off +# IIR filter settings + iir_gpass_dB: 0.1 # Max passband ripple below unity gain + iir_gstop_dB: 40 # Minimum stopband attenuation + iir_pb_edge_Hz: 5e6 # Passband edge frequency + iir_sb_edge_Hz: 5.008e6 # Stopband edge frequency +# FFT settings + nffts: 320e3 +# PFP frame + pfp_frame_period_ms: 10 +# APD downsampling settings + apd_bin_size_dB: 1.0 # Set to 0 or negative for no downsampling + apd_max_bin_dBm: -30 + apd_min_bin_dBm: -180 +# Time domain power statistics settings + td_bin_size_ms: 10 +# Sigan Settings + preamp_enable: True + reference_level: -25 + attenuation: 0 + sample_rate: 14e6 +# Acquisition settings (3540-3710 MHz in 10 MHz steps, each 4s long) + duration_ms: 4000 + nskip: 0 + frequency: + - 3545e6 + - 3555e6 + - 3565e6 + - 3575e6 + - 3585e6 + - 3595e6 + - 3605e6 + - 3615e6 + - 3625e6 + - 3635e6 + - 3645e6 + - 3655e6 + - 3665e6 + - 3675e6 + - 3685e6 + - 3695e6 + - 3705e6 From 209f7aceb5e27da3c23f184313e9cd0924ecf07c Mon Sep 17 00:00:00 2001 From: Anthony Romaniello Date: Fri, 22 Dec 2023 15:59:00 -0500 Subject: [PATCH 05/45] Add firmware and API version properties --- src/scos_tekrsa/hardware/tekrsa_sigan.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/scos_tekrsa/hardware/tekrsa_sigan.py b/src/scos_tekrsa/hardware/tekrsa_sigan.py index 4f378bc..77d46b6 100644 --- a/src/scos_tekrsa/hardware/tekrsa_sigan.py +++ b/src/scos_tekrsa/hardware/tekrsa_sigan.py @@ -92,6 +92,8 @@ def connect(self): raise e # Finish setup with either real or Mock RSA device self.device_name = self.rsa.DEVICE_GetNomenclature() + self._firmware_version = self.rsa.DEVICE_GetFWVersion() + self._api_version = self.rsa.DEVICE_GetAPIVersion() self.get_constraints() logger.debug("Using the following Tektronix RSA device:") logger.debug( @@ -106,14 +108,24 @@ def connect(self): self._is_available = True @property - def is_available(self): + def is_available(self) -> bool: """Returns True if initialized and ready for measurements""" return self._is_available @property - def plugin_version(self): + def plugin_version(self) -> str: """Returns the current version of scos-tekrsa.""" return self._plugin_version + + @property + def firmware_version(self) -> str: + """Returns the current firmware version of the connected RSA device.""" + return self._firmware_version + + @property + def api_version(self) -> str: + """Returns the version of the Tektronix RSA API for Linux currently in use.""" + return self._api_version @property def sample_rate(self): From 01561c2e41e34fac4bbdc19fb7d6f7ba6751245d Mon Sep 17 00:00:00 2001 From: Anthony Romaniello Date: Fri, 22 Dec 2023 15:59:20 -0500 Subject: [PATCH 06/45] Add new properties to unit tests --- tests/test_tekrsa_sigan.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/test_tekrsa_sigan.py b/tests/test_tekrsa_sigan.py index bbd8fe5..50028c9 100644 --- a/tests/test_tekrsa_sigan.py +++ b/tests/test_tekrsa_sigan.py @@ -5,6 +5,7 @@ import numpy as np import pytest +from scos_tekrsa import __version__ as SCOS_TEKRSA_VERSION import scos_tekrsa.hardware.tekrsa_constants as rsa_constants from scos_tekrsa.hardware import sigan from scos_tekrsa.hardware.mocks.rsa_block import ( @@ -64,6 +65,16 @@ def test_is_available(self): assert self.rx.is_available == True assert isinstance(self.rx.is_available, bool) + def test_plugin_version(self): + assert isinstance(self.rx.plugin_version, str) + assert self.rx.plugin_version == SCOS_TEKRSA_VERSION + + def test_firmware_version(self): + assert isinstance(self.rx.firmware_version, str) + + def test_api_version(self): + assert isinstance(self.rx.api_version, str) + def test_sample_rate(self): assert isinstance(self.rx.sample_rate, (float, int)) From f4bb711a83116db3d8c58a97f00696533e7ee0ec Mon Sep 17 00:00:00 2001 From: Anthony Romaniello Date: Fri, 22 Dec 2023 15:59:57 -0500 Subject: [PATCH 07/45] Bump minor version to 4.1.0 --- src/scos_tekrsa/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scos_tekrsa/__init__.py b/src/scos_tekrsa/__init__.py index ce1305b..7039708 100644 --- a/src/scos_tekrsa/__init__.py +++ b/src/scos_tekrsa/__init__.py @@ -1 +1 @@ -__version__ = "4.0.0" +__version__ = "4.1.0" From ab62b2c8a9b4906e2bbc8e9c722a95acc253252e Mon Sep 17 00:00:00 2001 From: Anthony Romaniello Date: Fri, 22 Dec 2023 16:02:48 -0500 Subject: [PATCH 08/45] Update required scos-actions version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index d40e60a..373873b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,7 +41,7 @@ classifiers = [ dependencies = [ "environs>=9.5.0", "tekrsa-api-wrap>=1.3.2", - "scos_actions @ git+https://github.com/NTIA/scos-actions@7.0.0", + "scos_actions @ git+https://github.com/NTIA/scos-actions@7.1.0", ] [project.optional-dependencies] From e7983883e5c038e83f830346982ec92e3451981e Mon Sep 17 00:00:00 2001 From: Anthony Romaniello Date: Wed, 27 Dec 2023 13:12:40 -0500 Subject: [PATCH 09/45] Delete testing configs --- .../A_TEST_CBRS_EXT_PercentilesData.yml | 44 ------------------- .../B_TEST_CBRS_EXT_PercentilesData.yml | 44 ------------------- 2 files changed, 88 deletions(-) delete mode 100644 src/scos_tekrsa/configs/actions-500-600/A_TEST_CBRS_EXT_PercentilesData.yml delete mode 100644 src/scos_tekrsa/configs/actions-500-600/B_TEST_CBRS_EXT_PercentilesData.yml diff --git a/src/scos_tekrsa/configs/actions-500-600/A_TEST_CBRS_EXT_PercentilesData.yml b/src/scos_tekrsa/configs/actions-500-600/A_TEST_CBRS_EXT_PercentilesData.yml deleted file mode 100644 index 69fda55..0000000 --- a/src/scos_tekrsa/configs/actions-500-600/A_TEST_CBRS_EXT_PercentilesData.yml +++ /dev/null @@ -1,44 +0,0 @@ -nasctn_sea_data_product: - name: A_TEST_CBRS_EXT_PercentilesData - rf_path: antenna -# IIR filter settings - iir_gpass_dB: 0.1 # Max passband ripple below unity gain - iir_gstop_dB: 40 # Minimum stopband attenuation - iir_pb_edge_Hz: 5e6 # Passband edge frequency - iir_sb_edge_Hz: 5.008e6 # Stopband edge frequency -# FFT settings - nffts: 320e3 -# PFP frame - pfp_frame_period_ms: 10 -# APD downsampling settings - apd_bin_size_dB: 1.0 # Set to 0 or negative for no downsampling - apd_max_bin_dBm: -30 - apd_min_bin_dBm: -180 -# Time domain power statistics settings - td_bin_size_ms: 10 -# Sigan Settings - preamp_enable: True - reference_level: -25 - attenuation: 0 - sample_rate: 14e6 -# Acquisition settings (3540-3710 MHz in 10 MHz steps, each 4s long) - duration_ms: 4000 - nskip: 0 - frequency: - - 3545e6 - - 3555e6 - - 3565e6 - - 3575e6 - - 3585e6 - - 3595e6 - - 3605e6 - - 3615e6 - - 3625e6 - - 3635e6 - - 3645e6 - - 3655e6 - - 3665e6 - - 3675e6 - - 3685e6 - - 3695e6 - - 3705e6 diff --git a/src/scos_tekrsa/configs/actions-500-600/B_TEST_CBRS_EXT_PercentilesData.yml b/src/scos_tekrsa/configs/actions-500-600/B_TEST_CBRS_EXT_PercentilesData.yml deleted file mode 100644 index d15b6c6..0000000 --- a/src/scos_tekrsa/configs/actions-500-600/B_TEST_CBRS_EXT_PercentilesData.yml +++ /dev/null @@ -1,44 +0,0 @@ -nasctn_sea_data_product: - name: B_TEST_CBRS_EXT_PercentilesData - rf_path: noise_diode_off -# IIR filter settings - iir_gpass_dB: 0.1 # Max passband ripple below unity gain - iir_gstop_dB: 40 # Minimum stopband attenuation - iir_pb_edge_Hz: 5e6 # Passband edge frequency - iir_sb_edge_Hz: 5.008e6 # Stopband edge frequency -# FFT settings - nffts: 320e3 -# PFP frame - pfp_frame_period_ms: 10 -# APD downsampling settings - apd_bin_size_dB: 1.0 # Set to 0 or negative for no downsampling - apd_max_bin_dBm: -30 - apd_min_bin_dBm: -180 -# Time domain power statistics settings - td_bin_size_ms: 10 -# Sigan Settings - preamp_enable: True - reference_level: -25 - attenuation: 0 - sample_rate: 14e6 -# Acquisition settings (3540-3710 MHz in 10 MHz steps, each 4s long) - duration_ms: 4000 - nskip: 0 - frequency: - - 3545e6 - - 3555e6 - - 3565e6 - - 3575e6 - - 3585e6 - - 3595e6 - - 3605e6 - - 3615e6 - - 3625e6 - - 3635e6 - - 3645e6 - - 3655e6 - - 3665e6 - - 3675e6 - - 3685e6 - - 3695e6 - - 3705e6 From ddb14e1b9bc1f0fa7333f5b66d348e0fa74acd51 Mon Sep 17 00:00:00 2001 From: Anthony Romaniello Date: Wed, 27 Dec 2023 13:12:56 -0500 Subject: [PATCH 10/45] Update nffts in SEA data product configs --- .../actions-500-600/CBRS_DataProduct_00dB_Attenuation.yml | 4 ++-- .../actions-500-600/CBRS_EXT_DataProduct_00dB_Attenuation.yml | 4 ++-- .../actions-500-600/CBRS_EXT_DataProduct_02dB_Attenuation.yml | 4 ++-- .../actions-500-600/CBRS_EXT_DataProduct_04dB_Attenuation.yml | 4 ++-- .../actions-500-600/CBRS_EXT_DataProduct_06dB_Attenuation.yml | 4 ++-- .../actions-500-600/CBRS_EXT_DataProduct_08dB_Attenuation.yml | 4 ++-- .../actions-500-600/CBRS_EXT_DataProduct_10dB_Attenuation.yml | 4 ++-- .../actions-500-600/CBRS_EXT_DataProduct_12dB_Attenuation.yml | 4 ++-- .../actions-500-600/CBRS_EXT_DataProduct_14dB_Attenuation.yml | 4 ++-- .../actions-500-600/CBRS_EXT_DataProduct_16dB_Attenuation.yml | 4 ++-- .../actions-500-600/CBRS_EXT_DataProduct_18dB_Attenuation.yml | 4 ++-- .../actions-500-600/CBRS_EXT_DataProduct_20dB_Attenuation.yml | 4 ++-- .../actions-500-600/CBRS_EXT_DataProduct_22dB_Attenuation.yml | 4 ++-- 13 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/scos_tekrsa/configs/actions-500-600/CBRS_DataProduct_00dB_Attenuation.yml b/src/scos_tekrsa/configs/actions-500-600/CBRS_DataProduct_00dB_Attenuation.yml index 1702881..04396a5 100644 --- a/src/scos_tekrsa/configs/actions-500-600/CBRS_DataProduct_00dB_Attenuation.yml +++ b/src/scos_tekrsa/configs/actions-500-600/CBRS_DataProduct_00dB_Attenuation.yml @@ -6,8 +6,8 @@ nasctn_sea_data_product: iir_gstop_dB: 40 # Minimum stopband attenuation iir_pb_edge_Hz: 5e6 # Passband edge frequency iir_sb_edge_Hz: 5.008e6 # Stopband edge frequency -# Mean/Max FFT settings - nffts: 64e3 +# FFT settings + nffts: 320e3 # PFP frame pfp_frame_period_ms: 10 # APD downsampling settings diff --git a/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_00dB_Attenuation.yml b/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_00dB_Attenuation.yml index 144e3e0..766fed1 100644 --- a/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_00dB_Attenuation.yml +++ b/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_00dB_Attenuation.yml @@ -6,8 +6,8 @@ nasctn_sea_data_product: iir_gstop_dB: 40 # Minimum stopband attenuation iir_pb_edge_Hz: 5e6 # Passband edge frequency iir_sb_edge_Hz: 5.008e6 # Stopband edge frequency -# Mean/Max FFT settings - nffts: 64e3 +# FFT settings + nffts: 320e3 # PFP frame pfp_frame_period_ms: 10 # APD downsampling settings diff --git a/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_02dB_Attenuation.yml b/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_02dB_Attenuation.yml index 4c0f911..9f30fc8 100644 --- a/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_02dB_Attenuation.yml +++ b/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_02dB_Attenuation.yml @@ -6,8 +6,8 @@ nasctn_sea_data_product: iir_gstop_dB: 40 # Minimum stopband attenuation iir_pb_edge_Hz: 5e6 # Passband edge frequency iir_sb_edge_Hz: 5.008e6 # Stopband edge frequency -# Mean/Max FFT settings - nffts: 64e3 +# FFT settings + nffts: 320e3 # PFP frame pfp_frame_period_ms: 10 # APD downsampling settings diff --git a/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_04dB_Attenuation.yml b/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_04dB_Attenuation.yml index a6317b2..b1a9047 100644 --- a/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_04dB_Attenuation.yml +++ b/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_04dB_Attenuation.yml @@ -6,8 +6,8 @@ nasctn_sea_data_product: iir_gstop_dB: 40 # Minimum stopband attenuation iir_pb_edge_Hz: 5e6 # Passband edge frequency iir_sb_edge_Hz: 5.008e6 # Stopband edge frequency -# Mean/Max FFT settings - nffts: 64e3 +# FFT settings + nffts: 320e3 # PFP frame pfp_frame_period_ms: 10 # APD downsampling settings diff --git a/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_06dB_Attenuation.yml b/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_06dB_Attenuation.yml index 66120e4..456b355 100644 --- a/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_06dB_Attenuation.yml +++ b/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_06dB_Attenuation.yml @@ -6,8 +6,8 @@ nasctn_sea_data_product: iir_gstop_dB: 40 # Minimum stopband attenuation iir_pb_edge_Hz: 5e6 # Passband edge frequency iir_sb_edge_Hz: 5.008e6 # Stopband edge frequency -# Mean/Max FFT settings - nffts: 64e3 +# FFT settings + nffts: 320e3 # PFP frame pfp_frame_period_ms: 10 # APD downsampling settings diff --git a/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_08dB_Attenuation.yml b/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_08dB_Attenuation.yml index 255d23a..c0135e4 100644 --- a/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_08dB_Attenuation.yml +++ b/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_08dB_Attenuation.yml @@ -6,8 +6,8 @@ nasctn_sea_data_product: iir_gstop_dB: 40 # Minimum stopband attenuation iir_pb_edge_Hz: 5e6 # Passband edge frequency iir_sb_edge_Hz: 5.008e6 # Stopband edge frequency -# Mean/Max FFT settings - nffts: 64e3 +# FFT settings + nffts: 320e3 # PFP frame pfp_frame_period_ms: 10 # APD downsampling settings diff --git a/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_10dB_Attenuation.yml b/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_10dB_Attenuation.yml index 8b237e0..e5b6b8f 100644 --- a/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_10dB_Attenuation.yml +++ b/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_10dB_Attenuation.yml @@ -6,8 +6,8 @@ nasctn_sea_data_product: iir_gstop_dB: 40 # Minimum stopband attenuation iir_pb_edge_Hz: 5e6 # Passband edge frequency iir_sb_edge_Hz: 5.008e6 # Stopband edge frequency -# Mean/Max FFT settings - nffts: 64e3 +# FFT settings + nffts: 320e3 # PFP frame pfp_frame_period_ms: 10 # APD downsampling settings diff --git a/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_12dB_Attenuation.yml b/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_12dB_Attenuation.yml index 7319cca..dac5570 100644 --- a/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_12dB_Attenuation.yml +++ b/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_12dB_Attenuation.yml @@ -6,8 +6,8 @@ nasctn_sea_data_product: iir_gstop_dB: 40 # Minimum stopband attenuation iir_pb_edge_Hz: 5e6 # Passband edge frequency iir_sb_edge_Hz: 5.008e6 # Stopband edge frequency -# Mean/Max FFT settings - nffts: 64e3 +# FFT settings + nffts: 320e3 # PFP frame pfp_frame_period_ms: 10 # APD downsampling settings diff --git a/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_14dB_Attenuation.yml b/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_14dB_Attenuation.yml index 693b81a..26a4740 100644 --- a/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_14dB_Attenuation.yml +++ b/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_14dB_Attenuation.yml @@ -6,8 +6,8 @@ nasctn_sea_data_product: iir_gstop_dB: 40 # Minimum stopband attenuation iir_pb_edge_Hz: 5e6 # Passband edge frequency iir_sb_edge_Hz: 5.008e6 # Stopband edge frequency -# Mean/Max FFT settings - nffts: 64e3 +# FFT settings + nffts: 320e3 # PFP frame pfp_frame_period_ms: 10 # APD downsampling settings diff --git a/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_16dB_Attenuation.yml b/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_16dB_Attenuation.yml index 6a0b7fd..2c480b1 100644 --- a/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_16dB_Attenuation.yml +++ b/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_16dB_Attenuation.yml @@ -6,8 +6,8 @@ nasctn_sea_data_product: iir_gstop_dB: 40 # Minimum stopband attenuation iir_pb_edge_Hz: 5e6 # Passband edge frequency iir_sb_edge_Hz: 5.008e6 # Stopband edge frequency -# Mean/Max FFT settings - nffts: 64e3 +# FFT settings + nffts: 320e3 # PFP frame pfp_frame_period_ms: 10 # APD downsampling settings diff --git a/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_18dB_Attenuation.yml b/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_18dB_Attenuation.yml index 039bab8..210e601 100644 --- a/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_18dB_Attenuation.yml +++ b/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_18dB_Attenuation.yml @@ -6,8 +6,8 @@ nasctn_sea_data_product: iir_gstop_dB: 40 # Minimum stopband attenuation iir_pb_edge_Hz: 5e6 # Passband edge frequency iir_sb_edge_Hz: 5.008e6 # Stopband edge frequency -# Mean/Max FFT settings - nffts: 64e3 +# FFT settings + nffts: 320e3 # PFP frame pfp_frame_period_ms: 10 # APD downsampling settings diff --git a/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_20dB_Attenuation.yml b/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_20dB_Attenuation.yml index 07913d6..eebe0c3 100644 --- a/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_20dB_Attenuation.yml +++ b/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_20dB_Attenuation.yml @@ -6,8 +6,8 @@ nasctn_sea_data_product: iir_gstop_dB: 40 # Minimum stopband attenuation iir_pb_edge_Hz: 5e6 # Passband edge frequency iir_sb_edge_Hz: 5.008e6 # Stopband edge frequency -# Mean/Max FFT settings - nffts: 64e3 +# FFT settings + nffts: 320e3 # PFP frame pfp_frame_period_ms: 10 # APD downsampling settings diff --git a/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_22dB_Attenuation.yml b/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_22dB_Attenuation.yml index fd35524..2d7f297 100644 --- a/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_22dB_Attenuation.yml +++ b/src/scos_tekrsa/configs/actions-500-600/CBRS_EXT_DataProduct_22dB_Attenuation.yml @@ -6,8 +6,8 @@ nasctn_sea_data_product: iir_gstop_dB: 40 # Minimum stopband attenuation iir_pb_edge_Hz: 5e6 # Passband edge frequency iir_sb_edge_Hz: 5.008e6 # Stopband edge frequency -# Mean/Max FFT settings - nffts: 64e3 +# FFT settings + nffts: 320e3 # PFP frame pfp_frame_period_ms: 10 # APD downsampling settings From aa42b9998d73931c1ad8ca92de30ad02312167d4 Mon Sep 17 00:00:00 2001 From: Doug Boulware Date: Wed, 3 Jan 2024 12:41:30 -0700 Subject: [PATCH 11/45] add no filter cal action for testing. --- .../configs/actions-500-600/NO_FILTER_CAL.yml | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 src/scos_tekrsa/configs/actions-500-600/NO_FILTER_CAL.yml diff --git a/src/scos_tekrsa/configs/actions-500-600/NO_FILTER_CAL.yml b/src/scos_tekrsa/configs/actions-500-600/NO_FILTER_CAL.yml new file mode 100644 index 0000000..a0767b6 --- /dev/null +++ b/src/scos_tekrsa/configs/actions-500-600/NO_FILTER_CAL.yml @@ -0,0 +1,38 @@ +y_factor_cal: + name: No_Filter_Cal + # Preselector configuration + cal_source_idx: 0 + temp_sensor_idx: 2 + noise_diode_on: noise_diode_on + noise_diode_off: noise_diode_off + # Signal Analyzer Settings + preamp_enable: True + reference_level: -25 + attenuation: 0 + sample_rate: 14e6 + duration_ms: 1000 + nskip: 0 + frequency: + - 3555e6 + - 3565e6 + - 3575e6 + - 3585e6 + - 3595e6 + - 3605e6 + - 3615e6 + - 3625e6 + - 3635e6 + - 3645e6 + - 3655e6 + - 3665e6 + - 3675e6 + - 3685e6 + - 3695e6 + # IIR Filter Settings: + # Optionally apply a low-pass IIR filter before Y-Factor + iir_apply: False + iir_gpass_dB: 0.1 + iir_gstop_dB: 40 + iir_pb_edge_Hz: 5e6 + iir_sb_edge_Hz: 5.008e6 + iir_num_response_frequencies: 1000 From b5b6d052ced54698d519225ca754b5394e46a33f Mon Sep 17 00:00:00 2001 From: Anthony Romaniello Date: Fri, 5 Jan 2024 14:03:55 -0500 Subject: [PATCH 12/45] Delete example calibration files --- .../configs/sensor_calibration_example.json | 255 ------------------ .../configs/sigan_calibration_example.json | 61 ----- 2 files changed, 316 deletions(-) delete mode 100644 src/scos_tekrsa/configs/sensor_calibration_example.json delete mode 100644 src/scos_tekrsa/configs/sigan_calibration_example.json diff --git a/src/scos_tekrsa/configs/sensor_calibration_example.json b/src/scos_tekrsa/configs/sensor_calibration_example.json deleted file mode 100644 index 8a01b1d..0000000 --- a/src/scos_tekrsa/configs/sensor_calibration_example.json +++ /dev/null @@ -1,255 +0,0 @@ -{ - "calibration_parameters": [ - "sample_rate", - "frequency", - "reference_level", - "preamp_enable", - "attenuation" - ], - "last_calibration_datetime": "1970-01-01T00:00:00.000000Z", - "calibration_data": { - "14000000.0":{ - "3545000000": { - "-25":{ - "true": { - "0": { - "datetime": "1970-01-01T00:00:00.000000Z", - "gain": 30.0, - "noise_figure": 5.0, - "1db_compression_point": -12.0, - "enbw": 15723428.858731967, - "temperature": 20.0 - } - } - } - }, - "3555000000":{ - "-25":{ - "true": { - "0": { - "datetime": "1970-01-01T00:00:00.000000Z", - "gain": 30.0, - "noise_figure": 5.0, - "1db_compression_point": -12.0, - "enbw": 15723428.858731967, - "temperature": 20.0 - } - } - } - }, - "3565000000":{ - "-25":{ - "true": { - "0": { - "datetime": "1970-01-01T00:00:00.000000Z", - "gain": 30.0, - "noise_figure": 5.0, - "1db_compression_point": -12.0, - "enbw": 15723428.858731967, - "temperature": 20.0 - } - } - } - }, - "3575000000": { - "-25":{ - "true": { - "0": { - "datetime": "1970-01-01T00:00:00.000000Z", - "gain": 30.0, - "noise_figure": 5.0, - "1db_compression_point": -12.0, - "enbw": 15723428.858731967, - "temperature": 20.0 - } - } - } - }, - "3585000000": { - "-25":{ - "true": { - "0": { - "datetime": "1970-01-01T00:00:00.000000Z", - "gain": 30.0, - "noise_figure": 5.0, - "1db_compression_point": -12.0, - "enbw": 15723428.858731967, - "temperature": 20.0 - } - } - } - }, - "3595000000": { - "-25":{ - "true": { - "0": { - "datetime": "1970-01-01T00:00:00.000000Z", - "gain": 30.0, - "noise_figure": 5.0, - "1db_compression_point": -12.0, - "enbw": 15723428.858731967, - "temperature": 20.0 - } - } - } - }, - "3605000000": { - "-25":{ - "true": { - "0": { - "datetime": "1970-01-01T00:00:00.000000Z", - "gain": 30.0, - "noise_figure": 5.0, - "1db_compression_point": -12.0, - "enbw": 15723428.858731967, - "temperature": 20.0 - } - } - } - }, - "3615000000": { - "-25":{ - "true": { - "0": { - "datetime": "1970-01-01T00:00:00.000000Z", - "gain": 30.0, - "noise_figure": 5.0, - "1db_compression_point": -12.0, - "enbw": 15723428.858731967, - "temperature": 20.0 - } - } - } - }, - "3625000000": { - "-25":{ - "true": { - "0": { - "datetime": "1970-01-01T00:00:00.000000Z", - "gain": 30.0, - "noise_figure": 5.0, - "1db_compression_point": -12.0, - "enbw": 15723428.858731967, - "temperature": 20.0 - } - } - } - }, - "3635000000": { - "-25":{ - "true": { - "0": { - "datetime": "1970-01-01T00:00:00.000000Z", - "gain": 30.0, - "noise_figure": 5.0, - "1db_compression_point": -12.0, - "enbw": 15723428.858731967, - "temperature": 20.0 - } - } - } - }, - "3645000000": { - "-25":{ - "true": { - "0": { - "datetime": "1970-01-01T00:00:00.000000Z", - "gain": 30.0, - "noise_figure": 5.0, - "1db_compression_point": -12.0, - "enbw": 15723428.858731967, - "temperature": 20.0 - } - } - } - }, - "3655000000": { - "-25":{ - "true": { - "0": { - "datetime": "1970-01-01T00:00:00.000000Z", - "gain": 30.0, - "noise_figure": 5.0, - "1db_compression_point": -12.0, - "enbw": 15723428.858731967, - "temperature": 20.0 - } - } - } - }, - "3665000000": { - "-25":{ - "true": { - "0": { - "datetime": "1970-01-01T00:00:00.000000Z", - "gain": 30.0, - "noise_figure": 5.0, - "1db_compression_point": -12.0, - "enbw": 15723428.858731967, - "temperature": 20.0 - } - } - } - }, - "3675000000": { - "-25":{ - "true": { - "0": { - "datetime": "1970-01-01T00:00:00.000000Z", - "gain": 30.0, - "noise_figure": 5.0, - "1db_compression_point": -12.0, - "enbw": 15723428.858731967, - "temperature": 20.0 - } - } - } - }, - "3685000000": { - "-25":{ - "true": { - "0": { - "datetime": "1970-01-01T00:00:00.000000Z", - "gain": 30.0, - "noise_figure": 5.0, - "1db_compression_point": -12.0, - "enbw": 15723428.858731967, - "temperature": 20.0 - } - } - } - }, - "3695000000": { - "-25":{ - "true": { - "0": { - "datetime": "1970-01-01T00:00:00.000000Z", - "gain": 30.0, - "noise_figure": 5.0, - "1db_compression_point": -12.0, - "enbw": 15723428.858731967, - "temperature": 20.0 - } - } - } - }, - "3705000000": { - "-25":{ - "true": { - "0": { - "datetime": "1970-01-01T00:00:00.000000Z", - "gain": 30.0, - "noise_figure": 5.0, - "1db_compression_point": -12.0, - "enbw": 15723428.858731967, - "temperature": 20.0 - } - } - } - } - } - }, - "clock_rate_lookup_by_sample_rate": [], - "calibration_frequency_divisions": [], - "sensor_uid": "EXAMPLE" -} diff --git a/src/scos_tekrsa/configs/sigan_calibration_example.json b/src/scos_tekrsa/configs/sigan_calibration_example.json deleted file mode 100644 index 9d017ba..0000000 --- a/src/scos_tekrsa/configs/sigan_calibration_example.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "calibration_parameters": [ - "sample_rate", - "frequency", - "reference_level", - "preamp_enable", - "attenuation" - ], - "last_calibration_datetime": "1970-01-01T00:00:00.000000Z", - "calibration_data": { - "14000000.0":{ - "3555000000":{ - "-25":{ - "true": { - "0": { - "datetime": "1970-01-01T00:00:00.000000Z", - "gain": 30.0, - "noise_figure": 5.0, - "1db_compression_point": -12.0, - "enbw": 15723428.858731967, - "temperature": 20.0 - }, - "5": { - "datetime": "1970-01-01T00:00:00.000000Z", - "gain": 30.0, - "noise_figure": 5.0, - "1db_compression_point": -12.0, - "enbw": 15723428.858731967, - "temperature": 20.0 - } - } - } - }, - "3565000000":{ - "-25":{ - "true": { - "0": { - "datetime": "1970-01-01T00:00:00.000000Z", - "gain": 30.0, - "noise_figure": 5.0, - "1db_compression_point": -12.0, - "enbw": 15723428.858731967, - "temperature": 20.0 - }, - "5": { - "datetime": "1970-01-01T00:00:00.000000Z", - "gain": 30.0, - "noise_figure": 5.0, - "1db_compression_point": -12.0, - "enbw": 15723428.858731967, - "temperature": 20.0 - } - } - } - } - } - }, - "clock_rate_lookup_by_sample_rate": [], - "calibration_frequency_divisions": [], - "sigan_uid": "EXAMPLE" -} From 21dcf3b3ccf6aa7fd8689e9b9e814284dd1ed11f Mon Sep 17 00:00:00 2001 From: Doug Boulware Date: Tue, 9 Jan 2024 10:30:29 -0700 Subject: [PATCH 13/45] actions branch --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index d175665..8b0be69 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,7 +41,7 @@ classifiers = [ dependencies = [ "environs>=9.5.0", "tekrsa-api-wrap>=1.3.2", - "scos_actions @ git+https://github.com/NTIA/scos-actions@empty_calibration_params", + "scos_actions @ git+https://github.com/NTIA/scos-actions@master", ] [project.optional-dependencies] From f6a08c609831d796b944f6b6cc8cb60e7647e754 Mon Sep 17 00:00:00 2001 From: Doug Boulware Date: Thu, 11 Jan 2024 16:21:39 -0700 Subject: [PATCH 14/45] expose signal_analyzer in discover. --- pyproject.toml | 2 +- src/scos_tekrsa/discover/__init__.py | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 8b0be69..f808779 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,7 +41,7 @@ classifiers = [ dependencies = [ "environs>=9.5.0", "tekrsa-api-wrap>=1.3.2", - "scos_actions @ git+https://github.com/NTIA/scos-actions@master", + "scos_actions @ git+https://github.com/NTIA/scos-actions@discover_action_types", ] [project.optional-dependencies] diff --git a/src/scos_tekrsa/discover/__init__.py b/src/scos_tekrsa/discover/__init__.py index c5ce5d6..0f3ba02 100644 --- a/src/scos_tekrsa/discover/__init__.py +++ b/src/scos_tekrsa/discover/__init__.py @@ -11,7 +11,9 @@ actions = {} logger.debug("scos-tekrsa: discovering actions") # Adjust ACTION_DEFINITIONS_DIR for specific Tektronix analyzer in use +signal_analyzer = None if sigan: + signal_analyzer = sigan logger.debug(f"Device Name: {sigan.device_name}") if sigan.device_name in ["RSA306B", "RSA306"]: ACTION_DEFINITIONS_DIR = CONFIG_DIR / "actions-300" From b686c7ce79a2c5570105c26bc57c49a786b8471f Mon Sep 17 00:00:00 2001 From: Doug Boulware Date: Fri, 12 Jan 2024 06:54:36 -0700 Subject: [PATCH 15/45] Only load actions in discover. Use a setting for the device model. --- src/scos_tekrsa/discover/__init__.py | 64 ++++++++++++---------------- src/scos_tekrsa/settings.py | 1 + 2 files changed, 28 insertions(+), 37 deletions(-) diff --git a/src/scos_tekrsa/discover/__init__.py b/src/scos_tekrsa/discover/__init__.py index 0f3ba02..8b2d194 100644 --- a/src/scos_tekrsa/discover/__init__.py +++ b/src/scos_tekrsa/discover/__init__.py @@ -2,49 +2,39 @@ from scos_actions.actions.monitor_sigan import MonitorSignalAnalyzer from scos_actions.discover import init - -from scos_tekrsa.hardware import sigan from scos_tekrsa.settings import CONFIG_DIR +from scos_tekrsa.settings import DEVICE_MODEL logger = logging.getLogger(__name__) actions = {} logger.debug("scos-tekrsa: discovering actions") # Adjust ACTION_DEFINITIONS_DIR for specific Tektronix analyzer in use -signal_analyzer = None -if sigan: - signal_analyzer = sigan - logger.debug(f"Device Name: {sigan.device_name}") - if sigan.device_name in ["RSA306B", "RSA306"]: - ACTION_DEFINITIONS_DIR = CONFIG_DIR / "actions-300" - elif sigan.device_name in [ - "RSA503A", - "RSA507A", - "RSA513A", - "RSA518A", - "RSA603A", - "RSA607A", - ]: - ACTION_DEFINITIONS_DIR = CONFIG_DIR / "actions-500-600" - else: - logger.error( - "Unable to determine RSA model. Defaulting to use RSA500/600 action configs" - ) - ACTION_DEFINITIONS_DIR = CONFIG_DIR / "actions-500-600" - logger.debug(f"Action configs directory: {ACTION_DEFINITIONS_DIR}") - actions["monitor_tekrsa"] = MonitorSignalAnalyzer( - parameters={"name": "monitor_tekrsa"}, sigan=sigan - ) - logger.debug("Created Monitor SIGAN action") - # Pass new radio to existing action classes with new SDR specific yaml files - logger.debug("Initializing yaml actions") - yaml_actions, yaml_test_actions = init(sigan=sigan, yaml_dir=ACTION_DEFINITIONS_DIR) - logger.debug(f"Created {len(yaml_actions)} actions") - actions.update(yaml_actions) +logger.debug(f"Device Model: {DEVICE_MODEL}") +if DEVICE_MODEL in ["RSA306B", "RSA306"]: + ACTION_DEFINITIONS_DIR = CONFIG_DIR / "actions-300" +elif DEVICE_MODEL in [ + "RSA503A", + "RSA507A", + "RSA513A", + "RSA518A", + "RSA603A", + "RSA607A", +]: + ACTION_DEFINITIONS_DIR = CONFIG_DIR / "actions-500-600" else: - logger.warning("Sigan is None") - + logger.error( + "Unable to determine RSA model. Defaulting to use RSA500/600 action configs" + ) + ACTION_DEFINITIONS_DIR = CONFIG_DIR / "actions-500-600" +logger.debug(f"Action configs directory: {ACTION_DEFINITIONS_DIR}") +actions["monitor_tekrsa"] = MonitorSignalAnalyzer( + parameters={"name": "monitor_tekrsa"} +) +logger.debug("Created Monitor SIGAN action") +# Pass new radio to existing action classes with new SDR specific yaml files +logger.debug("Initializing yaml actions") +yaml_actions, yaml_test_actions = init( yaml_dir=ACTION_DEFINITIONS_DIR) +logger.debug(f"Created {len(yaml_actions)} actions") +actions.update(yaml_actions) -# Support status endpoint -def get_last_calibration_time(): - return sigan.last_calibration_time diff --git a/src/scos_tekrsa/settings.py b/src/scos_tekrsa/settings.py index f01878b..246b4a5 100644 --- a/src/scos_tekrsa/settings.py +++ b/src/scos_tekrsa/settings.py @@ -13,6 +13,7 @@ __cmd = Path(sys.argv[0]).name RUNNING_TESTS = "test" in __cmd +DEVICE_MODEL = env("DEVICE_MODEL", default="RSA507A") if not settings.configured or not hasattr(settings, "MOCK_SIGAN"): MOCK_SIGAN = env.bool("MOCK_SIGAN", default=False) or RUNNING_TESTS From 7eaf91361c162f3b66dedf83a9a763bdc9b22de4 Mon Sep 17 00:00:00 2001 From: Doug Boulware Date: Fri, 12 Jan 2024 10:14:04 -0700 Subject: [PATCH 16/45] Don't create sigan. --- src/scos_tekrsa/hardware/__init__.py | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/scos_tekrsa/hardware/__init__.py b/src/scos_tekrsa/hardware/__init__.py index 8c1d763..8b13789 100644 --- a/src/scos_tekrsa/hardware/__init__.py +++ b/src/scos_tekrsa/hardware/__init__.py @@ -1,16 +1 @@ -import logging -from scos_actions.signals import register_component_with_status - -from scos_tekrsa.hardware.tekrsa_sigan import TekRSASigan - -logger = logging.getLogger(__name__) -try: - logger.debug( - "*********************Creating TekRSASigan******************************" - ) - sigan = TekRSASigan() - register_component_with_status.send(sigan, component=sigan) -except Exception as err: - logger.error(f"Unable to create TekRSASigan: {err}") - sigan = None From a83cf3dcdabdb2cdf35693855464c120a2aef512 Mon Sep 17 00:00:00 2001 From: Doug Boulware Date: Sat, 13 Jan 2024 15:30:18 -0700 Subject: [PATCH 17/45] optional cals in sigan constructor. --- src/scos_tekrsa/hardware/tekrsa_sigan.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/scos_tekrsa/hardware/tekrsa_sigan.py b/src/scos_tekrsa/hardware/tekrsa_sigan.py index 77d46b6..d54ae5e 100644 --- a/src/scos_tekrsa/hardware/tekrsa_sigan.py +++ b/src/scos_tekrsa/hardware/tekrsa_sigan.py @@ -2,6 +2,7 @@ import threading from scos_actions import utils +from scos_actions.calibration.calibration import Calibration from scos_actions.hardware.sigan_iface import ( SignalAnalyzerInterface, sensor_calibration, @@ -18,9 +19,9 @@ class TekRSASigan(SignalAnalyzerInterface): - def __init__(self): + def __init__(self, sensor_cal: Calibration = None, sigan_cal: Calibration = None): try: - super().__init__() + super().__init__(sensor_cal, sigan_cal) logger.debug("Initializing Tektronix RSA Signal Analyzer") self._plugin_version = SCOS_TEKRSA_VERSION From 2b557c6a6361321cadd2e5831d6c055b96494725 Mon Sep 17 00:00:00 2001 From: Doug Boulware Date: Sat, 13 Jan 2024 17:00:35 -0700 Subject: [PATCH 18/45] remove bad import and use self.sensor_calibration. --- src/scos_tekrsa/hardware/tekrsa_sigan.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/scos_tekrsa/hardware/tekrsa_sigan.py b/src/scos_tekrsa/hardware/tekrsa_sigan.py index d54ae5e..00af736 100644 --- a/src/scos_tekrsa/hardware/tekrsa_sigan.py +++ b/src/scos_tekrsa/hardware/tekrsa_sigan.py @@ -4,8 +4,7 @@ from scos_actions import utils from scos_actions.calibration.calibration import Calibration from scos_actions.hardware.sigan_iface import ( - SignalAnalyzerInterface, - sensor_calibration, + SignalAnalyzerInterface ) import scos_tekrsa.hardware.tekrsa_constants as rsa_constants @@ -291,7 +290,7 @@ def acquire_time_domain_samples( if cal_adjust: # Get calibration data for acquisition if not (settings.RUNNING_TESTS or settings.MOCK_SIGAN): - cal_params = sensor_calibration.calibration_parameters + cal_params = self.sensor_calibration.calibration_parameters else: # Make it work for mock sigan/testing. Just match frequency. cal_params = [vars(self)["_frequency"]] From dfefabfad5c18ed60c03e54c7929bdfa08fc6f1a Mon Sep 17 00:00:00 2001 From: Doug Boulware Date: Thu, 18 Jan 2024 10:58:04 -0700 Subject: [PATCH 19/45] Add optional switches dictionary to TekRSASigan and pass to power_cycle. --- src/scos_tekrsa/hardware/tekrsa_sigan.py | 9 +++++---- src/scos_tekrsa/settings.py | 15 +++------------ 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/src/scos_tekrsa/hardware/tekrsa_sigan.py b/src/scos_tekrsa/hardware/tekrsa_sigan.py index 00af736..16155d2 100644 --- a/src/scos_tekrsa/hardware/tekrsa_sigan.py +++ b/src/scos_tekrsa/hardware/tekrsa_sigan.py @@ -1,6 +1,7 @@ import logging import threading - +from typing import Dict,Optional +from its_preselector.web_relay import WebRelay from scos_actions import utils from scos_actions.calibration.calibration import Calibration from scos_actions.hardware.sigan_iface import ( @@ -18,9 +19,9 @@ class TekRSASigan(SignalAnalyzerInterface): - def __init__(self, sensor_cal: Calibration = None, sigan_cal: Calibration = None): + def __init__(self, sensor_cal: Calibration = None, sigan_cal: Calibration = None, switches: Optional[Dict[str, WebRelay]] = None ): try: - super().__init__(sensor_cal, sigan_cal) + super().__init__(sensor_cal, sigan_cal, switches) logger.debug("Initializing Tektronix RSA Signal Analyzer") self._plugin_version = SCOS_TEKRSA_VERSION @@ -52,7 +53,7 @@ def __init__(self, sensor_cal: Calibration = None, sigan_cal: Calibration = None logger.error( f"Unable to initialize sigan: {error}.\nAttempting to power cycle and reconnect..." ) - self.power_cycle_and_connect() + self.power_cycle_and_connect(self.switches) def get_constraints(self): self.min_frequency = self.rsa.CONFIG_GetMinCenterFreq() diff --git a/src/scos_tekrsa/settings.py b/src/scos_tekrsa/settings.py index 246b4a5..ca04483 100644 --- a/src/scos_tekrsa/settings.py +++ b/src/scos_tekrsa/settings.py @@ -1,8 +1,6 @@ import logging import sys from pathlib import Path - -from django.conf import settings from environs import Env from scos_actions.settings import * @@ -14,15 +12,8 @@ RUNNING_TESTS = "test" in __cmd DEVICE_MODEL = env("DEVICE_MODEL", default="RSA507A") +MOCK_SIGAN = env.bool("MOCK_SIGAN", default=False) or RUNNING_TESTS +MOCK_SIGAN_RANDOM = env.bool("MOCK_SIGAN_RANDOM", default=False) -if not settings.configured or not hasattr(settings, "MOCK_SIGAN"): - MOCK_SIGAN = env.bool("MOCK_SIGAN", default=False) or RUNNING_TESTS -else: - MOCK_SIGAN = settings.MOCK_SIGAN -if not settings.configured or not hasattr(settings, "MOCK_SIGAN_RANDOM"): - MOCK_SIGAN_RANDOM = env.bool("MOCK_SIGAN_RANDOM", default=False) -else: - MOCK_SIGAN_RANDOM = settings.MOCK_SIGAN_RANDOM - -if not settings.configured: +if RUNNING_TESTS: logging.basicConfig(level=logging.DEBUG) From 01990544e087114435151362e81969b066366ee3 Mon Sep 17 00:00:00 2001 From: Doug Boulware Date: Thu, 18 Jan 2024 11:31:08 -0700 Subject: [PATCH 20/45] remove switches from power_cycle_and_connect call. --- src/scos_tekrsa/hardware/tekrsa_sigan.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scos_tekrsa/hardware/tekrsa_sigan.py b/src/scos_tekrsa/hardware/tekrsa_sigan.py index 16155d2..3d3dd28 100644 --- a/src/scos_tekrsa/hardware/tekrsa_sigan.py +++ b/src/scos_tekrsa/hardware/tekrsa_sigan.py @@ -53,7 +53,7 @@ def __init__(self, sensor_cal: Calibration = None, sigan_cal: Calibration = None logger.error( f"Unable to initialize sigan: {error}.\nAttempting to power cycle and reconnect..." ) - self.power_cycle_and_connect(self.switches) + self.power_cycle_and_connect() def get_constraints(self): self.min_frequency = self.rsa.CONFIG_GetMinCenterFreq() From 79f71b5de75f60be7b105dc16402b768f5093bd7 Mon Sep 17 00:00:00 2001 From: Doug Boulware Date: Thu, 18 Jan 2024 14:14:06 -0700 Subject: [PATCH 21/45] Instantiate signal_analyzer and expose in discover if not running migrations. --- src/scos_tekrsa/discover/__init__.py | 3 ++- src/scos_tekrsa/hardware/__init__.py | 14 ++++++++++++++ src/scos_tekrsa/settings.py | 2 +- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/scos_tekrsa/discover/__init__.py b/src/scos_tekrsa/discover/__init__.py index 8b2d194..ff6c6a9 100644 --- a/src/scos_tekrsa/discover/__init__.py +++ b/src/scos_tekrsa/discover/__init__.py @@ -2,6 +2,7 @@ from scos_actions.actions.monitor_sigan import MonitorSignalAnalyzer from scos_actions.discover import init +from scos_tekrsa.hardware import sigan from scos_tekrsa.settings import CONFIG_DIR from scos_tekrsa.settings import DEVICE_MODEL @@ -37,4 +38,4 @@ yaml_actions, yaml_test_actions = init( yaml_dir=ACTION_DEFINITIONS_DIR) logger.debug(f"Created {len(yaml_actions)} actions") actions.update(yaml_actions) - +signal_analyzer = sigan diff --git a/src/scos_tekrsa/hardware/__init__.py b/src/scos_tekrsa/hardware/__init__.py index 8b13789..9b222d4 100644 --- a/src/scos_tekrsa/hardware/__init__.py +++ b/src/scos_tekrsa/hardware/__init__.py @@ -1 +1,15 @@ +import logging +from scos_tekrsa.hardware.tekrsa_sigan import TekRSASigan +from scos_tekrsa import settings + +logger = logging.getLogger(__name__) +try: + if not settings.RUNNING_MIGRATIONS: + logger.debug( + "*********************Creating TekRSASigan******************************" + ) + sigan = TekRSASigan() +except Exception as err: + logger.error(f"Unable to create TekRSASigan: {err}") + sigan = None diff --git a/src/scos_tekrsa/settings.py b/src/scos_tekrsa/settings.py index ca04483..fe8f00c 100644 --- a/src/scos_tekrsa/settings.py +++ b/src/scos_tekrsa/settings.py @@ -14,6 +14,6 @@ DEVICE_MODEL = env("DEVICE_MODEL", default="RSA507A") MOCK_SIGAN = env.bool("MOCK_SIGAN", default=False) or RUNNING_TESTS MOCK_SIGAN_RANDOM = env.bool("MOCK_SIGAN_RANDOM", default=False) - +RUNNING_MIGRATIONS = env.bool("RUNNING_MIGRATIONS", default=False) if RUNNING_TESTS: logging.basicConfig(level=logging.DEBUG) From a9a69863d9bb8a8180d956d0d09604b9447608f6 Mon Sep 17 00:00:00 2001 From: Doug Boulware Date: Thu, 18 Jan 2024 14:30:11 -0700 Subject: [PATCH 22/45] set sigan to None when running migration. --- src/scos_tekrsa/hardware/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/scos_tekrsa/hardware/__init__.py b/src/scos_tekrsa/hardware/__init__.py index 9b222d4..8e8b3c8 100644 --- a/src/scos_tekrsa/hardware/__init__.py +++ b/src/scos_tekrsa/hardware/__init__.py @@ -10,6 +10,8 @@ "*********************Creating TekRSASigan******************************" ) sigan = TekRSASigan() + else: + sigan = None except Exception as err: logger.error(f"Unable to create TekRSASigan: {err}") sigan = None From effd540cd9e07837139fca5f95d140da21c42194 Mon Sep 17 00:00:00 2001 From: Doug Boulware Date: Thu, 18 Jan 2024 15:01:08 -0700 Subject: [PATCH 23/45] log running migrations. --- src/scos_tekrsa/hardware/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/scos_tekrsa/hardware/__init__.py b/src/scos_tekrsa/hardware/__init__.py index 8e8b3c8..c080cbc 100644 --- a/src/scos_tekrsa/hardware/__init__.py +++ b/src/scos_tekrsa/hardware/__init__.py @@ -11,6 +11,7 @@ ) sigan = TekRSASigan() else: + logger.debug("Running migrations. Not creating signal analyzer.") sigan = None except Exception as err: logger.error(f"Unable to create TekRSASigan: {err}") From 8237df5f4190a35c57d087a93397ee7c001b58ab Mon Sep 17 00:00:00 2001 From: Doug Boulware Date: Thu, 18 Jan 2024 16:32:08 -0700 Subject: [PATCH 24/45] load switches before creating tekrsa. --- src/scos_tekrsa/discover/__init__.py | 1 + src/scos_tekrsa/hardware/__init__.py | 5 ++++- src/scos_tekrsa/settings.py | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/scos_tekrsa/discover/__init__.py b/src/scos_tekrsa/discover/__init__.py index ff6c6a9..7591413 100644 --- a/src/scos_tekrsa/discover/__init__.py +++ b/src/scos_tekrsa/discover/__init__.py @@ -38,4 +38,5 @@ yaml_actions, yaml_test_actions = init( yaml_dir=ACTION_DEFINITIONS_DIR) logger.debug(f"Created {len(yaml_actions)} actions") actions.update(yaml_actions) +logger.debug(f"signal_analyzer: {sigan}") signal_analyzer = sigan diff --git a/src/scos_tekrsa/hardware/__init__.py b/src/scos_tekrsa/hardware/__init__.py index c080cbc..68f41a0 100644 --- a/src/scos_tekrsa/hardware/__init__.py +++ b/src/scos_tekrsa/hardware/__init__.py @@ -1,5 +1,6 @@ import logging +from scos_actions.hardware.utils import load_switches from scos_tekrsa.hardware.tekrsa_sigan import TekRSASigan from scos_tekrsa import settings @@ -9,7 +10,9 @@ logger.debug( "*********************Creating TekRSASigan******************************" ) - sigan = TekRSASigan() + logger.debug("Tekrsa: loading switches") + switches = load_switches(settings.SWITCH_CONFIGS_DIR) + sigan = TekRSASigan(switches = switches) else: logger.debug("Running migrations. Not creating signal analyzer.") sigan = None diff --git a/src/scos_tekrsa/settings.py b/src/scos_tekrsa/settings.py index fe8f00c..2208381 100644 --- a/src/scos_tekrsa/settings.py +++ b/src/scos_tekrsa/settings.py @@ -15,5 +15,6 @@ MOCK_SIGAN = env.bool("MOCK_SIGAN", default=False) or RUNNING_TESTS MOCK_SIGAN_RANDOM = env.bool("MOCK_SIGAN_RANDOM", default=False) RUNNING_MIGRATIONS = env.bool("RUNNING_MIGRATIONS", default=False) +SWITCH_CONFIGS_DIR = Path(env.str("SWITCH_CONFIGS_DIR")) if RUNNING_TESTS: logging.basicConfig(level=logging.DEBUG) From 67fe1592a7be26f07af8fd52c817e6f61da609e3 Mon Sep 17 00:00:00 2001 From: Doug Boulware Date: Thu, 18 Jan 2024 16:52:52 -0700 Subject: [PATCH 25/45] Don't create sigan. --- src/scos_tekrsa/discover/__init__.py | 1 - src/scos_tekrsa/hardware/__init__.py | 21 --------------------- 2 files changed, 22 deletions(-) diff --git a/src/scos_tekrsa/discover/__init__.py b/src/scos_tekrsa/discover/__init__.py index 7591413..f31d321 100644 --- a/src/scos_tekrsa/discover/__init__.py +++ b/src/scos_tekrsa/discover/__init__.py @@ -2,7 +2,6 @@ from scos_actions.actions.monitor_sigan import MonitorSignalAnalyzer from scos_actions.discover import init -from scos_tekrsa.hardware import sigan from scos_tekrsa.settings import CONFIG_DIR from scos_tekrsa.settings import DEVICE_MODEL diff --git a/src/scos_tekrsa/hardware/__init__.py b/src/scos_tekrsa/hardware/__init__.py index 68f41a0..e69de29 100644 --- a/src/scos_tekrsa/hardware/__init__.py +++ b/src/scos_tekrsa/hardware/__init__.py @@ -1,21 +0,0 @@ -import logging - -from scos_actions.hardware.utils import load_switches -from scos_tekrsa.hardware.tekrsa_sigan import TekRSASigan -from scos_tekrsa import settings - -logger = logging.getLogger(__name__) -try: - if not settings.RUNNING_MIGRATIONS: - logger.debug( - "*********************Creating TekRSASigan******************************" - ) - logger.debug("Tekrsa: loading switches") - switches = load_switches(settings.SWITCH_CONFIGS_DIR) - sigan = TekRSASigan(switches = switches) - else: - logger.debug("Running migrations. Not creating signal analyzer.") - sigan = None -except Exception as err: - logger.error(f"Unable to create TekRSASigan: {err}") - sigan = None From 3ae55c5070394b21db55089eaaa6cae596a529a2 Mon Sep 17 00:00:00 2001 From: Doug Boulware Date: Fri, 19 Jan 2024 07:07:12 -0700 Subject: [PATCH 26/45] Return to not initializing sigan for testing. --- src/scos_tekrsa/discover/__init__.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/scos_tekrsa/discover/__init__.py b/src/scos_tekrsa/discover/__init__.py index f31d321..8b2d194 100644 --- a/src/scos_tekrsa/discover/__init__.py +++ b/src/scos_tekrsa/discover/__init__.py @@ -37,5 +37,4 @@ yaml_actions, yaml_test_actions = init( yaml_dir=ACTION_DEFINITIONS_DIR) logger.debug(f"Created {len(yaml_actions)} actions") actions.update(yaml_actions) -logger.debug(f"signal_analyzer: {sigan}") -signal_analyzer = sigan + From eb6c70cd129a745caa25f1b8765085f4f7c3b2e3 Mon Sep 17 00:00:00 2001 From: Anthony Romaniello Date: Mon, 22 Jan 2024 15:41:18 -0500 Subject: [PATCH 27/45] remove sigan calibration --- src/scos_tekrsa/hardware/tekrsa_sigan.py | 20 +++++++++++--------- tests/test_calibration.py | 17 +---------------- 2 files changed, 12 insertions(+), 25 deletions(-) diff --git a/src/scos_tekrsa/hardware/tekrsa_sigan.py b/src/scos_tekrsa/hardware/tekrsa_sigan.py index 3d3dd28..848031a 100644 --- a/src/scos_tekrsa/hardware/tekrsa_sigan.py +++ b/src/scos_tekrsa/hardware/tekrsa_sigan.py @@ -1,12 +1,11 @@ import logging import threading -from typing import Dict,Optional +from typing import Dict, Optional + from its_preselector.web_relay import WebRelay from scos_actions import utils from scos_actions.calibration.calibration import Calibration -from scos_actions.hardware.sigan_iface import ( - SignalAnalyzerInterface -) +from scos_actions.hardware.sigan_iface import SignalAnalyzerInterface import scos_tekrsa.hardware.tekrsa_constants as rsa_constants from scos_tekrsa import __version__ as SCOS_TEKRSA_VERSION @@ -19,9 +18,13 @@ class TekRSASigan(SignalAnalyzerInterface): - def __init__(self, sensor_cal: Calibration = None, sigan_cal: Calibration = None, switches: Optional[Dict[str, WebRelay]] = None ): + def __init__( + self, + sensor_cal: Calibration = None, + switches: Optional[Dict[str, WebRelay]] = None, + ): try: - super().__init__(sensor_cal, sigan_cal, switches) + super().__init__(sensor_cal, switches) logger.debug("Initializing Tektronix RSA Signal Analyzer") self._plugin_version = SCOS_TEKRSA_VERSION @@ -45,7 +48,6 @@ def __init__(self, sensor_cal: Calibration = None, sigan_cal: Calibration = None self.min_frequency = None self.sensor_calibration_data = None - self.sigan_calibration_data = None self._capture_time = None self.connect() @@ -117,12 +119,12 @@ def is_available(self) -> bool: def plugin_version(self) -> str: """Returns the current version of scos-tekrsa.""" return self._plugin_version - + @property def firmware_version(self) -> str: """Returns the current firmware version of the connected RSA device.""" return self._firmware_version - + @property def api_version(self) -> str: """Returns the version of the Tektronix RSA API for Linux currently in use.""" diff --git a/tests/test_calibration.py b/tests/test_calibration.py index 677e32a..273f1cd 100644 --- a/tests/test_calibration.py +++ b/tests/test_calibration.py @@ -1,25 +1,10 @@ import pytest -from scos_actions.calibration import get_sensor_calibration, get_sigan_calibration +from scos_actions.calibration import get_sensor_calibration from scos_tekrsa.settings import CONFIG_DIR class TestCalibration: - def test_sigan_calibration(self): - sigan_calibration = get_sigan_calibration( - CONFIG_DIR / "sigan_calibration_example.json" - ) - assert sigan_calibration is not None - assert isinstance(sigan_calibration.calibration_data, dict) - assert isinstance(sigan_calibration.last_calibration_datetime, str) - assert isinstance(sigan_calibration.calibration_parameters, list) - assert ( - sigan_calibration.calibration_data["14000000.0"]["3555000000"]["-25"][ - "true" - ]["0"]["noise_figure"] - == 5.0 - ) - def test_sensor_calibration(self): sensor_calibration = get_sensor_calibration( CONFIG_DIR / "sensor_calibration_example.json" From bf5fd9fba5b30f24b9060de40bfa60f81546193f Mon Sep 17 00:00:00 2001 From: Anthony Romaniello Date: Mon, 22 Jan 2024 15:41:49 -0500 Subject: [PATCH 28/45] update scos-actions branch for testing --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index f808779..5486982 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,7 +41,7 @@ classifiers = [ dependencies = [ "environs>=9.5.0", "tekrsa-api-wrap>=1.3.2", - "scos_actions @ git+https://github.com/NTIA/scos-actions@discover_action_types", + "scos_actions @ git+https://github.com/NTIA/scos-actions@calibrate_to_antenna", ] [project.optional-dependencies] From 8f00d2c0c6fcaf20cb6be059b60ca3a3ce8e7396 Mon Sep 17 00:00:00 2001 From: Anthony Romaniello Date: Tue, 23 Jan 2024 20:22:56 -0500 Subject: [PATCH 29/45] remove sensor calibration and cal_adjust --- src/scos_tekrsa/hardware/tekrsa_sigan.py | 30 +----------------------- 1 file changed, 1 insertion(+), 29 deletions(-) diff --git a/src/scos_tekrsa/hardware/tekrsa_sigan.py b/src/scos_tekrsa/hardware/tekrsa_sigan.py index 848031a..c361823 100644 --- a/src/scos_tekrsa/hardware/tekrsa_sigan.py +++ b/src/scos_tekrsa/hardware/tekrsa_sigan.py @@ -4,7 +4,6 @@ from its_preselector.web_relay import WebRelay from scos_actions import utils -from scos_actions.calibration.calibration import Calibration from scos_actions.hardware.sigan_iface import SignalAnalyzerInterface import scos_tekrsa.hardware.tekrsa_constants as rsa_constants @@ -20,11 +19,10 @@ class TekRSASigan(SignalAnalyzerInterface): def __init__( self, - sensor_cal: Calibration = None, switches: Optional[Dict[str, WebRelay]] = None, ): try: - super().__init__(sensor_cal, switches) + super().__init__(switches) logger.debug("Initializing Tektronix RSA Signal Analyzer") self._plugin_version = SCOS_TEKRSA_VERSION @@ -47,7 +45,6 @@ def __init__( self.max_frequency = None self.min_frequency = None - self.sensor_calibration_data = None self._capture_time = None self.connect() @@ -276,7 +273,6 @@ def acquire_time_domain_samples( num_samples: int, num_samples_skip: int = 0, retries: int = 5, - cal_adjust: bool = True, ): """Acquire specific number of time-domain IQ samples.""" with sigan_lock: @@ -290,27 +286,6 @@ def acquire_time_domain_samples( nskip = int(num_samples_skip) # Requested number of samples to skip nsamps = nsamps_req + nskip # Total number of samples to collect - if cal_adjust: - # Get calibration data for acquisition - if not (settings.RUNNING_TESTS or settings.MOCK_SIGAN): - cal_params = self.sensor_calibration.calibration_parameters - else: - # Make it work for mock sigan/testing. Just match frequency. - cal_params = [vars(self)["_frequency"]] - try: - cal_args = [vars(self)[f"_{p}"] for p in cal_params] - except KeyError: - raise Exception( - "One or more required cal parameters is not a valid sigan setting." - ) - logger.debug(f"Matched calibration params: {cal_args}") - self.recompute_sensor_calibration_data(cal_args) - # Compute the linear gain - db_gain = self.sensor_calibration_data["gain"] - linear_gain = 10.0 ** (db_gain / 20.0) - else: - linear_gain = 1 - # Determine correct time length (round up, integer ms) durationMsec = int(1000 * (nsamps / self.sample_rate)) + ( 1000 * nsamps % self.sample_rate > 0 @@ -372,9 +347,6 @@ def acquire_time_domain_samples( logger.debug( f"IQ stream: successfully acquired {data_len} samples." ) - # Scale data to RF power and return - logger.debug(f"Applying gain of {linear_gain}") - data /= linear_gain measurement_result = { "data": data, From cfa7abbe96d09e2f1060cf9e240e81f21d06ba50 Mon Sep 17 00:00:00 2001 From: Anthony Romaniello Date: Mon, 29 Jan 2024 12:02:56 -0500 Subject: [PATCH 30/45] remove retry logic in acquire_time_domain_samples --- src/scos_tekrsa/hardware/tekrsa_sigan.py | 30 +++++------------------- 1 file changed, 6 insertions(+), 24 deletions(-) diff --git a/src/scos_tekrsa/hardware/tekrsa_sigan.py b/src/scos_tekrsa/hardware/tekrsa_sigan.py index c361823..84a35ed 100644 --- a/src/scos_tekrsa/hardware/tekrsa_sigan.py +++ b/src/scos_tekrsa/hardware/tekrsa_sigan.py @@ -272,7 +272,6 @@ def acquire_time_domain_samples( self, num_samples: int, num_samples_skip: int = 0, - retries: int = 5, ): """Acquire specific number of time-domain IQ samples.""" with sigan_lock: @@ -301,9 +300,6 @@ def acquire_time_domain_samples( logger.debug( f"acquire_time_domain_samples starting, num_samples = {nsamps}" ) - logger.debug(f"Number of retries = {retries}") - - max_retries = retries while True: self._capture_time = utils.get_datetime_str_now() @@ -320,29 +316,15 @@ def acquire_time_domain_samples( logger.debug("IQ stream: ADC overrange event occurred.") if "data loss" in status or "discontinuity" in status: # Invalid data - if retries > 0: - logger.info( - f"Data loss occurred during IQ streaming. Retrying {retries} more times." - ) - retries -= 1 - continue - else: - err = "Data loss occurred with no retries remaining." - err += f" (tried {max_retries} times.)" - raise RuntimeError(err) + msg = "Data loss occurred during IQ streaming" + logger.debug(msg) + raise RuntimeError(msg) elif ( not data_len == nsamps_req ): # Invalid data: incorrect number of samples - if retries > 0: - msg = f"RSA error: requested {nsamps_req + nskip} samples, but got {data_len}." - logger.debug(msg) - logger.debug(f"Retrying {retries} more times.") - retries -= 1 - continue - else: - err = "Failed to acquire correct number of samples " - err += f"{max_retries} times in a row." - raise RuntimeError(err) + msg = f"RSA error: requested {nsamps_req + nskip} samples, but got {data_len}." + logger.debug(msg) + raise RuntimeError(msg) else: logger.debug( f"IQ stream: successfully acquired {data_len} samples." From 19a02400da1f6e689882f5b5fe3cdce5763217fd Mon Sep 17 00:00:00 2001 From: Anthony Romaniello Date: Wed, 7 Feb 2024 12:38:25 -0500 Subject: [PATCH 31/45] Add newly-required instructions to README Adds mention of required environment variables and their correct values --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 079cd4d..289e766 100644 --- a/README.md +++ b/README.md @@ -86,10 +86,15 @@ file: cp env.template ./env ``` -1. In the newly-created `env` file, set the `BASE_IMAGE`: +1. In the newly-created `env` file, set the following environment variables: ```text + DEVICE_MODEL=RSA507A # Or 'RSA306B', 'RSA517A', etc. + # These are the same for all supported Tektronix RSA devices: BASE_IMAGE=ghcr.io/ntia/scos-tekrsa/tekrsa_usb:latest + USB_DEVICE=Tektronix + SIGAN_CLASS=TekRSASigan + SIGAN_MODULE=scos_tekrsa.hardware.tekrsa_sigan ``` 1. Get environment variables: From f80cac25612d2ce6208364d322dcf45ed9ad95da Mon Sep 17 00:00:00 2001 From: Anthony Romaniello Date: Tue, 12 Mar 2024 15:18:46 -0400 Subject: [PATCH 32/45] Add required parameter to calibration YAML --- .../configs/actions-500-600/SEA_CBRS_Calibrate_Baseline.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/scos_tekrsa/configs/actions-500-600/SEA_CBRS_Calibrate_Baseline.yml b/src/scos_tekrsa/configs/actions-500-600/SEA_CBRS_Calibrate_Baseline.yml index 39a85f9..c1bf9a7 100644 --- a/src/scos_tekrsa/configs/actions-500-600/SEA_CBRS_Calibrate_Baseline.yml +++ b/src/scos_tekrsa/configs/actions-500-600/SEA_CBRS_Calibrate_Baseline.yml @@ -1,5 +1,6 @@ y_factor_cal: name: SEA_CBRS_Calibrate_Baseline + reference_point: "noise source output" # Preselector configuration cal_source_idx: 0 temp_sensor_idx: 2 From 4c1c5030f80230badc22dc67e2abf14f5ff7c14e Mon Sep 17 00:00:00 2001 From: Anthony Romaniello Date: Tue, 12 Mar 2024 15:52:45 -0400 Subject: [PATCH 33/45] remove unit tests related to removed retry loop --- src/scos_tekrsa/hardware/mocks/rsa_block.py | 16 +------- tests/test_tekrsa_sigan.py | 44 +++------------------ 2 files changed, 7 insertions(+), 53 deletions(-) diff --git a/src/scos_tekrsa/hardware/mocks/rsa_block.py b/src/scos_tekrsa/hardware/mocks/rsa_block.py index d42e868..6d7ba3d 100644 --- a/src/scos_tekrsa/hardware/mocks/rsa_block.py +++ b/src/scos_tekrsa/hardware/mocks/rsa_block.py @@ -6,11 +6,6 @@ rng = np.random.default_rng() -# For testing IQ capture retry on failure, this parameter controls the -# number of times that the mocked IQSTREAM_Tempfile_NoConfig() will fail -# when run consecutively, before working. -TIMES_TO_FAIL = 3 - # Mock Signal Analyzer Constants DEVICE_NOMENCLATURE = "MOCK RSA507A" MIN_CENTER_FREQ = 9e3 @@ -30,8 +25,6 @@ class MockRSA: def __init__(self, randomize_values=False): # Simulate returning less than requested num samples - self.times_to_fail = TIMES_TO_FAIL - self.times_failed = 0 self.randomize_values = randomize_values # Initialize parameters @@ -107,10 +100,7 @@ def IQSTREAM_Tempfile_NoConfig(self, dur_msec, return_status): # Get n_samp from dur_msec n_samp = int((dur_msec / 1000) * self.IQSTREAM_GetAcqParameters()[1]) - if self.times_failed < self.times_to_fail: - self.times_failed += 1 - iq = np.ones(0, dtype=np.complex64) - elif self.randomize_values: + if self.randomize_values: i = rng.normal(0.5, 0.5, n_samp) q = rng.normal(0.5, 0.5, n_samp) rand_iq = np.empty(n_samp, dtype=np.complex64) @@ -127,10 +117,6 @@ def IQSTREAM_Tempfile_NoConfig(self, dur_msec, return_status): def IQSTREAM_Acquire(self, dur_msec, return_status): return self.IQSTREAM_Tempfile_NoConfig(dur_msec, return_status) - def set_times_to_fail(self, n): - self.times_to_fail = n - self.times_failed = 0 - def DEVICE_GetFWVersion(self): return "mock_rsa" diff --git a/tests/test_tekrsa_sigan.py b/tests/test_tekrsa_sigan.py index c464f89..38c8066 100644 --- a/tests/test_tekrsa_sigan.py +++ b/tests/test_tekrsa_sigan.py @@ -12,7 +12,6 @@ MAX_IQ_BW, MIN_CENTER_FREQ, MIN_IQ_BW, - TIMES_TO_FAIL, ) from scos_tekrsa.hardware.tekrsa_sigan import TekRSASigan @@ -156,34 +155,11 @@ def test_preamp_enable(self): assert self.rx.preamp_enable is None setattr(self.rx, "model", old_dev_name) - def test_acquire_samples_retry(self): - # Not enough retries = acquisition should fail - # The mocked IQ capture function will fail the first - # TIMES_TO_FAIL times it is called consecutively. - - # With retries=0, IQ capture should fail TIMES_TO_FAIL times - for i in range(TIMES_TO_FAIL): - with pytest.raises(RuntimeError): - _ = self.rx.acquire_time_domain_samples( - 100, retries=0, cal_adjust=False - ) - - # With retries>TIMES_TO_FAIL, IQ capture should succeed - # In this case, IQ capture fails TIMES_TO_FAIL times within - # acquire_time_domain_samples, which handles the retry logic until - # the IQ acquisition succeeds. - self.rx.rsa.set_times_to_fail(TIMES_TO_FAIL) # Reset times_failed - _ = self.rx.acquire_time_domain_samples( - 100, retries=TIMES_TO_FAIL + 1, cal_adjust=False - ) - def test_acquire_samples(self): setattr(self.rx, "iq_bandwidth", max(self.CORRECT_ALLOWED_BW)) # Test non-data measurement result components - r = self.rx.acquire_time_domain_samples( - int(self.rx.iq_bandwidth * 0.001), cal_adjust=False - ) + r = self.rx.acquire_time_domain_samples(int(self.rx.iq_bandwidth * 0.001)) assert r["frequency"] == self.rx.frequency assert r["overload"] == False assert r["reference_level"] == self.rx.reference_level @@ -195,9 +171,7 @@ def test_acquire_samples(self): # Attenuation/preamp keys should not exist for RSA30X old_dev_name = self.rx.model setattr(self.rx, "model", "RSA306B") - r = self.rx.acquire_time_domain_samples( - int(self.rx.iq_bandwidth * 0.001), cal_adjust=False - ) + r = self.rx.acquire_time_domain_samples(int(self.rx.iq_bandwidth * 0.001)) with pytest.raises(KeyError): _ = r["attenuation"] with pytest.raises(KeyError): @@ -207,25 +181,19 @@ def test_acquire_samples(self): # Acquire n_samps resulting in integer number of milliseconds for duration_ms in [1, 2, 3, 7, 10]: n_samps = int(self.rx.iq_bandwidth * duration_ms * 0.001) - result = self.rx.acquire_time_domain_samples(n_samps, cal_adjust=False) + result = self.rx.acquire_time_domain_samples(n_samps) assert len(result["data"]) == n_samps # Acquire n_samps resulting in non-integer milliseconds for duration_ms in [1.1, 2.02, 3.3, 7.007, 10.05]: n_samps = int(self.rx.iq_bandwidth * duration_ms * 0.001) - result = self.rx.acquire_time_domain_samples(n_samps, cal_adjust=False) + result = self.rx.acquire_time_domain_samples(n_samps) assert len(result["data"]) == n_samps - # Calibration data is not loaded, cal_adjust should fail - with pytest.raises(Exception): - _ = self.rx.acquire_time_domain_samples(100) - # Non-integer n_samps should fail with pytest.raises(ValueError): - _ = self.rx.acquire_time_domain_samples(1.01, cal_adjust=False) + _ = self.rx.acquire_time_domain_samples(1.01) # Test with skipping samples - r = self.rx.acquire_time_domain_samples( - int(self.rx.iq_bandwidth * 0.001), 100, cal_adjust=False - ) + r = self.rx.acquire_time_domain_samples(int(self.rx.iq_bandwidth * 0.001), 100) assert len(r["data"]) == int(self.rx.iq_bandwidth * 0.001) From 3b5515f5bbc5776a327487759d06947e42ebee90 Mon Sep 17 00:00:00 2001 From: Anthony Romaniello Date: Tue, 12 Mar 2024 15:53:39 -0400 Subject: [PATCH 34/45] Remove unnecessary loop formerly used to contain retry loop --- src/scos_tekrsa/hardware/tekrsa_sigan.py | 79 ++++++++++++------------ 1 file changed, 38 insertions(+), 41 deletions(-) diff --git a/src/scos_tekrsa/hardware/tekrsa_sigan.py b/src/scos_tekrsa/hardware/tekrsa_sigan.py index 82b3328..4ae0418 100644 --- a/src/scos_tekrsa/hardware/tekrsa_sigan.py +++ b/src/scos_tekrsa/hardware/tekrsa_sigan.py @@ -299,44 +299,41 @@ def acquire_time_domain_samples( f"acquire_time_domain_samples starting, num_samples = {nsamps}" ) - while True: - self._capture_time = utils.get_datetime_str_now() - data, status = self.rsa.IQSTREAM_Tempfile_NoConfig(durationMsec, True) - data = data[nskip : nskip + nsamps_req] # Remove extra samples, if any - data_len = len(data) - - logger.debug(f"IQ Stream status: {status}") - - # Check status string for overload / data loss - self.overload = False - if "Input overrange" in status: - self.overload = True - logger.debug("IQ stream: ADC overrange event occurred.") - - if "data loss" in status or "discontinuity" in status: # Invalid data - msg = "Data loss occurred during IQ streaming" - logger.debug(msg) - raise RuntimeError(msg) - elif ( - not data_len == nsamps_req - ): # Invalid data: incorrect number of samples - msg = f"RSA error: requested {nsamps_req + nskip} samples, but got {data_len}." - logger.debug(msg) - raise RuntimeError(msg) - else: - logger.debug( - f"IQ stream: successfully acquired {data_len} samples." - ) - - measurement_result = { - "data": data, - "overload": self.overload, - "frequency": self.frequency, - "reference_level": self.reference_level, - "sample_rate": self.rsa.IQSTREAM_GetAcqParameters()[1], - "capture_time": self._capture_time, - } - if self._model not in ["RSA306B", "RSA306"]: - measurement_result["attenuation"] = self.attenuation - measurement_result["preamp_enable"] = self.preamp_enable - return measurement_result + self._capture_time = utils.get_datetime_str_now() + data, status = self.rsa.IQSTREAM_Tempfile_NoConfig(durationMsec, True) + data = data[nskip : nskip + nsamps_req] # Remove extra samples, if any + data_len = len(data) + + logger.debug(f"IQ Stream status: {status}") + + # Check status string for overload / data loss + self.overload = False + if "Input overrange" in status: + self.overload = True + logger.debug("IQ stream: ADC overrange event occurred.") + + if "data loss" in status or "discontinuity" in status: # Invalid data + msg = "Data loss occurred during IQ streaming" + logger.debug(msg) + raise RuntimeError(msg) + elif ( + not data_len == nsamps_req + ): # Invalid data: incorrect number of samples + msg = f"RSA error: requested {nsamps_req + nskip} samples, but got {data_len}." + logger.debug(msg) + raise RuntimeError(msg) + else: + logger.debug(f"IQ stream: successfully acquired {data_len} samples.") + + measurement_result = { + "data": data, + "overload": self.overload, + "frequency": self.frequency, + "reference_level": self.reference_level, + "sample_rate": self.rsa.IQSTREAM_GetAcqParameters()[1], + "capture_time": self._capture_time, + } + if self._model not in ["RSA306B", "RSA306"]: + measurement_result["attenuation"] = self.attenuation + measurement_result["preamp_enable"] = self.preamp_enable + return measurement_result From d2ff954eeb4a8ab5d1094ef0a9b05c842abb5630 Mon Sep 17 00:00:00 2001 From: Doug Boulware Date: Fri, 15 Mar 2024 09:40:43 -0600 Subject: [PATCH 35/45] retry IQ once. --- src/scos_tekrsa/hardware/tekrsa_sigan.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/scos_tekrsa/hardware/tekrsa_sigan.py b/src/scos_tekrsa/hardware/tekrsa_sigan.py index 8e97f1f..ec26604 100644 --- a/src/scos_tekrsa/hardware/tekrsa_sigan.py +++ b/src/scos_tekrsa/hardware/tekrsa_sigan.py @@ -305,7 +305,12 @@ def acquire_time_domain_samples( ) self._capture_time = utils.get_datetime_str_now() - data, status = self.rsa.IQSTREAM_Tempfile_NoConfig(durationMsec, True) + try: + data, status = self.rsa.IQSTREAM_Tempfile_NoConfig(durationMsec, True) + except BaseException as error: + logger.error(f"Error acquiring IQ: {error}. Retrying..." ) + data, status = self.rsa.IQSTREAM_Tempfile_NoConfig(durationMsec, True) + data = data[nskip : nskip + nsamps_req] # Remove extra samples, if any data_len = len(data) From 933e2c59aaaa1fa1b5af797cce751833237e95a9 Mon Sep 17 00:00:00 2001 From: Doug Boulware Date: Fri, 15 Mar 2024 10:08:21 -0600 Subject: [PATCH 36/45] remove retry IQ. --- src/scos_tekrsa/hardware/tekrsa_sigan.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/scos_tekrsa/hardware/tekrsa_sigan.py b/src/scos_tekrsa/hardware/tekrsa_sigan.py index ec26604..ebc5f06 100644 --- a/src/scos_tekrsa/hardware/tekrsa_sigan.py +++ b/src/scos_tekrsa/hardware/tekrsa_sigan.py @@ -305,11 +305,8 @@ def acquire_time_domain_samples( ) self._capture_time = utils.get_datetime_str_now() - try: - data, status = self.rsa.IQSTREAM_Tempfile_NoConfig(durationMsec, True) - except BaseException as error: - logger.error(f"Error acquiring IQ: {error}. Retrying..." ) - data, status = self.rsa.IQSTREAM_Tempfile_NoConfig(durationMsec, True) + + data, status = self.rsa.IQSTREAM_Tempfile_NoConfig(durationMsec, True) data = data[nskip : nskip + nsamps_req] # Remove extra samples, if any data_len = len(data) From ddb23774c624befeef29c74201d775a508f92f54 Mon Sep 17 00:00:00 2001 From: Doug Boulware Date: Fri, 15 Mar 2024 12:23:19 -0600 Subject: [PATCH 37/45] testing acquiring IQ with retries. --- src/scos_tekrsa/hardware/tekrsa_sigan.py | 121 +++++++++++++---------- 1 file changed, 67 insertions(+), 54 deletions(-) diff --git a/src/scos_tekrsa/hardware/tekrsa_sigan.py b/src/scos_tekrsa/hardware/tekrsa_sigan.py index ebc5f06..2b277ff 100644 --- a/src/scos_tekrsa/hardware/tekrsa_sigan.py +++ b/src/scos_tekrsa/hardware/tekrsa_sigan.py @@ -58,6 +58,7 @@ def __init__( self.max_iq_bandwidth = None self.min_iq_bandwidth = None self.overload = None + self.retries = 3 self.connect() except BaseException as error: @@ -278,69 +279,81 @@ def acquire_time_domain_samples( ): """Acquire specific number of time-domain IQ samples.""" with sigan_lock: - self._capture_time = None - if isinstance(num_samples, int) or ( + for i in range(self.retries): + try + measurement_result = self._try_acquire_time_domain_samples(num_samples, num_samples_skip) + return measurement_result + except BaseException as error: + if i == self.retries -1: + logger.error(f"Reached retry limit: Failed to acquire IQ: {error}") + raise error + else: + logger.error("Error acquiring IQ. Retrying...") + + def _try_acquire_time_domain_samples(self, num_samples: int, num_samples_skip: int = 0): + self._capture_time = None + if isinstance(num_samples, int) or ( isinstance(num_samples, float) and num_samples.is_integer() - ): - nsamps_req = int(num_samples) # Requested number of samples - else: - raise ValueError("Requested number of samples must be an integer.") - nskip = int(num_samples_skip) # Requested number of samples to skip - nsamps = nsamps_req + nskip # Total number of samples to collect + ): + nsamps_req = int(num_samples) # Requested number of samples + else: + raise ValueError("Requested number of samples must be an integer.") + nskip = int(num_samples_skip) # Requested number of samples to skip + nsamps = nsamps_req + nskip # Total number of samples to collect - # Determine correct time length (round up, integer ms) - durationMsec = int(1000 * (nsamps / self.sample_rate)) + ( + # Determine correct time length (round up, integer ms) + durationMsec = int(1000 * (nsamps / self.sample_rate)) + ( 1000 * nsamps % self.sample_rate > 0 - ) + ) - if durationMsec == 0: - # Num. samples requested is less than minimum duration for IQ stream. - # Handle this by skipping more samples than requested - durationMsec = 1 # Minimum allowed IQ stream duration - nskip = int((self.sample_rate / 1000) - nsamps_req) - nsamps = nskip + nsamps_req + if durationMsec == 0: + # Num. samples requested is less than minimum duration for IQ stream. + # Handle this by skipping more samples than requested + durationMsec = 1 # Minimum allowed IQ stream duration + nskip = int((self.sample_rate / 1000) - nsamps_req) + nsamps = nskip + nsamps_req - logger.debug( - f"acquire_time_domain_samples starting, num_samples = {nsamps}" - ) + logger.debug( + f"acquire_time_domain_samples starting, num_samples = {nsamps}" + ) - self._capture_time = utils.get_datetime_str_now() + self._capture_time = utils.get_datetime_str_now() - data, status = self.rsa.IQSTREAM_Tempfile_NoConfig(durationMsec, True) + data, status = self.rsa.IQSTREAM_Tempfile_NoConfig(durationMsec, True) - data = data[nskip : nskip + nsamps_req] # Remove extra samples, if any - data_len = len(data) + data = data[nskip: nskip + nsamps_req] # Remove extra samples, if any + data_len = len(data) - logger.debug(f"IQ Stream status: {status}") + logger.debug(f"IQ Stream status: {status}") - # Check status string for overload / data loss - self.overload = False - if "Input overrange" in status: - self.overload = True - logger.debug("IQ stream: ADC overrange event occurred.") + # Check status string for overload / data loss + self.overload = False + if "Input overrange" in status: + self.overload = True + logger.debug("IQ stream: ADC overrange event occurred.") - if "data loss" in status or "discontinuity" in status: # Invalid data - msg = "Data loss occurred during IQ streaming" - logger.debug(msg) - raise RuntimeError(msg) - elif ( + if "data loss" in status or "discontinuity" in status: # Invalid data + msg = "Data loss occurred during IQ streaming" + logger.debug(msg) + raise RuntimeError(msg) + elif ( not data_len == nsamps_req - ): # Invalid data: incorrect number of samples - msg = f"RSA error: requested {nsamps_req + nskip} samples, but got {data_len}." - logger.debug(msg) - raise RuntimeError(msg) - else: - logger.debug(f"IQ stream: successfully acquired {data_len} samples.") - - measurement_result = { - "data": data, - "overload": self.overload, - "frequency": self.frequency, - "reference_level": self.reference_level, - "sample_rate": self.rsa.IQSTREAM_GetAcqParameters()[1], - "capture_time": self._capture_time, - } - if self._model not in ["RSA306B", "RSA306"]: - measurement_result["attenuation"] = self.attenuation - measurement_result["preamp_enable"] = self.preamp_enable - return measurement_result + ): # Invalid data: incorrect number of samples + msg = f"RSA error: requested {nsamps_req + nskip} samples, but got {data_len}." + logger.debug(msg) + raise RuntimeError(msg) + else: + logger.debug(f"IQ stream: successfully acquired {data_len} samples.") + + measurement_result = { + "data": data, + "overload": self.overload, + "frequency": self.frequency, + "reference_level": self.reference_level, + "sample_rate": self.rsa.IQSTREAM_GetAcqParameters()[1], + "capture_time": self._capture_time, + } + if self._model not in ["RSA306B", "RSA306"]: + measurement_result["attenuation"] = self.attenuation + measurement_result["preamp_enable"] = self.preamp_enable + return measurement_result \ No newline at end of file From 94bf277089167b752ac9d1940628a2c66ab60009 Mon Sep 17 00:00:00 2001 From: Doug Boulware Date: Fri, 15 Mar 2024 12:27:24 -0600 Subject: [PATCH 38/45] typo fix. --- src/scos_tekrsa/hardware/tekrsa_sigan.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scos_tekrsa/hardware/tekrsa_sigan.py b/src/scos_tekrsa/hardware/tekrsa_sigan.py index 2b277ff..fc1a0ac 100644 --- a/src/scos_tekrsa/hardware/tekrsa_sigan.py +++ b/src/scos_tekrsa/hardware/tekrsa_sigan.py @@ -280,7 +280,7 @@ def acquire_time_domain_samples( """Acquire specific number of time-domain IQ samples.""" with sigan_lock: for i in range(self.retries): - try + try: measurement_result = self._try_acquire_time_domain_samples(num_samples, num_samples_skip) return measurement_result except BaseException as error: From 320d9592d0d49fb4e514fc2252d3fe7d41b33e36 Mon Sep 17 00:00:00 2001 From: Doug Boulware Date: Fri, 15 Mar 2024 12:40:18 -0600 Subject: [PATCH 39/45] remove retry. --- src/scos_tekrsa/hardware/tekrsa_sigan.py | 121 ++++++++++------------- 1 file changed, 54 insertions(+), 67 deletions(-) diff --git a/src/scos_tekrsa/hardware/tekrsa_sigan.py b/src/scos_tekrsa/hardware/tekrsa_sigan.py index fc1a0ac..ebc5f06 100644 --- a/src/scos_tekrsa/hardware/tekrsa_sigan.py +++ b/src/scos_tekrsa/hardware/tekrsa_sigan.py @@ -58,7 +58,6 @@ def __init__( self.max_iq_bandwidth = None self.min_iq_bandwidth = None self.overload = None - self.retries = 3 self.connect() except BaseException as error: @@ -279,81 +278,69 @@ def acquire_time_domain_samples( ): """Acquire specific number of time-domain IQ samples.""" with sigan_lock: - for i in range(self.retries): - try: - measurement_result = self._try_acquire_time_domain_samples(num_samples, num_samples_skip) - return measurement_result - except BaseException as error: - if i == self.retries -1: - logger.error(f"Reached retry limit: Failed to acquire IQ: {error}") - raise error - else: - logger.error("Error acquiring IQ. Retrying...") - - def _try_acquire_time_domain_samples(self, num_samples: int, num_samples_skip: int = 0): - self._capture_time = None - if isinstance(num_samples, int) or ( + self._capture_time = None + if isinstance(num_samples, int) or ( isinstance(num_samples, float) and num_samples.is_integer() - ): - nsamps_req = int(num_samples) # Requested number of samples - else: - raise ValueError("Requested number of samples must be an integer.") - nskip = int(num_samples_skip) # Requested number of samples to skip - nsamps = nsamps_req + nskip # Total number of samples to collect + ): + nsamps_req = int(num_samples) # Requested number of samples + else: + raise ValueError("Requested number of samples must be an integer.") + nskip = int(num_samples_skip) # Requested number of samples to skip + nsamps = nsamps_req + nskip # Total number of samples to collect - # Determine correct time length (round up, integer ms) - durationMsec = int(1000 * (nsamps / self.sample_rate)) + ( + # Determine correct time length (round up, integer ms) + durationMsec = int(1000 * (nsamps / self.sample_rate)) + ( 1000 * nsamps % self.sample_rate > 0 - ) + ) - if durationMsec == 0: - # Num. samples requested is less than minimum duration for IQ stream. - # Handle this by skipping more samples than requested - durationMsec = 1 # Minimum allowed IQ stream duration - nskip = int((self.sample_rate / 1000) - nsamps_req) - nsamps = nskip + nsamps_req + if durationMsec == 0: + # Num. samples requested is less than minimum duration for IQ stream. + # Handle this by skipping more samples than requested + durationMsec = 1 # Minimum allowed IQ stream duration + nskip = int((self.sample_rate / 1000) - nsamps_req) + nsamps = nskip + nsamps_req - logger.debug( - f"acquire_time_domain_samples starting, num_samples = {nsamps}" - ) + logger.debug( + f"acquire_time_domain_samples starting, num_samples = {nsamps}" + ) - self._capture_time = utils.get_datetime_str_now() + self._capture_time = utils.get_datetime_str_now() - data, status = self.rsa.IQSTREAM_Tempfile_NoConfig(durationMsec, True) + data, status = self.rsa.IQSTREAM_Tempfile_NoConfig(durationMsec, True) - data = data[nskip: nskip + nsamps_req] # Remove extra samples, if any - data_len = len(data) + data = data[nskip : nskip + nsamps_req] # Remove extra samples, if any + data_len = len(data) - logger.debug(f"IQ Stream status: {status}") + logger.debug(f"IQ Stream status: {status}") - # Check status string for overload / data loss - self.overload = False - if "Input overrange" in status: - self.overload = True - logger.debug("IQ stream: ADC overrange event occurred.") + # Check status string for overload / data loss + self.overload = False + if "Input overrange" in status: + self.overload = True + logger.debug("IQ stream: ADC overrange event occurred.") - if "data loss" in status or "discontinuity" in status: # Invalid data - msg = "Data loss occurred during IQ streaming" - logger.debug(msg) - raise RuntimeError(msg) - elif ( + if "data loss" in status or "discontinuity" in status: # Invalid data + msg = "Data loss occurred during IQ streaming" + logger.debug(msg) + raise RuntimeError(msg) + elif ( not data_len == nsamps_req - ): # Invalid data: incorrect number of samples - msg = f"RSA error: requested {nsamps_req + nskip} samples, but got {data_len}." - logger.debug(msg) - raise RuntimeError(msg) - else: - logger.debug(f"IQ stream: successfully acquired {data_len} samples.") - - measurement_result = { - "data": data, - "overload": self.overload, - "frequency": self.frequency, - "reference_level": self.reference_level, - "sample_rate": self.rsa.IQSTREAM_GetAcqParameters()[1], - "capture_time": self._capture_time, - } - if self._model not in ["RSA306B", "RSA306"]: - measurement_result["attenuation"] = self.attenuation - measurement_result["preamp_enable"] = self.preamp_enable - return measurement_result \ No newline at end of file + ): # Invalid data: incorrect number of samples + msg = f"RSA error: requested {nsamps_req + nskip} samples, but got {data_len}." + logger.debug(msg) + raise RuntimeError(msg) + else: + logger.debug(f"IQ stream: successfully acquired {data_len} samples.") + + measurement_result = { + "data": data, + "overload": self.overload, + "frequency": self.frequency, + "reference_level": self.reference_level, + "sample_rate": self.rsa.IQSTREAM_GetAcqParameters()[1], + "capture_time": self._capture_time, + } + if self._model not in ["RSA306B", "RSA306"]: + measurement_result["attenuation"] = self.attenuation + measurement_result["preamp_enable"] = self.preamp_enable + return measurement_result From 2f3797c86563a7fc193c3629c73b6a61957cbc75 Mon Sep 17 00:00:00 2001 From: Doug Boulware Date: Fri, 22 Mar 2024 09:51:25 -0600 Subject: [PATCH 40/45] scos-actions 9.0.0 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 5486982..c1c85d7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,7 +41,7 @@ classifiers = [ dependencies = [ "environs>=9.5.0", "tekrsa-api-wrap>=1.3.2", - "scos_actions @ git+https://github.com/NTIA/scos-actions@calibrate_to_antenna", + "scos_actions @ git+https://github.com/NTIA/scos-actions@9.0.0", ] [project.optional-dependencies] From 10f1848988fbdaf539f9b48986aef49ca7ef4d60 Mon Sep 17 00:00:00 2001 From: Doug Boulware Date: Fri, 22 Mar 2024 09:53:49 -0600 Subject: [PATCH 41/45] Remove action added for testing. --- .../configs/actions-500-600/NO_FILTER_CAL.yml | 38 ------------------- 1 file changed, 38 deletions(-) delete mode 100644 src/scos_tekrsa/configs/actions-500-600/NO_FILTER_CAL.yml diff --git a/src/scos_tekrsa/configs/actions-500-600/NO_FILTER_CAL.yml b/src/scos_tekrsa/configs/actions-500-600/NO_FILTER_CAL.yml deleted file mode 100644 index a0767b6..0000000 --- a/src/scos_tekrsa/configs/actions-500-600/NO_FILTER_CAL.yml +++ /dev/null @@ -1,38 +0,0 @@ -y_factor_cal: - name: No_Filter_Cal - # Preselector configuration - cal_source_idx: 0 - temp_sensor_idx: 2 - noise_diode_on: noise_diode_on - noise_diode_off: noise_diode_off - # Signal Analyzer Settings - preamp_enable: True - reference_level: -25 - attenuation: 0 - sample_rate: 14e6 - duration_ms: 1000 - nskip: 0 - frequency: - - 3555e6 - - 3565e6 - - 3575e6 - - 3585e6 - - 3595e6 - - 3605e6 - - 3615e6 - - 3625e6 - - 3635e6 - - 3645e6 - - 3655e6 - - 3665e6 - - 3675e6 - - 3685e6 - - 3695e6 - # IIR Filter Settings: - # Optionally apply a low-pass IIR filter before Y-Factor - iir_apply: False - iir_gpass_dB: 0.1 - iir_gstop_dB: 40 - iir_pb_edge_Hz: 5e6 - iir_sb_edge_Hz: 5.008e6 - iir_num_response_frequencies: 1000 From 1dcb5ce5ba5585e30fe7107c5a9055b8a5371c60 Mon Sep 17 00:00:00 2001 From: Justin Haze Date: Mon, 25 Mar 2024 13:35:13 -0600 Subject: [PATCH 42/45] update scos_actions version for testing --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index c1c85d7..5486982 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,7 +41,7 @@ classifiers = [ dependencies = [ "environs>=9.5.0", "tekrsa-api-wrap>=1.3.2", - "scos_actions @ git+https://github.com/NTIA/scos-actions@9.0.0", + "scos_actions @ git+https://github.com/NTIA/scos-actions@calibrate_to_antenna", ] [project.optional-dependencies] From 2d81d4647abb9a8802122b03d5b050f4b2139ad5 Mon Sep 17 00:00:00 2001 From: Justin Haze Date: Wed, 27 Mar 2024 11:02:09 -0600 Subject: [PATCH 43/45] set scos-actions version back to 9.0.0 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 5486982..c1c85d7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,7 +41,7 @@ classifiers = [ dependencies = [ "environs>=9.5.0", "tekrsa-api-wrap>=1.3.2", - "scos_actions @ git+https://github.com/NTIA/scos-actions@calibrate_to_antenna", + "scos_actions @ git+https://github.com/NTIA/scos-actions@9.0.0", ] [project.optional-dependencies] From 32b27971d08bdcb32aff53ff0aade89c5562bd1e Mon Sep 17 00:00:00 2001 From: Anthony Romaniello Date: Wed, 27 Mar 2024 14:59:03 -0400 Subject: [PATCH 44/45] remove outdated comment text --- tests/test_tekrsa_sigan.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_tekrsa_sigan.py b/tests/test_tekrsa_sigan.py index 38c8066..8dbb73a 100644 --- a/tests/test_tekrsa_sigan.py +++ b/tests/test_tekrsa_sigan.py @@ -17,7 +17,7 @@ class TestTekRSA: - # Ensure we write the test cal file and use mocks + # Ensure we use mock TekRSA setup_complete = False @pytest.fixture(autouse=True) From cdd9f1871ee1aa0643dc98ad0c6a4cf19f5098a9 Mon Sep 17 00:00:00 2001 From: Anthony Romaniello Date: Wed, 27 Mar 2024 15:01:25 -0400 Subject: [PATCH 45/45] bump major version --- src/scos_tekrsa/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scos_tekrsa/__init__.py b/src/scos_tekrsa/__init__.py index 0d72820..0f607a5 100644 --- a/src/scos_tekrsa/__init__.py +++ b/src/scos_tekrsa/__init__.py @@ -1 +1 @@ -__version__ = "5.1.0" +__version__ = "6.0.0"