spectre-core 0.0.9__py3-none-any.whl → 0.0.11__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. spectre_core/__init__.py +0 -3
  2. spectre_core/_file_io/__init__.py +15 -0
  3. spectre_core/_file_io/file_handlers.py +128 -0
  4. spectre_core/capture_configs/__init__.py +29 -0
  5. spectre_core/capture_configs/_capture_config.py +85 -0
  6. spectre_core/capture_configs/_capture_templates.py +222 -0
  7. spectre_core/capture_configs/_parameters.py +110 -0
  8. spectre_core/capture_configs/_pconstraints.py +82 -0
  9. spectre_core/capture_configs/_ptemplates.py +450 -0
  10. spectre_core/capture_configs/_pvalidators.py +171 -0
  11. spectre_core/chunks/__init__.py +17 -201
  12. spectre_core/chunks/{base.py → _base.py} +15 -60
  13. spectre_core/chunks/_chunks.py +200 -0
  14. spectre_core/chunks/{factory.py → _factory.py} +6 -7
  15. spectre_core/chunks/library/{callisto/chunk.py → _callisto.py} +4 -7
  16. spectre_core/chunks/library/{fixed/chunk.py → _fixed_center_frequency.py} +7 -64
  17. spectre_core/chunks/library/_swept_center_frequency.py +103 -0
  18. spectre_core/config/__init__.py +20 -0
  19. spectre_core/config/_paths.py +77 -0
  20. spectre_core/config/_time_formats.py +15 -0
  21. spectre_core/exceptions.py +4 -5
  22. spectre_core/logging/__init__.py +11 -0
  23. spectre_core/logging/_configure.py +35 -0
  24. spectre_core/logging/_decorators.py +19 -0
  25. spectre_core/{logging.py → logging/_log_handlers.py} +13 -58
  26. spectre_core/plotting/__init__.py +7 -1
  27. spectre_core/plotting/{base.py → _base.py} +40 -20
  28. spectre_core/plotting/_format.py +18 -0
  29. spectre_core/plotting/{panel_stack.py → _panel_stack.py} +48 -48
  30. spectre_core/plotting/_panels.py +234 -0
  31. spectre_core/post_processing/__init__.py +10 -2
  32. spectre_core/post_processing/_base.py +119 -0
  33. spectre_core/post_processing/{factory.py → _factory.py} +7 -6
  34. spectre_core/post_processing/{post_processor.py → _post_processor.py} +3 -3
  35. spectre_core/post_processing/library/_fixed_center_frequency.py +115 -0
  36. spectre_core/post_processing/library/_swept_center_frequency.py +382 -0
  37. spectre_core/receivers/__init__.py +13 -2
  38. spectre_core/receivers/_base.py +180 -0
  39. spectre_core/receivers/{factory.py → _factory.py} +2 -2
  40. spectre_core/receivers/_spec_names.py +20 -0
  41. spectre_core/receivers/gr/__init__.py +3 -0
  42. spectre_core/receivers/gr/_base.py +33 -0
  43. spectre_core/receivers/gr/_rsp1a.py +158 -0
  44. spectre_core/receivers/gr/_rspduo.py +227 -0
  45. spectre_core/receivers/gr/_test.py +123 -0
  46. spectre_core/receivers/library/_rsp1a.py +61 -0
  47. spectre_core/receivers/library/_rspduo.py +69 -0
  48. spectre_core/receivers/library/_sdrplay_receiver.py +185 -0
  49. spectre_core/receivers/library/_test.py +221 -0
  50. spectre_core/spectrograms/__init__.py +18 -0
  51. spectre_core/spectrograms/{analytical.py → _analytical.py} +29 -27
  52. spectre_core/spectrograms/{array_operations.py → _array_operations.py} +47 -1
  53. spectre_core/spectrograms/{spectrogram.py → _spectrogram.py} +62 -35
  54. spectre_core/spectrograms/{transform.py → _transform.py} +76 -89
  55. spectre_core/{post_processing/library → wgetting}/__init__.py +4 -5
  56. spectre_core/wgetting/_callisto.py +155 -0
  57. {spectre_core-0.0.9.dist-info → spectre_core-0.0.11.dist-info}/METADATA +1 -1
  58. spectre_core-0.0.11.dist-info/RECORD +64 -0
  59. spectre_core/cfg.py +0 -116
  60. spectre_core/chunks/library/__init__.py +0 -8
  61. spectre_core/chunks/library/callisto/__init__.py +0 -0
  62. spectre_core/chunks/library/fixed/__init__.py +0 -0
  63. spectre_core/chunks/library/sweep/__init__.py +0 -0
  64. spectre_core/chunks/library/sweep/chunk.py +0 -400
  65. spectre_core/dynamic_imports.py +0 -22
  66. spectre_core/file_handlers/base.py +0 -68
  67. spectre_core/file_handlers/configs.py +0 -271
  68. spectre_core/file_handlers/json.py +0 -40
  69. spectre_core/file_handlers/text.py +0 -21
  70. spectre_core/plotting/factory.py +0 -26
  71. spectre_core/plotting/format.py +0 -19
  72. spectre_core/plotting/library/__init__.py +0 -7
  73. spectre_core/plotting/library/frequency_cuts/panel.py +0 -74
  74. spectre_core/plotting/library/integral_over_frequency/panel.py +0 -34
  75. spectre_core/plotting/library/spectrogram/panel.py +0 -92
  76. spectre_core/plotting/library/time_cuts/panel.py +0 -77
  77. spectre_core/plotting/panel_register.py +0 -13
  78. spectre_core/post_processing/base.py +0 -132
  79. spectre_core/post_processing/library/fixed/__init__.py +0 -0
  80. spectre_core/post_processing/library/fixed/event_handler.py +0 -40
  81. spectre_core/post_processing/library/sweep/event_handler.py +0 -54
  82. spectre_core/receivers/base.py +0 -422
  83. spectre_core/receivers/library/__init__.py +0 -7
  84. spectre_core/receivers/library/rsp1a/__init__.py +0 -0
  85. spectre_core/receivers/library/rsp1a/gr/__init__.py +0 -0
  86. spectre_core/receivers/library/rsp1a/gr/fixed.py +0 -104
  87. spectre_core/receivers/library/rsp1a/gr/sweep.py +0 -129
  88. spectre_core/receivers/library/rsp1a/receiver.py +0 -68
  89. spectre_core/receivers/library/rspduo/__init__.py +0 -0
  90. spectre_core/receivers/library/rspduo/gr/__init__.py +0 -0
  91. spectre_core/receivers/library/rspduo/gr/tuner_1_fixed.py +0 -114
  92. spectre_core/receivers/library/rspduo/gr/tuner_1_sweep.py +0 -131
  93. spectre_core/receivers/library/rspduo/gr/tuner_2_fixed.py +0 -120
  94. spectre_core/receivers/library/rspduo/gr/tuner_2_sweep.py +0 -119
  95. spectre_core/receivers/library/rspduo/receiver.py +0 -97
  96. spectre_core/receivers/library/test/__init__.py +0 -0
  97. spectre_core/receivers/library/test/gr/__init__.py +0 -0
  98. spectre_core/receivers/library/test/gr/cosine_signal_1.py +0 -83
  99. spectre_core/receivers/library/test/gr/tagged_staircase.py +0 -93
  100. spectre_core/receivers/library/test/receiver.py +0 -203
  101. spectre_core/receivers/validators.py +0 -231
  102. spectre_core/web_fetch/callisto.py +0 -101
  103. spectre_core-0.0.9.dist-info/RECORD +0 -74
  104. /spectre_core/chunks/{chunk_register.py → _register.py} +0 -0
  105. /spectre_core/post_processing/{event_handler_register.py → _register.py} +0 -0
  106. /spectre_core/receivers/{receiver_register.py → _register.py} +0 -0
  107. {spectre_core-0.0.9.dist-info → spectre_core-0.0.11.dist-info}/LICENSE +0 -0
  108. {spectre_core-0.0.9.dist-info → spectre_core-0.0.11.dist-info}/WHEEL +0 -0
  109. {spectre_core-0.0.9.dist-info → spectre_core-0.0.11.dist-info}/top_level.txt +0 -0
@@ -1,119 +0,0 @@
1
- #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
-
4
- #
5
- # SPDX-License-Identifier: GPL-3.0
6
- #
7
- # GNU Radio Python Flow Graph
8
- # Title: Not titled yet
9
- # GNU Radio version: 3.10.1.1
10
-
11
- from gnuradio import gr
12
- from gnuradio.filter import firdes
13
- from gnuradio.fft import window
14
- import sys
15
- import signal
16
- from argparse import ArgumentParser
17
- from gnuradio.eng_arg import eng_float, intx
18
- from gnuradio import eng_notation
19
- from gnuradio import sdrplay3
20
- from gnuradio import spectre
21
-
22
- from spectre_core.cfg import CHUNKS_DIR_PATH
23
- from spectre_core.file_handlers.configs import CaptureConfig
24
-
25
-
26
- class tuner_2_sweep(gr.top_block):
27
- def __init__(self,
28
- capture_config: CaptureConfig):
29
- gr.top_block.__init__(self, "tuner_2_sweep", catch_exceptions=True)
30
-
31
- ##################################################
32
- # Unpack capture config
33
- ##################################################
34
- samp_rate = capture_config['samp_rate']
35
- bandwidth = capture_config['bandwidth']
36
- min_freq = capture_config['min_freq']
37
- max_freq = capture_config['max_freq']
38
- freq_step = capture_config['freq_step']
39
- samples_per_step = capture_config['samples_per_step']
40
- IF_gain = capture_config['IF_gain']
41
- RF_gain = capture_config['RF_gain']
42
- chunk_size = capture_config['chunk_size']
43
- start_freq = min_freq + samp_rate/2
44
- tag = capture_config['tag']
45
-
46
- ##################################################
47
- # Blocks
48
- ##################################################
49
- self.spectre_sweep_driver_0 = spectre.sweep_driver(min_freq,
50
- max_freq,
51
- freq_step,
52
- samp_rate,
53
- samples_per_step,
54
- 'freq')
55
- self.spectre_batched_file_sink_0 = spectre.batched_file_sink(CHUNKS_DIR_PATH,
56
- tag,
57
- chunk_size,
58
- samp_rate,
59
- True,
60
- 'freq',
61
- start_freq)
62
- self.sdrplay3_rspduo_0 = sdrplay3.rspduo(
63
- '',
64
- rspduo_mode="Single Tuner",
65
- antenna="Tuner 2 50 ohm",
66
- stream_args=sdrplay3.stream_args(
67
- output_type='fc32',
68
- channels_size=1
69
- ),
70
- )
71
- self.sdrplay3_rspduo_0.set_sample_rate(samp_rate, True)
72
- self.sdrplay3_rspduo_0.set_center_freq(start_freq, True)
73
- self.sdrplay3_rspduo_0.set_bandwidth(bandwidth)
74
- self.sdrplay3_rspduo_0.set_antenna("Tuner 2 50 ohm")
75
- self.sdrplay3_rspduo_0.set_gain_mode(False)
76
- self.sdrplay3_rspduo_0.set_gain(IF_gain, 'IF', True)
77
- self.sdrplay3_rspduo_0.set_gain(RF_gain, 'RF', True)
78
- self.sdrplay3_rspduo_0.set_freq_corr(0)
79
- self.sdrplay3_rspduo_0.set_dc_offset_mode(False)
80
- self.sdrplay3_rspduo_0.set_iq_balance_mode(False)
81
- self.sdrplay3_rspduo_0.set_agc_setpoint(-30)
82
- self.sdrplay3_rspduo_0.set_rf_notch_filter(False)
83
- self.sdrplay3_rspduo_0.set_dab_notch_filter(True)
84
- self.sdrplay3_rspduo_0.set_am_notch_filter(False)
85
- self.sdrplay3_rspduo_0.set_biasT(False)
86
- self.sdrplay3_rspduo_0.set_stream_tags(True)
87
- self.sdrplay3_rspduo_0.set_debug_mode(False)
88
- self.sdrplay3_rspduo_0.set_sample_sequence_gaps_check(False)
89
- self.sdrplay3_rspduo_0.set_show_gain_changes(False)
90
-
91
-
92
- ##################################################
93
- # Connections
94
- ##################################################
95
- self.msg_connect((self.spectre_sweep_driver_0, 'freq'), (self.sdrplay3_rspduo_0, 'freq'))
96
- self.connect((self.sdrplay3_rspduo_0, 0), (self.spectre_batched_file_sink_0, 0))
97
- self.connect((self.sdrplay3_rspduo_0, 0), (self.spectre_sweep_driver_0, 0))
98
-
99
-
100
- def main(capture_config: CaptureConfig,
101
- top_block_cls=tuner_2_sweep,
102
- options=None):
103
- tb = top_block_cls(capture_config)
104
-
105
- def sig_handler(sig=None, frame=None):
106
- tb.stop()
107
- tb.wait()
108
-
109
- sys.exit(0)
110
-
111
- signal.signal(signal.SIGINT, sig_handler)
112
- signal.signal(signal.SIGTERM, sig_handler)
113
-
114
- tb.start(1024)
115
-
116
- tb.wait()
117
-
118
- if __name__ == '__main__':
119
- main()
@@ -1,97 +0,0 @@
1
- # SPDX-FileCopyrightText: © 2024 Jimmy Fitzpatrick <jcfitzpatrick12@gmail.com>
2
- # This file is part of SPECTRE
3
- # SPDX-License-Identifier: GPL-3.0-or-later
4
-
5
- from spectre_core.receivers.base import SDRPlayReceiver
6
- from spectre_core.receivers.receiver_register import register_receiver
7
- from spectre_core.receivers.library.rspduo.gr import (
8
- tuner_1_fixed,
9
- tuner_1_sweep,
10
- tuner_2_fixed,
11
- tuner_2_sweep
12
- )
13
- from spectre_core.file_handlers.configs import CaptureConfig
14
-
15
-
16
- @register_receiver("rspduo")
17
- class Receiver(SDRPlayReceiver):
18
- def __init__(self, *args, **kwargs):
19
- super().__init__(*args, **kwargs)
20
-
21
-
22
- def _set_capture_methods(self) -> None:
23
- self._capture_methods = {
24
- "tuner-1-fixed": self.__tuner_1_fixed,
25
- "tuner-1-sweep": self.__tuner_1_sweep,
26
- "tuner-2-fixed": self.__tuner_2_fixed,
27
- "tuner-2-sweep": self.__tuner_2_sweep
28
- }
29
-
30
-
31
- def _set_validators(self) -> None:
32
- self._validators = {
33
- "tuner-1-fixed": self.__tuner_1_fixed_validator,
34
- "tuner-1-sweep": self.__tuner_1_sweep_validator,
35
- "tuner-2-fixed": self.__tuner_2_fixed_validator,
36
- "tuner-2-sweep": self.__tuner_2_sweep_validator,
37
- }
38
- return
39
-
40
-
41
- def _set_type_templates(self) -> None:
42
- self._type_templates = {
43
- "tuner-1-fixed": self._get_default_type_template("fixed"),
44
- "tuner-1-sweep": self._get_default_type_template("sweep"),
45
- "tuner-2-fixed": self._get_default_type_template("fixed"),
46
- "tuner-2-sweep": self._get_default_type_template("sweep"),
47
- }
48
-
49
- def _set_specifications(self) -> None:
50
- self._specifications = {
51
- "center_freq_lower_bound": 1e3, # [Hz]
52
- "center_freq_upper_bound": 2e9, # [Hz]
53
- "samp_rate_lower_bound": 200e3, # [Hz]
54
- "samp_rate_upper_bound": 10e6, # [Hz]
55
- "bandwidth_lower_bound": 200e3, # [Hz]
56
- "bandwidth_upper_bound": 8e6, # [Hz]
57
- "IF_gain_upper_bound": -20, # [dB]
58
- "RF_gain_upper_bound": 0, # [dB]
59
- "api_latency": 50 * 1e-3 # [s]
60
- }
61
-
62
-
63
- def __tuner_1_fixed(self, capture_config: CaptureConfig) -> None:
64
- tuner_1_fixed.main(capture_config)
65
-
66
-
67
- def __tuner_1_sweep(self, capture_config: CaptureConfig) -> None:
68
- tuner_1_sweep.main(capture_config)
69
-
70
-
71
- def __tuner_2_fixed(self, capture_config: CaptureConfig) -> None:
72
- tuner_2_fixed.main(capture_config)
73
-
74
-
75
- def __tuner_2_sweep(self, capture_config: CaptureConfig) -> None:
76
- tuner_2_sweep.main(capture_config)
77
-
78
-
79
- def __tuner_1_fixed_validator(self, capture_config: CaptureConfig) -> None:
80
- self._default_fixed_validator(capture_config)
81
- self._sdrplay_validator(capture_config)
82
-
83
-
84
- def __tuner_1_sweep_validator(self, capture_config: CaptureConfig) -> None:
85
- self._default_sweep_validator(capture_config)
86
- self._sdrplay_validator(capture_config)
87
-
88
-
89
- def __tuner_2_fixed_validator(self, capture_config: CaptureConfig) -> None:
90
- self._default_fixed_validator(capture_config)
91
- self._sdrplay_validator(capture_config)
92
-
93
-
94
- def __tuner_2_sweep_validator(self, capture_config: CaptureConfig) -> None:
95
- self._default_sweep_validator(capture_config)
96
- self._sdrplay_validator(capture_config)
97
-
File without changes
File without changes
@@ -1,83 +0,0 @@
1
- #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
-
4
- #
5
- # SPDX-License-Identifier: GPL-3.0
6
- #
7
- # GNU Radio Python Flow Graph
8
- # Title: Not titled yet
9
- # GNU Radio version: 3.10.1.1
10
-
11
- # SPDX-FileCopyrightText: © 2024 Jimmy Fitzpatrick <jcfitzpatrick12@gmail.com>
12
- # This file is part of SPECTRE
13
- # SPDX-License-Identifier: GPL-3.0-or-later
14
-
15
- import sys
16
- import signal
17
- from typing import Any
18
-
19
- from gnuradio import analog
20
- from gnuradio import blocks
21
- from gnuradio import gr
22
- from gnuradio.filter import firdes
23
- from gnuradio.fft import window
24
- from gnuradio.eng_arg import eng_float, intx
25
- from gnuradio import eng_notation
26
- from gnuradio import spectre
27
-
28
- from spectre_core.cfg import CHUNKS_DIR_PATH
29
- from spectre_core.file_handlers.configs import CaptureConfig
30
-
31
- class cosine_signal_1(gr.top_block):
32
-
33
- def __init__(self,
34
- capture_config: CaptureConfig):
35
- gr.top_block.__init__(self, "cosine-signal-1", catch_exceptions=True)
36
-
37
- ##################################################
38
- # Unpack capture config
39
- ##################################################
40
- samp_rate = capture_config['samp_rate']
41
- tag = capture_config['tag']
42
- chunk_size = capture_config['chunk_size']
43
- frequency = capture_config['frequency']
44
- amplitude = capture_config['amplitude']
45
-
46
- ##################################################
47
- # Blocks
48
- ##################################################
49
- self.spectre_batched_file_sink_0 = spectre.batched_file_sink(CHUNKS_DIR_PATH, tag, chunk_size, samp_rate)
50
- self.blocks_throttle_0_1 = blocks.throttle(gr.sizeof_float*1, samp_rate,True)
51
- self.blocks_throttle_0 = blocks.throttle(gr.sizeof_float*1, samp_rate,True)
52
- self.blocks_null_source_1 = blocks.null_source(gr.sizeof_float*1)
53
- self.blocks_float_to_complex_1 = blocks.float_to_complex(1)
54
- self.analog_sig_source_x_0 = analog.sig_source_f(samp_rate, analog.GR_COS_WAVE, frequency, amplitude, 0, 0)
55
-
56
-
57
- ##################################################
58
- # Connections
59
- ##################################################
60
- self.connect((self.analog_sig_source_x_0, 0), (self.blocks_throttle_0, 0))
61
- self.connect((self.blocks_float_to_complex_1, 0), (self.spectre_batched_file_sink_0, 0))
62
- self.connect((self.blocks_null_source_1, 0), (self.blocks_throttle_0_1, 0))
63
- self.connect((self.blocks_throttle_0, 0), (self.blocks_float_to_complex_1, 0))
64
- self.connect((self.blocks_throttle_0_1, 0), (self.blocks_float_to_complex_1, 1))
65
-
66
-
67
- def main(capture_config: CaptureConfig,
68
- top_block_cls=cosine_signal_1,
69
- options=None):
70
- tb = top_block_cls(capture_config)
71
-
72
- def sig_handler(sig=None, frame=None):
73
- tb.stop()
74
- tb.wait()
75
-
76
- sys.exit(0)
77
-
78
- signal.signal(signal.SIGINT, sig_handler)
79
- signal.signal(signal.SIGTERM, sig_handler)
80
-
81
- tb.start()
82
-
83
- tb.wait()
@@ -1,93 +0,0 @@
1
- #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
-
4
- #
5
- # SPDX-License-Identifier: GPL-3.0
6
- #
7
- # GNU Radio Python Flow Graph
8
- # Title: Not titled yet
9
- # GNU Radio version: 3.10.1.1
10
-
11
- # SPDX-FileCopyrightText: © 2024 Jimmy Fitzpatrick <jcfitzpatrick12@gmail.com>
12
- # This file is part of SPECTRE
13
- # SPDX-License-Identifier: GPL-3.0-or-later
14
-
15
- import sys
16
- import signal
17
- from argparse import ArgumentParser
18
- from typing import Any
19
-
20
- from gnuradio import blocks
21
- from gnuradio import gr
22
- from gnuradio.filter import firdes
23
- from gnuradio.fft import window
24
- from gnuradio.eng_arg import eng_float, intx
25
- from gnuradio import eng_notation
26
- from gnuradio import spectre
27
-
28
- from spectre_core.cfg import CHUNKS_DIR_PATH
29
- from spectre_core.file_handlers.configs import CaptureConfig
30
-
31
- class tagged_staircase(gr.top_block):
32
-
33
- def __init__(self,
34
- capture_config: CaptureConfig):
35
- gr.top_block.__init__(self, "tagged-staircase", catch_exceptions=True)
36
-
37
- ##################################################
38
- # Unpack capture config
39
- ##################################################
40
- tag = capture_config['tag']
41
- step_increment = capture_config['step_increment']
42
- samp_rate = capture_config['samp_rate']
43
- min_samples_per_step = capture_config['min_samples_per_step']
44
- max_samples_per_step = capture_config['max_samples_per_step']
45
- freq_step = capture_config['freq_step']
46
- chunk_size = capture_config['chunk_size']
47
- is_sweeping = True
48
-
49
- ##################################################
50
- # Blocks
51
- ##################################################
52
- self.spectre_tagged_staircase_0 = spectre.tagged_staircase(min_samples_per_step,
53
- max_samples_per_step,
54
- freq_step,
55
- step_increment,
56
- samp_rate)
57
- self.spectre_batched_file_sink_0 = spectre.batched_file_sink(CHUNKS_DIR_PATH,
58
- tag,
59
- chunk_size,
60
- samp_rate,
61
- is_sweeping,
62
- 'rx_freq',
63
- 0
64
- )
65
- self.blocks_throttle_0 = blocks.throttle(gr.sizeof_gr_complex*1, samp_rate, True)
66
-
67
-
68
- ##################################################
69
- # Connections
70
- ##################################################
71
- self.connect((self.blocks_throttle_0, 0), (self.spectre_batched_file_sink_0, 0))
72
- self.connect((self.spectre_tagged_staircase_0, 0), (self.blocks_throttle_0, 0))
73
-
74
-
75
-
76
-
77
- def main(capture_config: CaptureConfig,
78
- top_block_cls=tagged_staircase,
79
- options=None):
80
- tb = top_block_cls(capture_config)
81
-
82
- def sig_handler(sig=None, frame=None):
83
- tb.stop()
84
- tb.wait()
85
-
86
- sys.exit(0)
87
-
88
- signal.signal(signal.SIGINT, sig_handler)
89
- signal.signal(signal.SIGTERM, sig_handler)
90
-
91
- tb.start()
92
-
93
- tb.wait()
@@ -1,203 +0,0 @@
1
- # SPDX-FileCopyrightText: © 2024 Jimmy Fitzpatrick <jcfitzpatrick12@gmail.com>
2
- # This file is part of SPECTRE
3
- # SPDX-License-Identifier: GPL-3.0-or-later
4
-
5
- from spectre_core.receivers import validators
6
- from spectre_core.receivers.base import SPECTREReceiver
7
- from spectre_core.receivers.receiver_register import register_receiver
8
- from spectre_core.receivers.library.test.gr import cosine_signal_1
9
- from spectre_core.receivers.library.test.gr import tagged_staircase
10
- from spectre_core.file_handlers.configs import CaptureConfig
11
-
12
-
13
- @register_receiver("test")
14
- class Receiver(SPECTREReceiver):
15
- def __init__(self, *args, **kwargs):
16
- super().__init__(*args, **kwargs)
17
-
18
-
19
- def _set_capture_methods(self) -> None:
20
- self._capture_methods = {
21
- "cosine-signal-1": self.__cosine_signal_1,
22
- "tagged-staircase": self.__tagged_staircase
23
- }
24
-
25
-
26
- def _set_validators(self) -> None:
27
- self._validators = {
28
- "cosine-signal-1": self.__cosine_signal_1_validator,
29
- "tagged-staircase": self.__tagged_staircase_validator
30
- }
31
-
32
-
33
- def _set_type_templates(self) -> None:
34
- self._type_templates = {
35
- "cosine-signal-1": {
36
- "samp_rate": int, # [Hz]
37
- "frequency": float, # [Hz]
38
- "amplitude": float, # unitless
39
- "chunk_size": int, # [s]
40
- "joining_time": int, # [s]
41
- "time_resolution": float, # [s]
42
- "frequency_resolution": float, # [Hz]
43
- "window_type": str, # the window type for the STFFT
44
- "window_kwargs": dict, # keyword arguments for scipy get window function. Must be in order as in scipy documentation.
45
- "window_size": int, # number of samples for the window
46
- "hop": int, # STFFT hop shifts window by so many samples
47
- "chunk_key": str, # maps to the corresponding chunk class
48
- "event_handler_key": str, # maps to the event handler used in post processing
49
- "watch_extension": str # event handlers watch for files with this extension
50
- },
51
- "tagged-staircase": {
52
- "samp_rate": int, # [Hz]
53
- "min_samples_per_step": int, # [samples]
54
- "max_samples_per_step": int, # [samples]
55
- "freq_step": float, # [Hz]
56
- "step_increment": int, # [samples]
57
- "chunk_size": int, # [s]
58
- "joining_time": int, # [s]
59
- "time_resolution": float, # [s]
60
- "frequency_resolution": float, # [Hz]
61
- "window_type": str, # the window type for the STFFT
62
- "window_kwargs": dict, # keyword arguments for scipy get window function. Must be in order as in scipy documentation.
63
- "window_size": int, # number of samples for the window
64
- "hop": int, # keyword arguments for scipy STFFT class
65
- "chunk_key": str, # maps to the corresponding chunk class
66
- "event_handler_key": str, # maps to the event handler used in post processing
67
- "watch_extension": str # event handlers watch for files with this extension
68
- }
69
- }
70
-
71
- def _set_specifications(self) -> None:
72
- self._specifications = {
73
- "samp_rate_lower_bound": 64000
74
- }
75
-
76
-
77
- def __cosine_signal_1(self, capture_config: CaptureConfig) -> None:
78
- cosine_signal_1.main(capture_config)
79
-
80
-
81
- def __tagged_staircase(self, capture_config: CaptureConfig) -> None:
82
- tagged_staircase.main(capture_config)
83
-
84
-
85
- def __cosine_signal_1_validator(self, capture_config: CaptureConfig) -> None:
86
- # unpack the capture config
87
- samp_rate = capture_config["samp_rate"]
88
- frequency = capture_config["frequency"]
89
- amplitude = capture_config["amplitude"]
90
- chunk_size = capture_config["chunk_size"]
91
- window_type = capture_config["window_type"]
92
- window_size = capture_config["window_size"]
93
- hop = capture_config["hop"]
94
- chunk_key = capture_config["chunk_key"]
95
- event_handler_key = capture_config["event_handler_key"]
96
- time_resolution = capture_config["time_resolution"]
97
- frequency_resolution = capture_config["frequency_resolution"]
98
- watch_extension = capture_config["watch_extension"]
99
-
100
- validators.samp_rate_strictly_positive(samp_rate)
101
- validators.chunk_size_strictly_positive(chunk_size)
102
- validators.time_resolution(time_resolution, chunk_size)
103
- validators.window(window_type,
104
- {},
105
- window_size,
106
- chunk_size,
107
- samp_rate)
108
- validators.hop(hop)
109
- validators.chunk_key(chunk_key,
110
- "fixed")
111
- validators.event_handler_key(event_handler_key,
112
- "fixed")
113
- validators.watch_extension(watch_extension,
114
- "bin")
115
-
116
- if samp_rate < self.specifications.get("samp_rate_lower_bound"):
117
- raise ValueError((f"Sample rate must be greater than or equal to "
118
- f"{self.specifications.get('samp_rate_lower_bound')}"))
119
-
120
- if time_resolution != 0:
121
- raise ValueError(f"Time resolution must be zero. "
122
- f"Got {time_resolution} [s]")
123
-
124
- if frequency_resolution != 0:
125
- raise ValueError((f"Frequency resolution must be zero. "
126
- f"Got {frequency_resolution}"))
127
-
128
- # check that the sample rate is an integer multiple of the underlying signal frequency
129
- if samp_rate % frequency != 0:
130
- raise ValueError("The sampling rate must be some integer multiple of frequency")
131
-
132
- a = samp_rate/frequency
133
- if a < 2:
134
- raise ValueError((f"The ratio of sampling rate over frequency must be a natural number greater than two. "
135
- f"Got {a}"))
136
-
137
- # ensuring the window type is rectangular
138
- if window_type != "boxcar":
139
- raise ValueError((f"The window type must be 'boxcar'. "
140
- f"Got {window_type}"))
141
-
142
- # analytical requirement
143
- # if p is the number of sampled cycles, we can find that p = window_size / a
144
- # the number of sampled cycles must be a positive natural number.
145
- p = window_size / a
146
- if window_size % a != 0:
147
- raise ValueError((f"The number of sampled cycles must be a positive natural number. "
148
- f"Computed that p={p}"))
149
-
150
-
151
- if amplitude <= 0:
152
- raise ValueError((f"The amplitude must be strictly positive. "
153
- f"Got {amplitude}"))
154
-
155
-
156
- def __tagged_staircase_validator(self, capture_config: CaptureConfig) -> None:
157
- samp_rate = capture_config["samp_rate"]
158
- min_samples_per_step = capture_config["min_samples_per_step"]
159
- max_samples_per_step = capture_config["max_samples_per_step"]
160
- freq_step = capture_config["freq_step"]
161
- step_increment = capture_config["step_increment"]
162
- chunk_size = capture_config["chunk_size"]
163
- window_type = capture_config["window_type"]
164
- window_kwargs = capture_config["window_kwargs"]
165
- window_size = capture_config["window_size"]
166
- hop = capture_config["hop"]
167
- chunk_key = capture_config["chunk_key"]
168
- event_handler_key = capture_config["event_handler_key"]
169
- time_resolution = capture_config["time_resolution"]
170
- watch_extension = capture_config["watch_extension"]
171
-
172
- validators.samp_rate_strictly_positive(samp_rate)
173
- validators.chunk_size_strictly_positive(chunk_size)
174
- validators.time_resolution(time_resolution, chunk_size)
175
- validators.window(window_type,
176
- window_kwargs,
177
- window_size,
178
- chunk_size,
179
- samp_rate)
180
- validators.hop(hop)
181
- validators.chunk_key(chunk_key, "sweep")
182
- validators.event_handler_key(event_handler_key, "sweep")
183
- validators.watch_extension(watch_extension,
184
- "bin")
185
-
186
- if freq_step != samp_rate:
187
- raise ValueError(f"The frequency step must be equal to the sampling rate")
188
-
189
- if min_samples_per_step <= 0:
190
- raise ValueError((f"Minimum samples per step must be strictly positive. "
191
- f"Got {min_samples_per_step}"))
192
-
193
- if max_samples_per_step <= 0:
194
- raise ValueError((f"Maximum samples per step must be strictly positive. "
195
- f"Got {max_samples_per_step}"))
196
-
197
- if step_increment <= 0:
198
- raise ValueError((f"Step increment must be strictly positive. "
199
- f"Got {step_increment}"))
200
-
201
- if min_samples_per_step > max_samples_per_step:
202
- raise ValueError((f"Minimum samples per step cannot be greater than the maximum samples per step. "
203
- f"Got {min_samples_per_step}, which is greater than {max_samples_per_step}"))