diff --git a/README.md b/README.md index 291caa9..04fa27c 100644 --- a/README.md +++ b/README.md @@ -107,14 +107,22 @@ hatchling build ### Running Tests -Since the UHD drivers are required, a docker container is used for testing. [Install -Docker](https://docs.docker.com/get-docker/). +Without the python3-uhd package installed, a docker container can be used for +testing. [Install Docker](https://docs.docker.com/get-docker/). ```bash docker build -f docker/Dockerfile-test -t usrp_test . docker run usrp_test ``` +With the python3-uhd package installed (`sudo apt install python3-uhd` on Ubuntu), +pytest can be run directly when using a compatible version of Python +(3.10 on Ubuntu 22.04): + +```bash +pytest +``` + ### Committing Besides running the test suite and ensuring that all tests are passing, we also expect @@ -162,4 +170,5 @@ See [LICENSE](LICENSE.md). ## Contact -For technical questions about scos-usrp, contact Justin Haze, +For technical questions about scos-usrp, contact the +[ITS Spectrum Monitoring Team](mailto:spectrummonitoring@ntia.gov) diff --git a/docker/Dockerfile-test b/docker/Dockerfile-test index 13d801b..2493443 100644 --- a/docker/Dockerfile-test +++ b/docker/Dockerfile-test @@ -1,4 +1,4 @@ -FROM ubuntu:20.04 +FROM ubuntu:22.04 RUN apt-get update -q && \ diff --git a/docker/Dockerfile-uhd b/docker/Dockerfile-uhd index 7acd55b..1cbc958 100644 --- a/docker/Dockerfile-uhd +++ b/docker/Dockerfile-uhd @@ -1,4 +1,4 @@ -FROM ubuntu:20.04 +FROM ubuntu:22.04 RUN apt-get update -q && apt-get upgrade -yq diff --git a/pyproject.toml b/pyproject.toml index eb3ffbf..1bc8e72 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -40,10 +40,10 @@ classifiers = [ ] dependencies = [ - "django>=3.2.15,<4.0", + "django>=4.2.17, <5.0", "environs>=9.0, <10.0", "numpy>=1.22.0", - "scos_actions @ git+https://github.com/NTIA/scos-actions@7.0.1", + "scos_actions @ git+https://github.com/NTIA/scos-actions@11.1.0", ] [project.optional-dependencies] diff --git a/scos_usrp/__init__.py b/scos_usrp/__init__.py index ce1305b..ba7be38 100644 --- a/scos_usrp/__init__.py +++ b/scos_usrp/__init__.py @@ -1 +1 @@ -__version__ = "4.0.0" +__version__ = "5.0.0" diff --git a/scos_usrp/configs/actions/acquire_iq_700MHz_ATT_DL.yml b/scos_usrp/configs/actions/acquire_iq_700MHz_ATT_DL_no_cal.yml similarity index 69% rename from scos_usrp/configs/actions/acquire_iq_700MHz_ATT_DL.yml rename to scos_usrp/configs/actions/acquire_iq_700MHz_ATT_DL_no_cal.yml index 8b71297..5e62863 100644 --- a/scos_usrp/configs/actions/acquire_iq_700MHz_ATT_DL.yml +++ b/scos_usrp/configs/actions/acquire_iq_700MHz_ATT_DL_no_cal.yml @@ -1,9 +1,9 @@ single_frequency_time_domain_iq: - name: acquire_iq_700MHz_ATT_DL + name: acquire_iq_700MHz_ATT_DL_no_cal frequency: 739e6 gain: 40 sample_rate: 15.36e6 duration_ms: 1000 nskip: 15.36e4 classification: UNCLASSIFIED - calibration_adjust: true + calibration_adjust: False diff --git a/scos_usrp/configs/actions/acquire_iq_700MHz_ATT_UL.yml b/scos_usrp/configs/actions/acquire_iq_700MHz_ATT_UL_no_cal.yml similarity index 69% rename from scos_usrp/configs/actions/acquire_iq_700MHz_ATT_UL.yml rename to scos_usrp/configs/actions/acquire_iq_700MHz_ATT_UL_no_cal.yml index 5f839f2..8a7c215 100644 --- a/scos_usrp/configs/actions/acquire_iq_700MHz_ATT_UL.yml +++ b/scos_usrp/configs/actions/acquire_iq_700MHz_ATT_UL_no_cal.yml @@ -1,9 +1,9 @@ single_frequency_time_domain_iq: - name: acquire_iq_700MHz_ATT_UL + name: acquire_iq_700MHz_ATT_UL_no_cal frequency: 709e6 gain: 40 sample_rate: 15.36e6 duration_ms: 1000 nskip: 15.36e4 classification: UNCLASSIFIED - calibration_adjust: true + calibration_adjust: False diff --git a/scos_usrp/configs/actions/acquire_iq_700MHz_FirstNet_DL.yml b/scos_usrp/configs/actions/acquire_iq_700MHz_FirstNet_DL_no_cal.yml similarity index 67% rename from scos_usrp/configs/actions/acquire_iq_700MHz_FirstNet_DL.yml rename to scos_usrp/configs/actions/acquire_iq_700MHz_FirstNet_DL_no_cal.yml index c104ff7..db34b96 100644 --- a/scos_usrp/configs/actions/acquire_iq_700MHz_FirstNet_DL.yml +++ b/scos_usrp/configs/actions/acquire_iq_700MHz_FirstNet_DL_no_cal.yml @@ -1,9 +1,9 @@ single_frequency_time_domain_iq: - name: acquire_iq_700MHz_FirstNet_DL + name: acquire_iq_700MHz_FirstNet_DL_no_cal frequency: 763e6 gain: 40 sample_rate: 15.36e6 duration_ms: 1000 nskip: 15.36e4 classification: UNCLASSIFIED - calibration_adjust: true + calibration_adjust: False diff --git a/scos_usrp/configs/actions/acquire_iq_700MHz_FirstNet_UL.yml b/scos_usrp/configs/actions/acquire_iq_700MHz_FirstNet_UL_no_cal.yml similarity index 67% rename from scos_usrp/configs/actions/acquire_iq_700MHz_FirstNet_UL.yml rename to scos_usrp/configs/actions/acquire_iq_700MHz_FirstNet_UL_no_cal.yml index 1448621..99d79c2 100644 --- a/scos_usrp/configs/actions/acquire_iq_700MHz_FirstNet_UL.yml +++ b/scos_usrp/configs/actions/acquire_iq_700MHz_FirstNet_UL_no_cal.yml @@ -1,9 +1,9 @@ single_frequency_time_domain_iq: - name: acquire_iq_700MHz_FirstNet_UL + name: acquire_iq_700MHz_FirstNet_UL_no_cal frequency: 793e6 gain: 40 sample_rate: 15.36e6 duration_ms: 1000 nskip: 15.36e4 classification: UNCLASSIFIED - calibration_adjust: true + calibration_adjust: False diff --git a/scos_usrp/configs/actions/acquire_iq_700MHz_P-SafetyNB_DL.yml b/scos_usrp/configs/actions/acquire_iq_700MHz_P-SafetyNB_DL_no_cal.yml similarity index 67% rename from scos_usrp/configs/actions/acquire_iq_700MHz_P-SafetyNB_DL.yml rename to scos_usrp/configs/actions/acquire_iq_700MHz_P-SafetyNB_DL_no_cal.yml index 0fba5a9..d1a52ac 100644 --- a/scos_usrp/configs/actions/acquire_iq_700MHz_P-SafetyNB_DL.yml +++ b/scos_usrp/configs/actions/acquire_iq_700MHz_P-SafetyNB_DL_no_cal.yml @@ -1,9 +1,9 @@ single_frequency_time_domain_iq: - name: acquire_iq_700MHz_P-SafetyNB_DL + name: acquire_iq_700MHz_P-SafetyNB_DL_no_cal frequency: 772e6 gain: 40 sample_rate: 15.36e6 duration_ms: 10000 nskip: 15.36e4 classification: UNCLASSIFIED - calibration_adjust: true + calibration_adjust: False diff --git a/scos_usrp/configs/actions/acquire_iq_700MHz_P-SafetyNB_UL.yml b/scos_usrp/configs/actions/acquire_iq_700MHz_P-SafetyNB_UL_no_cal.yml similarity index 67% rename from scos_usrp/configs/actions/acquire_iq_700MHz_P-SafetyNB_UL.yml rename to scos_usrp/configs/actions/acquire_iq_700MHz_P-SafetyNB_UL_no_cal.yml index 287df52..5a75285 100644 --- a/scos_usrp/configs/actions/acquire_iq_700MHz_P-SafetyNB_UL.yml +++ b/scos_usrp/configs/actions/acquire_iq_700MHz_P-SafetyNB_UL_no_cal.yml @@ -1,9 +1,9 @@ single_frequency_time_domain_iq: - name: acquire_iq_700MHz_P-SafetyNB_UL + name: acquire_iq_700MHz_P-SafetyNB_UL_no_cal frequency: 802e6 gain: 40 sample_rate: 15.36e6 duration_ms: 10000 nskip: 15.36e4 classification: UNCLASSIFIED - calibration_adjust: true + calibration_adjust: False diff --git a/scos_usrp/configs/actions/acquire_iq_700MHz_T-Mobile_DL.yml b/scos_usrp/configs/actions/acquire_iq_700MHz_T-Mobile_DL_no_cal.yml similarity index 68% rename from scos_usrp/configs/actions/acquire_iq_700MHz_T-Mobile_DL.yml rename to scos_usrp/configs/actions/acquire_iq_700MHz_T-Mobile_DL_no_cal.yml index 83b274d..58eadb9 100644 --- a/scos_usrp/configs/actions/acquire_iq_700MHz_T-Mobile_DL.yml +++ b/scos_usrp/configs/actions/acquire_iq_700MHz_T-Mobile_DL_no_cal.yml @@ -1,9 +1,9 @@ single_frequency_time_domain_iq: - name: acquire_iq_700MHz_T-Mobile_DL + name: acquire_iq_700MHz_T-Mobile_DL_no_cal frequency: 731.5e6 gain: 40 sample_rate: 15.36e6 duration_ms: 1000 nskip: 15.36e4 classification: UNCLASSIFIED - calibration_adjust: true + calibration_adjust: False diff --git a/scos_usrp/configs/actions/acquire_iq_700MHz_T-Mobile_UL_cal.yml b/scos_usrp/configs/actions/acquire_iq_700MHz_T-Mobile_UL_cal.yml new file mode 100644 index 0000000..7704645 --- /dev/null +++ b/scos_usrp/configs/actions/acquire_iq_700MHz_T-Mobile_UL_cal.yml @@ -0,0 +1,9 @@ +single_frequency_time_domain_iq: + name: acquire_iq_700MHz_T-Mobile_UL_cal + frequency: 700e6 + gain: 40 + sample_rate: 15.36e6 + duration_ms: 1000 + nskip: 15.36e4 + classification: UNCLASSIFIED + calibration_adjust: True diff --git a/scos_usrp/configs/actions/acquire_iq_700MHz_T-Mobile_UL.yml b/scos_usrp/configs/actions/acquire_iq_700MHz_T-Mobile_UL_no_cal.yml similarity index 68% rename from scos_usrp/configs/actions/acquire_iq_700MHz_T-Mobile_UL.yml rename to scos_usrp/configs/actions/acquire_iq_700MHz_T-Mobile_UL_no_cal.yml index da9b06d..eb47039 100644 --- a/scos_usrp/configs/actions/acquire_iq_700MHz_T-Mobile_UL.yml +++ b/scos_usrp/configs/actions/acquire_iq_700MHz_T-Mobile_UL_no_cal.yml @@ -1,9 +1,9 @@ single_frequency_time_domain_iq: - name: acquire_iq_700MHz_T-Mobile_UL + name: acquire_iq_700MHz_T-Mobile_UL_no_cal frequency: 700.5e6 gain: 40 sample_rate: 15.36e6 duration_ms: 1000 nskip: 15.36e4 classification: UNCLASSIFIED - calibration_adjust: true + calibration_adjust: False diff --git a/scos_usrp/configs/actions/acquire_iq_700MHz_Verizon_DL.yml b/scos_usrp/configs/actions/acquire_iq_700MHz_Verizon_DL_no_cal.yml similarity index 68% rename from scos_usrp/configs/actions/acquire_iq_700MHz_Verizon_DL.yml rename to scos_usrp/configs/actions/acquire_iq_700MHz_Verizon_DL_no_cal.yml index a4d2c4d..1f0503d 100644 --- a/scos_usrp/configs/actions/acquire_iq_700MHz_Verizon_DL.yml +++ b/scos_usrp/configs/actions/acquire_iq_700MHz_Verizon_DL_no_cal.yml @@ -1,9 +1,9 @@ single_frequency_time_domain_iq: - name: acquire_iq_700MHz_Verizon_DL + name: acquire_iq_700MHz_Verizon_DL_no_cal frequency: 751e6 gain: 40 sample_rate: 15.36e6 duration_ms: 1000 nskip: 15.36e4 classification: UNCLASSIFIED - calibration_adjust: true + calibration_adjust: False diff --git a/scos_usrp/configs/actions/acquire_iq_700MHz_Verizon_UL.yml b/scos_usrp/configs/actions/acquire_iq_700MHz_Verizon_UL_no_cal.yml similarity index 68% rename from scos_usrp/configs/actions/acquire_iq_700MHz_Verizon_UL.yml rename to scos_usrp/configs/actions/acquire_iq_700MHz_Verizon_UL_no_cal.yml index d1bb0b4..d57583c 100644 --- a/scos_usrp/configs/actions/acquire_iq_700MHz_Verizon_UL.yml +++ b/scos_usrp/configs/actions/acquire_iq_700MHz_Verizon_UL_no_cal.yml @@ -1,9 +1,9 @@ single_frequency_time_domain_iq: - name: acquire_iq_700MHz_Verizon_UL + name: acquire_iq_700MHz_Verizon_UL_no_cal frequency: 782e6 gain: 40 sample_rate: 15.36e6 duration_ms: 1000 nskip: 15.36e4 classification: UNCLASSIFIED - calibration_adjust: true + calibration_adjust: False diff --git a/scos_usrp/configs/actions/acquire_m4s_700MHz_ATT_DL.yml b/scos_usrp/configs/actions/acquire_m4s_700MHz_ATT_DL_no_cal.yml similarity index 68% rename from scos_usrp/configs/actions/acquire_m4s_700MHz_ATT_DL.yml rename to scos_usrp/configs/actions/acquire_m4s_700MHz_ATT_DL_no_cal.yml index c038a31..dd4795d 100644 --- a/scos_usrp/configs/actions/acquire_m4s_700MHz_ATT_DL.yml +++ b/scos_usrp/configs/actions/acquire_m4s_700MHz_ATT_DL_no_cal.yml @@ -1,5 +1,5 @@ single_frequency_fft: - name: acquire_m4s_700MHz_ATT_DL + name: acquire_m4s_700MHz_ATT_DL_no_cal frequency: 739e6 gain: 40 sample_rate: 15.36e6 @@ -7,4 +7,4 @@ single_frequency_fft: nffts: 300 nskip: 15.36e4 classification: UNCLASSIFIED - calibration_adjust: true + calibration_adjust: False diff --git a/scos_usrp/configs/actions/acquire_m4s_700MHz_ATT_UL.yml b/scos_usrp/configs/actions/acquire_m4s_700MHz_ATT_UL_no_cal.yml similarity index 68% rename from scos_usrp/configs/actions/acquire_m4s_700MHz_ATT_UL.yml rename to scos_usrp/configs/actions/acquire_m4s_700MHz_ATT_UL_no_cal.yml index 95c32ed..8bfe397 100644 --- a/scos_usrp/configs/actions/acquire_m4s_700MHz_ATT_UL.yml +++ b/scos_usrp/configs/actions/acquire_m4s_700MHz_ATT_UL_no_cal.yml @@ -1,5 +1,5 @@ single_frequency_fft: - name: acquire_m4s_700MHz_ATT_UL + name: acquire_m4s_700MHz_ATT_UL_no_cal frequency: 709e6 gain: 40 sample_rate: 15.36e6 @@ -7,4 +7,4 @@ single_frequency_fft: nffts: 300 nskip: 15.36e4 classification: UNCLASSIFIED - calibration_adjust: true + calibration_adjust: False diff --git a/scos_usrp/configs/actions/acquire_m4s_700MHz_FirstNet_DL.yml b/scos_usrp/configs/actions/acquire_m4s_700MHz_FirstNet_DL_no_cal.yml similarity index 67% rename from scos_usrp/configs/actions/acquire_m4s_700MHz_FirstNet_DL.yml rename to scos_usrp/configs/actions/acquire_m4s_700MHz_FirstNet_DL_no_cal.yml index ba357e2..6ed5dca 100644 --- a/scos_usrp/configs/actions/acquire_m4s_700MHz_FirstNet_DL.yml +++ b/scos_usrp/configs/actions/acquire_m4s_700MHz_FirstNet_DL_no_cal.yml @@ -1,5 +1,5 @@ single_frequency_fft: - name: acquire_m4s_700MHz_FirstNet_DL + name: acquire_m4s_700MHz_FirstNet_DL_no_cal frequency: 763e6 gain: 40 sample_rate: 15.36e6 @@ -7,4 +7,4 @@ single_frequency_fft: nffts: 300 nskip: 15.36e4 classification: UNCLASSIFIED - calibration_adjust: true + calibration_adjust: False diff --git a/scos_usrp/configs/actions/acquire_m4s_700MHz_FirstNet_UL.yml b/scos_usrp/configs/actions/acquire_m4s_700MHz_FirstNet_UL_no_cal.yml similarity index 67% rename from scos_usrp/configs/actions/acquire_m4s_700MHz_FirstNet_UL.yml rename to scos_usrp/configs/actions/acquire_m4s_700MHz_FirstNet_UL_no_cal.yml index 36e2c30..1f3fa13 100644 --- a/scos_usrp/configs/actions/acquire_m4s_700MHz_FirstNet_UL.yml +++ b/scos_usrp/configs/actions/acquire_m4s_700MHz_FirstNet_UL_no_cal.yml @@ -1,5 +1,5 @@ single_frequency_fft: - name: acquire_m4s_700MHz_FirstNet_UL + name: acquire_m4s_700MHz_FirstNet_UL_no_cal frequency: 793e6 gain: 40 sample_rate: 15.36e6 @@ -7,4 +7,4 @@ single_frequency_fft: nffts: 300 nskip: 15.36e4 classification: UNCLASSIFIED - calibration_adjust: true + calibration_adjust: False diff --git a/scos_usrp/configs/actions/acquire_m4s_700MHz_P-SafetyNB_DL.yml b/scos_usrp/configs/actions/acquire_m4s_700MHz_P-SafetyNB_DL_no_cal.yml similarity index 66% rename from scos_usrp/configs/actions/acquire_m4s_700MHz_P-SafetyNB_DL.yml rename to scos_usrp/configs/actions/acquire_m4s_700MHz_P-SafetyNB_DL_no_cal.yml index ce1105d..4dbbf88 100644 --- a/scos_usrp/configs/actions/acquire_m4s_700MHz_P-SafetyNB_DL.yml +++ b/scos_usrp/configs/actions/acquire_m4s_700MHz_P-SafetyNB_DL_no_cal.yml @@ -1,5 +1,5 @@ single_frequency_fft: - name: acquire_m4s_700MHz_P-SafetyNB_DL + name: acquire_m4s_700MHz_P-SafetyNB_DL_no_cal frequency: 772e6 gain: 40 sample_rate: 15.36e6 @@ -7,4 +7,4 @@ single_frequency_fft: nffts: 300 nskip: 15.36e4 classification: UNCLASSIFIED - calibration_adjust: true + calibration_adjust: False diff --git a/scos_usrp/configs/actions/acquire_m4s_700MHz_P-SafetyNB_UL.yml b/scos_usrp/configs/actions/acquire_m4s_700MHz_P-SafetyNB_UL_no_cal.yml similarity index 66% rename from scos_usrp/configs/actions/acquire_m4s_700MHz_P-SafetyNB_UL.yml rename to scos_usrp/configs/actions/acquire_m4s_700MHz_P-SafetyNB_UL_no_cal.yml index f02f544..250a601 100644 --- a/scos_usrp/configs/actions/acquire_m4s_700MHz_P-SafetyNB_UL.yml +++ b/scos_usrp/configs/actions/acquire_m4s_700MHz_P-SafetyNB_UL_no_cal.yml @@ -1,5 +1,5 @@ single_frequency_fft: - name: acquire_m4s_700MHz_P-SafetyNB_UL + name: acquire_m4s_700MHz_P-SafetyNB_UL_no_cal frequency: 802e6 gain: 40 sample_rate: 15.36e6 @@ -7,4 +7,4 @@ single_frequency_fft: nffts: 300 nskip: 15.36e4 classification: UNCLASSIFIED - calibration_adjust: true + calibration_adjust: False diff --git a/scos_usrp/configs/actions/acquire_m4s_700MHz_T-Mobile_DL.yml b/scos_usrp/configs/actions/acquire_m4s_700MHz_T-Mobile_DL_no_cal.yml similarity index 67% rename from scos_usrp/configs/actions/acquire_m4s_700MHz_T-Mobile_DL.yml rename to scos_usrp/configs/actions/acquire_m4s_700MHz_T-Mobile_DL_no_cal.yml index a378a67..5b0dde6 100644 --- a/scos_usrp/configs/actions/acquire_m4s_700MHz_T-Mobile_DL.yml +++ b/scos_usrp/configs/actions/acquire_m4s_700MHz_T-Mobile_DL_no_cal.yml @@ -1,5 +1,5 @@ single_frequency_fft: - name: acquire_m4s_700MHz_T-Mobile_DL + name: acquire_m4s_700MHz_T-Mobile_DL_no_cal frequency: 731.5e6 gain: 40 sample_rate: 15.36e6 @@ -7,4 +7,4 @@ single_frequency_fft: nffts: 300 nskip: 15.36e4 classification: UNCLASSIFIED - calibration_adjust: true + calibration_adjust: False diff --git a/scos_usrp/configs/actions/acquire_m4s_700MHz_T-Mobile_UL_cal.yml b/scos_usrp/configs/actions/acquire_m4s_700MHz_T-Mobile_UL_cal.yml new file mode 100644 index 0000000..2bc9d78 --- /dev/null +++ b/scos_usrp/configs/actions/acquire_m4s_700MHz_T-Mobile_UL_cal.yml @@ -0,0 +1,10 @@ +single_frequency_fft: + name: acquire_m4s_700MHz_T-Mobile_UL_cal + frequency: 700e6 + gain: 40 + sample_rate: 15.36e6 + fft_size: 1024 + nffts: 300 + nskip: 15.36e4 + classification: UNCLASSIFIED + calibration_adjust: True diff --git a/scos_usrp/configs/actions/acquire_m4s_700MHz_T-Mobile_UL.yml b/scos_usrp/configs/actions/acquire_m4s_700MHz_T-Mobile_UL_no_cal.yml similarity index 67% rename from scos_usrp/configs/actions/acquire_m4s_700MHz_T-Mobile_UL.yml rename to scos_usrp/configs/actions/acquire_m4s_700MHz_T-Mobile_UL_no_cal.yml index 5128cba..0b61406 100644 --- a/scos_usrp/configs/actions/acquire_m4s_700MHz_T-Mobile_UL.yml +++ b/scos_usrp/configs/actions/acquire_m4s_700MHz_T-Mobile_UL_no_cal.yml @@ -1,5 +1,5 @@ single_frequency_fft: - name: acquire_m4s_700MHz_T-Mobile_UL + name: acquire_m4s_700MHz_T-Mobile_UL_no_cal frequency: 700.5e6 gain: 40 sample_rate: 15.36e6 @@ -7,4 +7,4 @@ single_frequency_fft: nffts: 300 nskip: 15.36e4 classification: UNCLASSIFIED - calibration_adjust: true + calibration_adjust: False diff --git a/scos_usrp/configs/actions/acquire_m4s_700MHz_Verizon_DL.yml b/scos_usrp/configs/actions/acquire_m4s_700MHz_Verizon_DL_no_cal.yml similarity index 67% rename from scos_usrp/configs/actions/acquire_m4s_700MHz_Verizon_DL.yml rename to scos_usrp/configs/actions/acquire_m4s_700MHz_Verizon_DL_no_cal.yml index edbf610..c45ff96 100644 --- a/scos_usrp/configs/actions/acquire_m4s_700MHz_Verizon_DL.yml +++ b/scos_usrp/configs/actions/acquire_m4s_700MHz_Verizon_DL_no_cal.yml @@ -1,5 +1,5 @@ single_frequency_fft: - name: acquire_m4s_700MHz_Verizon_DL + name: acquire_m4s_700MHz_Verizon_DL_no_cal frequency: 751e6 gain: 40 sample_rate: 15.36e6 @@ -7,4 +7,4 @@ single_frequency_fft: nffts: 300 nskip: 15.36e4 classification: UNCLASSIFIED - calibration_adjust: true + calibration_adjust: False diff --git a/scos_usrp/configs/actions/acquire_m4s_700MHz_Verizon_UL.yml b/scos_usrp/configs/actions/acquire_m4s_700MHz_Verizon_UL_no_cal.yml similarity index 67% rename from scos_usrp/configs/actions/acquire_m4s_700MHz_Verizon_UL.yml rename to scos_usrp/configs/actions/acquire_m4s_700MHz_Verizon_UL_no_cal.yml index f49e84d..8d962bd 100644 --- a/scos_usrp/configs/actions/acquire_m4s_700MHz_Verizon_UL.yml +++ b/scos_usrp/configs/actions/acquire_m4s_700MHz_Verizon_UL_no_cal.yml @@ -1,5 +1,5 @@ single_frequency_fft: - name: acquire_m4s_700MHz_Verizon_UL + name: acquire_m4s_700MHz_Verizon_UL_no_cal frequency: 782e6 gain: 40 sample_rate: 15.36e6 @@ -7,4 +7,4 @@ single_frequency_fft: nffts: 300 nskip: 15.36e4 classification: UNCLASSIFIED - calibration_adjust: true + calibration_adjust: False diff --git a/scos_usrp/configs/actions/survey_700MHz_band_10dB_1000ms_iq.yml b/scos_usrp/configs/actions/survey_700MHz_band_10dB_1000ms_iq_no_cal.yml similarity index 78% rename from scos_usrp/configs/actions/survey_700MHz_band_10dB_1000ms_iq.yml rename to scos_usrp/configs/actions/survey_700MHz_band_10dB_1000ms_iq_no_cal.yml index 9905d24..352f304 100644 --- a/scos_usrp/configs/actions/survey_700MHz_band_10dB_1000ms_iq.yml +++ b/scos_usrp/configs/actions/survey_700MHz_band_10dB_1000ms_iq_no_cal.yml @@ -1,5 +1,5 @@ stepped_frequency_time_domain_iq: - name: survey_700MHz_band_10dB_1000ms_iq + name: survey_700MHz_band_10dB_1000ms_iq_no_cal frequency: - 700.5e6 - 709e6 @@ -16,4 +16,4 @@ stepped_frequency_time_domain_iq: duration_ms: 1000 nskip: 15.36e4 classification: UNCLASSIFIED - calibration_adjust: true + calibration_adjust: False diff --git a/scos_usrp/configs/actions/survey_700MHz_band_10dB_80ms_iq.yml b/scos_usrp/configs/actions/survey_700MHz_band_10dB_80ms_iq__no_cal.yml similarity index 78% rename from scos_usrp/configs/actions/survey_700MHz_band_10dB_80ms_iq.yml rename to scos_usrp/configs/actions/survey_700MHz_band_10dB_80ms_iq__no_cal.yml index dd43cd0..7a2e5d5 100644 --- a/scos_usrp/configs/actions/survey_700MHz_band_10dB_80ms_iq.yml +++ b/scos_usrp/configs/actions/survey_700MHz_band_10dB_80ms_iq__no_cal.yml @@ -1,5 +1,5 @@ stepped_frequency_time_domain_iq: - name: survey_700MHz_band_10dB_80ms_iq + name: survey_700MHz_band_10dB_80ms_iq_no_cal frequency: - 700.5e6 - 709e6 @@ -16,4 +16,4 @@ stepped_frequency_time_domain_iq: duration_ms: 80 nskip: 15.36e4 classification: UNCLASSIFIED - calibration_adjust: true + calibration_adjust: False diff --git a/scos_usrp/configs/actions/survey_700MHz_band_20dB_1000ms_iq.yml b/scos_usrp/configs/actions/survey_700MHz_band_20dB_1000ms_iq_no_cal.yml similarity index 78% rename from scos_usrp/configs/actions/survey_700MHz_band_20dB_1000ms_iq.yml rename to scos_usrp/configs/actions/survey_700MHz_band_20dB_1000ms_iq_no_cal.yml index bf00680..3c4d69e 100644 --- a/scos_usrp/configs/actions/survey_700MHz_band_20dB_1000ms_iq.yml +++ b/scos_usrp/configs/actions/survey_700MHz_band_20dB_1000ms_iq_no_cal.yml @@ -1,5 +1,5 @@ stepped_frequency_time_domain_iq: - name: survey_700MHz_band_20dB_1000ms_iq + name: survey_700MHz_band_20dB_1000ms_iq_no_cal frequency: - 700.5e6 - 709e6 @@ -16,4 +16,4 @@ stepped_frequency_time_domain_iq: duration_ms: 1000 nskip: 15.36e4 classification: UNCLASSIFIED - calibration_adjust: true + calibration_adjust: False diff --git a/scos_usrp/configs/actions/survey_700MHz_band_20dB_80ms_iq.yml b/scos_usrp/configs/actions/survey_700MHz_band_20dB_80ms_iq_no_cal.yml similarity index 78% rename from scos_usrp/configs/actions/survey_700MHz_band_20dB_80ms_iq.yml rename to scos_usrp/configs/actions/survey_700MHz_band_20dB_80ms_iq_no_cal.yml index 6f8ec90..afed372 100644 --- a/scos_usrp/configs/actions/survey_700MHz_band_20dB_80ms_iq.yml +++ b/scos_usrp/configs/actions/survey_700MHz_band_20dB_80ms_iq_no_cal.yml @@ -1,5 +1,5 @@ stepped_frequency_time_domain_iq: - name: survey_700MHz_band_20dB_80ms_iq + name: survey_700MHz_band_20dB_80ms_iq_no_cal frequency: - 700.5e6 - 709e6 @@ -16,4 +16,4 @@ stepped_frequency_time_domain_iq: duration_ms: 80 nskip: 15.36e4 classification: UNCLASSIFIED - calibration_adjust: true + calibration_adjust: False diff --git a/scos_usrp/configs/actions/survey_700MHz_band_40dB_1000ms_iq.yml b/scos_usrp/configs/actions/survey_700MHz_band_40dB_1000ms_iq_no_cal.yml similarity index 78% rename from scos_usrp/configs/actions/survey_700MHz_band_40dB_1000ms_iq.yml rename to scos_usrp/configs/actions/survey_700MHz_band_40dB_1000ms_iq_no_cal.yml index 3044250..f24fafd 100644 --- a/scos_usrp/configs/actions/survey_700MHz_band_40dB_1000ms_iq.yml +++ b/scos_usrp/configs/actions/survey_700MHz_band_40dB_1000ms_iq_no_cal.yml @@ -1,5 +1,5 @@ stepped_frequency_time_domain_iq: - name: survey_700MHz_band_40dB_1000ms_iq + name: survey_700MHz_band_40dB_1000ms_iq_no_cal frequency: - 700.5e6 - 709e6 @@ -16,4 +16,4 @@ stepped_frequency_time_domain_iq: duration_ms: 1000 nskip: 15.36e4 classification: UNCLASSIFIED - calibration_adjust: true + calibration_adjust: False diff --git a/scos_usrp/configs/actions/survey_700MHz_band_40dB_80ms_iq_no_cal.yml b/scos_usrp/configs/actions/survey_700MHz_band_40dB_80ms_iq_no_cal.yml new file mode 100644 index 0000000..7452f1a --- /dev/null +++ b/scos_usrp/configs/actions/survey_700MHz_band_40dB_80ms_iq_no_cal.yml @@ -0,0 +1,19 @@ +stepped_frequency_time_domain_iq: + name: survey_700MHz_band_40dB_80ms_iq_no_cal + frequency: + - 700.5e6 + - 709e6 + - 731.5e6 + - 739e6 + - 751e6 + - 763e6 + - 772e6 + - 782e6 + - 793e6 + - 802e6 + gain: 40 + sample_rate: 15.36e6 + duration_ms: 80 + nskip: 15.36e4 + classification: UNCLASSIFIED + calibration_adjust: False diff --git a/scos_usrp/configs/actions/survey_700MHz_band_iq_no_cal.yml b/scos_usrp/configs/actions/survey_700MHz_band_iq_no_cal.yml new file mode 100644 index 0000000..efde454 --- /dev/null +++ b/scos_usrp/configs/actions/survey_700MHz_band_iq_no_cal.yml @@ -0,0 +1,29 @@ +stepped_frequency_time_domain_iq: + name: survey_700MHz_band_iq_no_cal + frequency: + - 700.5e6 + - 709e6 + - 731.5e6 + - 739e6 + - 751e6 + - 763e6 + - 772e6 + - 782e6 + - 793e6 + - 802e6 + gain: 40 + sample_rate: 15.36e6 + duration_ms: + - 1000 + - 1000 + - 1000 + - 1000 + - 1000 + - 1000 + - 10000 + - 1000 + - 1000 + - 10000 + nskip: 15.36e4 + classification: UNCLASSIFIED + calibration_adjust: False diff --git a/scos_usrp/configs/actions/survey_700MHz_band_40dB_80ms_iq.yml b/scos_usrp/configs/test/test_multi_frequency_iq_action.yml similarity index 80% rename from scos_usrp/configs/actions/survey_700MHz_band_40dB_80ms_iq.yml rename to scos_usrp/configs/test/test_multi_frequency_iq_action.yml index 12272f0..cce2422 100644 --- a/scos_usrp/configs/actions/survey_700MHz_band_40dB_80ms_iq.yml +++ b/scos_usrp/configs/test/test_multi_frequency_iq_action.yml @@ -1,5 +1,5 @@ stepped_frequency_time_domain_iq: - name: survey_700MHz_band_40dB_80ms_iq + name: test_multi_frequency_iq_action frequency: - 700.5e6 - 709e6 @@ -16,4 +16,4 @@ stepped_frequency_time_domain_iq: duration_ms: 80 nskip: 15.36e4 classification: UNCLASSIFIED - calibration_adjust: true + calibration_adjust: False diff --git a/scos_usrp/configs/test/test_single_frequency_iq_action.yml b/scos_usrp/configs/test/test_single_frequency_iq_action.yml new file mode 100644 index 0000000..87943a4 --- /dev/null +++ b/scos_usrp/configs/test/test_single_frequency_iq_action.yml @@ -0,0 +1,9 @@ +single_frequency_time_domain_iq: + name: test_single_frequency_iq_action + frequency: 739e6 + gain: 40 + sample_rate: 15.36e6 + duration_ms: 1000 + nskip: 15.36e4 + classification: UNCLASSIFIED + calibration_adjust: False diff --git a/scos_usrp/configs/test/test_single_frequency_m4s_action.yml b/scos_usrp/configs/test/test_single_frequency_m4s_action.yml new file mode 100644 index 0000000..d1cb0a8 --- /dev/null +++ b/scos_usrp/configs/test/test_single_frequency_m4s_action.yml @@ -0,0 +1,10 @@ +single_frequency_fft: + name: test_single_frequency_m4s_action + frequency: 739e6 + gain: 40 + sample_rate: 15.36e6 + fft_size: 1024 + nffts: 300 + nskip: 15.36e4 + classification: UNCLASSIFIED + calibration_adjust: False diff --git a/scos_usrp/configs/actions/survey_700MHz_band_iq.yml b/scos_usrp/configs/test/test_survey_iq_action.yml similarity index 86% rename from scos_usrp/configs/actions/survey_700MHz_band_iq.yml rename to scos_usrp/configs/test/test_survey_iq_action.yml index f276cf2..495078a 100644 --- a/scos_usrp/configs/actions/survey_700MHz_band_iq.yml +++ b/scos_usrp/configs/test/test_survey_iq_action.yml @@ -1,5 +1,5 @@ stepped_frequency_time_domain_iq: - name: survey_700MHz_band_iq + name: test_survey_iq_action frequency: - 700.5e6 - 709e6 @@ -26,4 +26,4 @@ stepped_frequency_time_domain_iq: - 10000 nskip: 15.36e4 classification: UNCLASSIFIED - calibration_adjust: true + calibration_adjust: False diff --git a/scos_usrp/discover/__init__.py b/scos_usrp/discover/__init__.py index da283da..77c1519 100644 --- a/scos_usrp/discover/__init__.py +++ b/scos_usrp/discover/__init__.py @@ -4,24 +4,39 @@ from scos_actions.actions.sync_gps import SyncGps from scos_actions.discover import init -from scos_usrp.hardware import gps, sigan -from scos_usrp.settings import ACTION_DEFINITIONS_DIR +from scos_usrp.settings import CONFIG_DIR, SIGAN_CLASS, SIGAN_MODULE logger = logging.getLogger(__name__) -actions = { - "monitor_usrp": MonitorSignalAnalyzer( - parameters={"name": "monitor_usrp"}, sigan=sigan - ), - "sync_gps": SyncGps(gps, {"name": "sync_gps"}, sigan), -} +actions = {} +test_actions = {} -logger.debug("scos_usrp: ACTION_DEFINITIONS_DIR = " + ACTION_DEFINITIONS_DIR) -yaml_actions, yaml_test_actions = init( - sigan=sigan, gps=gps, yaml_dir=ACTION_DEFINITIONS_DIR -) -actions.update(yaml_actions) +ACTION_DEFINITIONS_DIR = CONFIG_DIR / "actions" +logger.debug("scos_usrp: ACTION_DEFINITIONS_DIR = " + str(ACTION_DEFINITIONS_DIR)) - -def get_last_calibration_time(): - return sigan.last_calibration_time +logger.debug(f"scos-usrp: SIGAN_MODULE = {SIGAN_MODULE}") +logger.debug(f"scos-usrp: SIGAN_CLASS = {SIGAN_CLASS}") +if ( + SIGAN_MODULE == "scos_usrp.hardware.usrp_sigan" + and SIGAN_CLASS == "USRPSignalAnalyzer" +): + actions.update( + { + "monitor_usrp": MonitorSignalAnalyzer(parameters={"name": "monitor_usrp"}), + "sync_gps": SyncGps({"name": "sync_gps"}), + } + ) + yaml_actions, yaml_test_actions = init(yaml_dir=ACTION_DEFINITIONS_DIR) + actions.update(yaml_actions) + logger.debug("scos-usrp: loading test action configs") + test_actions["test_monitor_usrp"] = MonitorSignalAnalyzer( + parameters={"name": "monitor_usrp"} + ) + TEST_ACTION_DEFINITIONS_DIR = CONFIG_DIR / "test" + logger.debug( + f"scos-usrp: TEST_ACTION_DEFINITIONS_DIR = {TEST_ACTION_DEFINITIONS_DIR}" + ) + _, yaml_test_actions = init(yaml_dir=TEST_ACTION_DEFINITIONS_DIR) + logger.debug(f"scos-usrp: Found {len(yaml_test_actions)} test action configs") + test_actions.update(yaml_test_actions) +logger.debug(f"scos-usrp: len(test_actions) = {len(test_actions)}") diff --git a/scos_usrp/hardware/__init__.py b/scos_usrp/hardware/__init__.py index 9ef83aa..e69de29 100644 --- a/scos_usrp/hardware/__init__.py +++ b/scos_usrp/hardware/__init__.py @@ -1,8 +0,0 @@ -from scos_actions.signals import register_component_with_status - -from scos_usrp.hardware.gps_iface import USRPLocation -from scos_usrp.hardware.usrp_sigan import USRPSignalAnalyzer - -sigan = USRPSignalAnalyzer() -register_component_with_status.send(sigan, component=sigan) -gps = USRPLocation(sigan) diff --git a/scos_usrp/hardware/mocks/usrp_block.py b/scos_usrp/hardware/mocks/usrp_block.py index 0223768..7803619 100644 --- a/scos_usrp/hardware/mocks/usrp_block.py +++ b/scos_usrp/hardware/mocks/usrp_block.py @@ -71,3 +71,6 @@ def set_rx_gain(self, g): def get_rx_gain(self): return self.gain + + def get_pp_string(self) -> str: + return "Mock USRP" diff --git a/scos_usrp/hardware/tests/test_gps.py b/scos_usrp/hardware/tests/test_gps.py index bdfb57e..25d5750 100644 --- a/scos_usrp/hardware/tests/test_gps.py +++ b/scos_usrp/hardware/tests/test_gps.py @@ -2,8 +2,10 @@ from unittest.mock import MagicMock, patch from pytest import approx +from scos_actions.hardware.sensor import Sensor -from scos_usrp.hardware import USRPLocation, USRPSignalAnalyzer +from scos_usrp.hardware.usrp_gps import UsrpGps +from scos_usrp.hardware.usrp_sigan import USRPSignalAnalyzer class TestGPS: @@ -32,8 +34,9 @@ def side_effect(value): sigan.uhd = MagicMock() sigan.uhd.types = MagicMock() sigan.uhd.types.TimeSpec = MagicMock() - gps = USRPLocation(sigan) - latitude, longitude, height = gps.get_location() + gps = UsrpGps() + sensor = Sensor(sigan, {}, gps) + latitude, longitude, height = gps.get_location(sensor) assert latitude == approx(39.99511463) assert longitude == approx(-105.26158690) assert height == approx(10.0) @@ -65,6 +68,7 @@ def side_effect(value): sigan.uhd = MagicMock() sigan.uhd.types = MagicMock() sigan.uhd.types.TimeSpec = MagicMock() - gps = USRPLocation(sigan) - ret = gps.get_location() + gps = UsrpGps() + sensor = Sensor(sigan, {}, gps) + ret = gps.get_location(sensor) assert ret == None diff --git a/scos_usrp/hardware/tests/test_usrp.py b/scos_usrp/hardware/tests/test_usrp.py index 048848f..e98c72b 100644 --- a/scos_usrp/hardware/tests/test_usrp.py +++ b/scos_usrp/hardware/tests/test_usrp.py @@ -2,7 +2,7 @@ import pytest -from scos_usrp.hardware import sigan +from scos_usrp.hardware.usrp_sigan import USRPSignalAnalyzer class TestUSRP: @@ -12,6 +12,7 @@ class TestUSRP: @pytest.fixture(autouse=True) def setup_mock_usrp(self): """Create the mock USRP""" + self.rx = USRPSignalAnalyzer() # Only setup once if self.setup_complete: @@ -19,58 +20,12 @@ def setup_mock_usrp(self): # Create the SignalAnalyzerInterface with the mock usrp_block and get the sigan # usrp_iface.connect() - if not sigan.is_available: + if not self.rx.is_available: raise RuntimeError("Receiver is not available.") - self.rx = sigan # Alert that the setup was complete self.setup_complete = True - # Ensure the usrp can recover from acquisition errors - def test_acquire_samples_with_retries(self): - """Acquire samples should retry without error up to `max_retries`.""" - - # Check that the setup was completed - assert self.setup_complete, "Setup was not completed" - - max_retries = 5 - times_to_fail = 3 - self.rx.sample_rate = 10000000.0 - self.rx.frequency = 650000000.0 - self.rx.gain = 40.0 - self.rx.usrp.set_times_to_fail(times_to_fail) - - try: - self.rx.acquire_time_domain_samples(1000, retries=max_retries) - except RuntimeError: - msg = "Acquisition failing {} times sequentially with {}\n" - msg += "retries requested should NOT have raised an error." - msg = msg.format(times_to_fail, max_retries) - pytest.fail(msg) - - self.rx.usrp.set_times_to_fail(0) - - def test_acquire_samples_fails_when_over_max_retries(self): - """After `max_retries`, an error should be thrown.""" - - # Check that the setup was completed - assert self.setup_complete, "Setup was not completed" - - max_retries = 5 - times_to_fail = 7 - self.rx.usrp.set_times_to_fail(times_to_fail) - self.rx.sample_rate = 10000000.0 - self.rx.frequency = 650000000.0 - self.rx.gain = 40.0 - msg = "Acquisition failing {} times sequentially with {}\n" - msg += "retries requested SHOULD have raised an error." - msg = msg.format(times_to_fail, max_retries) - with pytest.raises(RuntimeError): - self.rx.acquire_time_domain_samples(1000, 1000, max_retries) - pytest.fail(msg) - - self.rx.usrp.set_times_to_fail(0) - def test_tune_result(self): """Check that the tuning is correct""" # Check that the setup was completed diff --git a/scos_usrp/hardware/gps_iface.py b/scos_usrp/hardware/usrp_gps.py similarity index 91% rename from scos_usrp/hardware/gps_iface.py rename to scos_usrp/hardware/usrp_gps.py index 7633906..e8ef63d 100644 --- a/scos_usrp/hardware/gps_iface.py +++ b/scos_usrp/hardware/usrp_gps.py @@ -1,27 +1,23 @@ """Provides an interface to the on-board GPS.""" import logging -import subprocess from datetime import datetime from time import sleep, time from scos_actions.hardware.gps_iface import GPSInterface +from scos_actions.hardware.sensor import Sensor logger = logging.getLogger(__name__) -class USRPLocation(GPSInterface): - def __init__(self, sigan): - self.sigan = sigan - - def get_location(self, timeout_s=1): +class UsrpGps(GPSInterface): + def get_location(self, sensor: Sensor, timeout_s: float = 1): """Use low-level UHD and USRP block methods to sync with GPS.""" - if not self.sigan.is_available: + if not sensor.signal_analyzer.is_available: return None - uhd = self.sigan.uhd - usrp = self.sigan.usrp + usrp = sensor.signal_analyzer.usrp logger.debug("Waiting for GPS lock... ") start = time() @@ -126,9 +122,9 @@ def get_location(self, timeout_s=1): return latitude_dd, longitude_dd, height - def get_gps_time(self): - uhd = self.sigan.uhd - usrp = self.sigan.usrp + def get_gps_time(self, sensor: Sensor): + uhd = sensor.signal_analyzer.uhd + usrp = sensor.signal_analyzer.usrp gps_t = uhd.types.TimeSpec(usrp.get_mboard_sensor("gps_time").to_int() + 1) usrp.set_time_next_pps(gps_t) diff --git a/scos_usrp/hardware/usrp_sigan.py b/scos_usrp/hardware/usrp_sigan.py index 280b396..eedb22f 100644 --- a/scos_usrp/hardware/usrp_sigan.py +++ b/scos_usrp/hardware/usrp_sigan.py @@ -12,12 +12,15 @@ """ import logging +import subprocess +from typing import Dict, Optional import numpy as np +from its_preselector.web_relay import WebRelay from scos_actions import utils -from scos_actions.calibration import sensor_calibration, sigan_calibration from scos_actions.hardware.sigan_iface import SignalAnalyzerInterface +from scos_usrp import __package__ as SCOS_USRP_NAME from scos_usrp import __version__ as SCOS_USRP_VERSION from scos_usrp import settings from scos_usrp.hardware.mocks.usrp_block import MockUsrp @@ -31,34 +34,27 @@ class USRPSignalAnalyzer(SignalAnalyzerInterface): - @property - def last_calibration_time(self): - """Returns the last calibration time from calibration data.""" - return utils.convert_string_to_millisecond_iso_format( - sensor_calibration.calibration_datetime - ) - - @property - def overload(self): - """Returns True if overload occurred, otherwise returns False.""" - return self._sigan_overload or self._sensor_overload - # Define thresholds for determining ADC overload for the sigan ADC_FULL_RANGE_THRESHOLD = 0.98 # ADC scale -1 str: + """Returns the version of the signal analyzer firmware.""" + # firmware version + # based on https://github.com/EttusResearch/uhd/blob/master/host/utils/uhd_usrp_probe.cpp + tree = self.usrp.get_tree() + addr = tree.list("/mboards")[0] + path = f"/mboards/{addr}" + return tree.access_str(path + "/fw_version").get() + + @property + def api_version(self) -> str: + """Returns the version of the underlying signal analyzer API.""" + raw_version = subprocess.run(["dpkg", "-s", "python3-uhd"], capture_output=True, text=True).stdout + new_line_split = raw_version.split("\n") + for line in new_line_split: + if line.startswith("Version"): + return line.split(":")[1].strip() @property def plugin_version(self): """Returns the current version of scos-usrp.""" return self._plugin_version + @property + def plugin_name(self) -> str: + """Returns the current package name of scos-usrp.""" + return self._plugin_name + @property def is_available(self): """Returns True if initialized and ready to make measurements, otherwise returns False.""" @@ -128,20 +148,24 @@ def sample_rate(self, rate): :type sample_rate: float :param sample_rate: Sample rate in samples per second """ + clock_rate = rate + # Maximize clock rate while keeping it under 40e6 + while clock_rate <= 40e6: + clock_rate *= 2 + clock_rate /= 2 + self.clock_rate = clock_rate + if round(self.clock_rate, 1) != round(clock_rate, 1): + raise Exception( + f"Clock rate {self.clock_rate} does not match requested rate {clock_rate}!" + ) self.requested_sample_rate = rate self.usrp.set_rx_rate(rate) fs_MSps = self.sample_rate / 1e6 logger.debug("set USRP sample rate: {:.2f} MSps".format(fs_MSps)) - # Set the clock rate based on calibration - if sigan_calibration is not None: - clock_rate = sigan_calibration.get_clock_rate(rate) - else: - clock_rate = self.sample_rate - # Maximize clock rate while keeping it under 40e6 - while clock_rate <= 40e6: - clock_rate *= 2 - clock_rate /= 2 - self.clock_rate = clock_rate + if round(self.sample_rate, 1) != round(self.requested_sample_rate, 1): + raise Exception( + f"Sample rate {self.sample_rate} does not match requested rate {self.requested_sample_rate}!" + ) @property def clock_rate(self): @@ -209,34 +233,15 @@ def gain(self, gain): :param gain: Gain in dB """ if gain not in VALID_GAINS: - err = "Requested invalid gain {}. ".format(gain) - err += "Choose one of {!r}.".format(VALID_GAINS) - logger.error(err) - return + msg = "Requested invalid gain {}. ".format(gain) + msg += "It is recommended to choose one of {!r}.".format(VALID_GAINS) + logger.warning(msg) self.requested_gain = gain self.usrp.set_rx_gain(gain) msg = "set USRP gain: {:.1f} dB" logger.debug(msg.format(self.usrp.get_rx_gain())) - def check_sensor_overload(self, data): - """Check for sensor overload in the measurement data.""" - measured_data = data.astype(np.complex64) - - time_domain_avg_power = 10 * np.log10(np.mean(np.abs(measured_data) ** 2)) - time_domain_avg_power += ( - 10 * np.log10(1 / (2 * 50)) + 30 - ) # Convert log(V^2) to dBm - self._sensor_overload = False - # explicitly check is not None since 1db compression could be 0 - if self.sensor_calibration_data["1db_compression_point"] is not None: - self._sensor_overload = bool( - time_domain_avg_power - > self.sensor_calibration_data["1db_compression_point"] - ) - - def acquire_time_domain_samples( - self, num_samples, num_samples_skip=0, retries=5, cal_adjust: bool = True - ): + def acquire_time_domain_samples(self, num_samples: int, num_samples_skip: int = 0): """Acquire num_samples_skip+num_samples samples and return the last num_samples :type num_samples: int @@ -245,9 +250,6 @@ def acquire_time_domain_samples( :type num_samples_skip: int :param num_samples_skip: Skip samples to allow signal analyzer DC offset and IQ imbalance algorithms to take effect - :type retries: int - :param retries: The number of retries to attempt when failing to acquire samples - :rtype: dictionary containing the following: data - (list) measurement data overload - (boolean) True if overload occurred, otherwise False @@ -257,41 +259,16 @@ def acquire_time_domain_samples( capture_time - (string) Measurement capture time calibration_annotation - (dict) SigMF calibration annotation """ - self._sigan_overload = False + sigan_overload = False self._capture_time = None # Get the calibration data for the acquisition logger.debug( "Using requested sample rate of " + str(self.requested_sample_rate) ) - cal_params = [] - - if sensor_calibration is not None: - cal_params = sensor_calibration.calibration_parameters - try: - logger.debug(f"Using cal params: {cal_params}") - cal_args = [] - if cal_params is not None: - for p in cal_params: - cal_args.append(getattr(self, "requested_" + p)) - else: - cal_args = None - except KeyError: - raise Exception( - "One or more required cal parameters is not a valid sigan setting." - ) - logger.debug(f"Calibration arguments:{cal_args}") - self.recompute_sensor_calibration_data(cal_args) nsamps = int(num_samples) nskip = int(num_samples_skip) - # Compute the linear gain - db_gain = self.sensor_calibration_data["gain"] - if cal_adjust: - linear_gain = 10 ** (db_gain / 20.0) - else: - linear_gain = 1 # Try to acquire the samples - max_retries = retries while True: # No need to skip initial samples when simulating the signal analyzer if not settings.RUNNING_TESTS and not settings.MOCK_SIGAN: @@ -316,20 +293,14 @@ def acquire_time_domain_samples( data = data[nskip:] if not len(data) == num_samples: - if retries > 0: - msg = "USRP error: requested {} samples, but got {}." - logger.warning(msg.format(num_samples + num_samples_skip, data_len)) - logger.warning("Retrying {} more times.".format(retries)) - retries = retries - 1 - else: - err = "Failed to acquire correct number of samples " - err += "{} times in a row.".format(max_retries) - raise RuntimeError(err) + msg = f"USRP error: requested {num_samples + num_samples_skip} samples, but got {data_len}." + logger.error(msg) + raise RuntimeError(msg) else: logger.debug("Successfully acquired {} samples.".format(num_samples)) # Check IQ values versus ADC max for sigan compression - self._sigan_overload = False + sigan_overload = False i_samples = np.abs(np.real(data)) q_samples = np.abs(np.imag(data)) i_over_threshold = np.sum(i_samples > self.ADC_FULL_RANGE_THRESHOLD) @@ -337,14 +308,12 @@ def acquire_time_domain_samples( total_over_threshold = i_over_threshold + q_over_threshold ratio_over_threshold = float(total_over_threshold) / num_samples if ratio_over_threshold > self.ADC_OVERLOAD_THRESHOLD: - self._sigan_overload = True + sigan_overload = True + logger.warning("Signal Analyzer overload occurred!") - # Scale the data back to RF power and return it - data /= linear_gain - self.check_sensor_overload(data) measurement_result = { "data": data, - "overload": self.overload, + "overload": sigan_overload, "frequency": self.frequency, "gain": self.gain, "sample_rate": self.sample_rate, diff --git a/scos_usrp/settings.py b/scos_usrp/settings.py index e386a20..06651b4 100644 --- a/scos_usrp/settings.py +++ b/scos_usrp/settings.py @@ -1,24 +1,25 @@ +import logging import sys -from os import path +from pathlib import Path -from django.conf import settings from environs import Env +logger = logging.getLogger(__name__) env = Env() +CONFIG_DIR = Path(__file__).parent.resolve() / "configs" -CONFIG_DIR = path.join(path.dirname(path.abspath(__file__)), "configs") -ACTION_DEFINITIONS_DIR = path.join(CONFIG_DIR, "actions") +__cmd = Path(sys.argv[0]).name -__cmd = path.split(sys.argv[0])[-1] RUNNING_TESTS = "test" in __cmd - -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 - +MOCK_SIGAN = env.bool("MOCK_SIGAN", default=False) or RUNNING_TESTS +MOCK_SIGAN_RANDOM = env.bool("MOCK_SIGAN_RANDOM", default=False) +if RUNNING_TESTS: + logging.basicConfig(level=logging.DEBUG) +SIGAN_MODULE = env.str("SIGAN_MODULE", default=None) +SIGAN_CLASS = env.str("SIGAN_CLASS", default=None) +if RUNNING_TESTS: + SIGAN_MODULE = "scos_usrp.hardware.usrp_sigan" + SIGAN_CLASS = "USRPSignalAnalyzer" +logger.debug(f"scos-usrp: SIGAN_MODULE:{SIGAN_MODULE}") +logger.debug(f"scos-usrp: SIGAN_CLASS:{SIGAN_CLASS}") USRP_CONNECTION_ARGS = env("USRP_CONNECTION_ARGS", default="num_recv_frames=650")