qsp-fft 0.1.2__tar.gz
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.
- qsp_fft-0.1.2/LICENSE +21 -0
- qsp_fft-0.1.2/PKG-INFO +336 -0
- qsp_fft-0.1.2/README.md +300 -0
- qsp_fft-0.1.2/pyproject.toml +29 -0
- qsp_fft-0.1.2/qsp/fft/__init__.py +43 -0
- qsp_fft-0.1.2/qsp/fft/analysis.py +101 -0
- qsp_fft-0.1.2/qsp/fft/spectrum.py +94 -0
- qsp_fft-0.1.2/qsp/fft/utils.py +74 -0
- qsp_fft-0.1.2/qsp/fft/windows.py +103 -0
- qsp_fft-0.1.2/qsp_fft.egg-info/PKG-INFO +336 -0
- qsp_fft-0.1.2/qsp_fft.egg-info/SOURCES.txt +17 -0
- qsp_fft-0.1.2/qsp_fft.egg-info/dependency_links.txt +1 -0
- qsp_fft-0.1.2/qsp_fft.egg-info/requires.txt +6 -0
- qsp_fft-0.1.2/qsp_fft.egg-info/top_level.txt +1 -0
- qsp_fft-0.1.2/setup.cfg +4 -0
- qsp_fft-0.1.2/tests/test_analysis.py +92 -0
- qsp_fft-0.1.2/tests/test_package_api.py +88 -0
- qsp_fft-0.1.2/tests/test_spectrum.py +106 -0
- qsp_fft-0.1.2/tests/test_windows.py +112 -0
qsp_fft-0.1.2/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 RQM-Technologies-dev
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
qsp_fft-0.1.2/PKG-INFO
ADDED
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: qsp-fft
|
|
3
|
+
Version: 0.1.2
|
|
4
|
+
Summary: Spectral-transform library built on qsp-core for the RQM Technologies ecosystem
|
|
5
|
+
License: MIT License
|
|
6
|
+
|
|
7
|
+
Copyright (c) 2026 RQM-Technologies-dev
|
|
8
|
+
|
|
9
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
10
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
11
|
+
in the Software without restriction, including without limitation the rights
|
|
12
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
13
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
14
|
+
furnished to do so, subject to the following conditions:
|
|
15
|
+
|
|
16
|
+
The above copyright notice and this permission notice shall be included in all
|
|
17
|
+
copies or substantial portions of the Software.
|
|
18
|
+
|
|
19
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
20
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
21
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
22
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
23
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
24
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
25
|
+
SOFTWARE.
|
|
26
|
+
|
|
27
|
+
Requires-Python: >=3.9
|
|
28
|
+
Description-Content-Type: text/markdown
|
|
29
|
+
License-File: LICENSE
|
|
30
|
+
Requires-Dist: qsp-core>=0.1.0
|
|
31
|
+
Requires-Dist: numpy>=1.24
|
|
32
|
+
Provides-Extra: dev
|
|
33
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
34
|
+
Requires-Dist: pytest-cov; extra == "dev"
|
|
35
|
+
Dynamic: license-file
|
|
36
|
+
|
|
37
|
+
<img src="https://github.com/RQM-Technologies-dev/qsp-fft/actions/workflows/ci.yml/badge.svg" alt="CI Status">
|
|
38
|
+
|
|
39
|
+
# qsp-fft
|
|
40
|
+
|
|
41
|
+
**Spectral-transform primitives library for the RQM Technologies QSP ecosystem.**
|
|
42
|
+
|
|
43
|
+
`qsp-fft` is the **Layer-1 QSP library** for reusable spectral-analysis
|
|
44
|
+
primitives. It provides windowing, spectral analysis, and frequency utilities
|
|
45
|
+
as a focused, composable building block for downstream signal-analysis systems.
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Role in the QSP Ecosystem
|
|
50
|
+
|
|
51
|
+
`qsp-fft` is one layer in the RQM Technologies Quaternionic Signal Processing
|
|
52
|
+
(QSP) platform:
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
┌─────────────────────────────────────────────┐
|
|
56
|
+
│ Downstream / Application layer │
|
|
57
|
+
│ (quaternionic-modem, sensing pipelines, …) │
|
|
58
|
+
└─────────────────┬───────────────────────────┘
|
|
59
|
+
│ uses
|
|
60
|
+
┌─────────────────▼───────────────────────────┐
|
|
61
|
+
│ qsp-filter · qsp-modulation │
|
|
62
|
+
│ qsp-orientation · … │
|
|
63
|
+
└─────────────────┬───────────────────────────┘
|
|
64
|
+
│ uses
|
|
65
|
+
┌─────────────────▼───────────────────────────┐
|
|
66
|
+
│ qsp-fft │ ← THIS REPO
|
|
67
|
+
│ spectrum · windows · frequency bins │
|
|
68
|
+
└─────────────────┬───────────────────────────┘
|
|
69
|
+
│ imports
|
|
70
|
+
┌─────────────────▼───────────────────────────┐
|
|
71
|
+
│ qsp-core │
|
|
72
|
+
│ Quaternion · SU(2) helpers │
|
|
73
|
+
└─────────────────────────────────────────────┘
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
This repository provides:
|
|
77
|
+
|
|
78
|
+
- **FFT-based spectrum helpers** — magnitude spectrum, power spectrum
|
|
79
|
+
- **Frequency-bin generation** — one-sided frequency axes from FFT length and sample rate
|
|
80
|
+
- **Lightweight window functions** — rectangular, Hann, Hamming
|
|
81
|
+
- **Reusable building blocks** for downstream signal-analysis, communications, and sensing systems
|
|
82
|
+
|
|
83
|
+
`qsp-fft` is intended to support higher-level systems without becoming a full
|
|
84
|
+
signal-analysis application framework. It stays small, composable, and focused.
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Why This Repo Matters
|
|
89
|
+
|
|
90
|
+
Frequency-domain analysis is central to many signal-processing workflows.
|
|
91
|
+
`qsp-fft` provides the reusable spectral primitives that make the following
|
|
92
|
+
practical across the QSP ecosystem:
|
|
93
|
+
|
|
94
|
+
- **Waveform inspection** — verify spectral content of generated or received signals
|
|
95
|
+
- **Signal diagnostics** — identify dominant frequencies and energy distribution
|
|
96
|
+
- **Spectrum-based experiments** — prototype analysis algorithms on top of stable helpers
|
|
97
|
+
- **Communications prototyping** — inspect modulated waveforms before and after transmission
|
|
98
|
+
- **Downstream receiver and sensing pipelines** — feed clean spectral representations into classification and detection systems
|
|
99
|
+
|
|
100
|
+
Without a shared spectral layer, every downstream package would reimplement
|
|
101
|
+
the same FFT wrappers, window functions, and frequency-bin generators
|
|
102
|
+
inconsistently. `qsp-fft` is the single source of truth for these primitives.
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## QSP Perspective
|
|
107
|
+
|
|
108
|
+
Within the QSP ecosystem, spectral analysis is not just a convenience for
|
|
109
|
+
plotting frequency content. It is one of the primary ways structured signal
|
|
110
|
+
behavior becomes measurable and comparable across domains. `qsp-fft` provides
|
|
111
|
+
the reusable spectral primitives needed by downstream communication, sensing,
|
|
112
|
+
and analysis systems without embedding high-level application logic at the
|
|
113
|
+
library layer.
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## What belongs here vs. what does not
|
|
118
|
+
|
|
119
|
+
### Belongs in qsp-fft
|
|
120
|
+
|
|
121
|
+
| Category | Examples |
|
|
122
|
+
|----------|---------|
|
|
123
|
+
| FFT wrappers / helpers | `magnitude_spectrum`, `power_spectrum` |
|
|
124
|
+
| Frequency-axis helpers | `frequency_bins` |
|
|
125
|
+
| Window functions | `rectangular_window`, `hann_window`, `hamming_window` |
|
|
126
|
+
| Spectral analysis primitives | `dominant_frequency_value`, `spectral_energy` |
|
|
127
|
+
| Utility helpers for spectral work | `next_power_of_two`, `normalise_signal` |
|
|
128
|
+
| Spectral-analysis demos / examples | `examples/spectrum_demo.py`, `examples/window_demo.py` |
|
|
129
|
+
|
|
130
|
+
### Does NOT belong in qsp-fft
|
|
131
|
+
|
|
132
|
+
| What | Where it belongs |
|
|
133
|
+
|------|-----------------|
|
|
134
|
+
| Generic quaternion algebra | `qsp-core` |
|
|
135
|
+
| Filtering and normalization pipelines | `qsp-filter` |
|
|
136
|
+
| Digital modulation / IQ / symbol schemes | `qsp-modulation` |
|
|
137
|
+
| IMU / orientation / rotation logic | `qsp-orientation` |
|
|
138
|
+
| Plotting-heavy dashboards | downstream application repos |
|
|
139
|
+
| Complete signal-analysis frameworks | downstream application repos |
|
|
140
|
+
| Application-specific detection / classification | downstream application repos |
|
|
141
|
+
| SDR / hardware integrations | downstream application repos |
|
|
142
|
+
| End-to-end modem or communication receiver logic | `quaternionic-modem` or equivalent |
|
|
143
|
+
| Large statistical analysis layers | downstream application repos |
|
|
144
|
+
|
|
145
|
+
`qsp-fft` is a **building-block spectral library**, not a full analysis application.
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## Relationship to qsp-core
|
|
150
|
+
|
|
151
|
+
`qsp-core` is the intended home for shared quaternion primitives and
|
|
152
|
+
foundational math utilities. `qsp-fft` builds spectral-analysis helpers on
|
|
153
|
+
top of that foundation.
|
|
154
|
+
|
|
155
|
+
```
|
|
156
|
+
qsp-core → Quaternion class, SU(2) helpers, quaternion arithmetic
|
|
157
|
+
qsp-fft → FFT wrappers, window functions, spectral analysis helpers
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Current implementations in `qsp-fft` primarily rely on NumPy and standard
|
|
161
|
+
signal-processing math (`np.fft.rfft`, `np.fft.rfftfreq`). This is
|
|
162
|
+
acceptable: the spectral domain does not always require quaternion types
|
|
163
|
+
directly. However, when a future feature does require quaternion types (for
|
|
164
|
+
example, quaternion-valued FFT analysis), `qsp-fft` will import from
|
|
165
|
+
`qsp-core` rather than reimplement those primitives.
|
|
166
|
+
|
|
167
|
+
The dependency is declared in `pyproject.toml` so the architectural
|
|
168
|
+
relationship is explicit even where it is not yet exercised in code.
|
|
169
|
+
|
|
170
|
+
Install both packages:
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
pip install qsp-core qsp-fft
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Or, for a local development install of this repo:
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
pip install -e ".[dev]"
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## Quick start
|
|
185
|
+
|
|
186
|
+
```python
|
|
187
|
+
import numpy as np
|
|
188
|
+
from qsp.fft import magnitude_spectrum, frequency_bins, hann_window
|
|
189
|
+
|
|
190
|
+
# Build a simple sinusoidal signal
|
|
191
|
+
sample_rate = 1000 # Hz
|
|
192
|
+
n = 512
|
|
193
|
+
t = np.arange(n) / sample_rate
|
|
194
|
+
signal = np.sin(2 * np.pi * 50 * t) # 50 Hz tone
|
|
195
|
+
|
|
196
|
+
# Apply a Hann window and compute the spectrum
|
|
197
|
+
window = hann_window(n)
|
|
198
|
+
mag = magnitude_spectrum(signal * window)
|
|
199
|
+
freqs = frequency_bins(n, sample_rate)
|
|
200
|
+
|
|
201
|
+
peak_idx = int(np.argmax(mag))
|
|
202
|
+
print(f"Peak frequency: {freqs[peak_idx]:.1f} Hz") # → 50.0 Hz
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## Relationship to qsp-filter and qsp-modulation
|
|
206
|
+
|
|
207
|
+
These three repositories are **complementary and often used together**, but
|
|
208
|
+
their responsibilities are distinct:
|
|
209
|
+
|
|
210
|
+
| Repository | Responsibility |
|
|
211
|
+
|------------|---------------|
|
|
212
|
+
| `qsp-fft` | Spectral transforms, spectrum extraction, frequency-bin generation, windowing |
|
|
213
|
+
| `qsp-filter` | Filtering pipelines, FIR/IIR design, normalization workflows |
|
|
214
|
+
| `qsp-modulation` | Modulation schemes, IQ generation, symbol-level primitives |
|
|
215
|
+
|
|
216
|
+
A typical analysis pipeline might apply `qsp-modulation` to generate a
|
|
217
|
+
waveform, run `qsp-fft` to inspect its spectrum, and then pass results through
|
|
218
|
+
`qsp-filter` — but each repo keeps its own scope clean.
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## Downstream Systems
|
|
223
|
+
|
|
224
|
+
`qsp-fft` is a building block for Layer-2 repositories and application-level
|
|
225
|
+
systems. Examples of downstream use include:
|
|
226
|
+
|
|
227
|
+
- **`quaternionic-modem`** — combines modulation, spectral analysis, and filtering into a cohesive communications pipeline
|
|
228
|
+
- **Communication-analysis pipelines** — use magnitude/power spectra to characterize channel conditions
|
|
229
|
+
- **Waveform inspection tools** — use frequency-bin helpers to label and display spectral data
|
|
230
|
+
- **Spectral diagnostics in sensor systems** — feed `spectral_energy` and `dominant_frequency_value` results into classification layers
|
|
231
|
+
- **Downstream experiments** — combine `qsp-fft`, `qsp-filter`, and `qsp-modulation` to prototype novel signal-processing algorithms
|
|
232
|
+
|
|
233
|
+
See [docs/downstream-usage.md](docs/downstream-usage.md) for concrete usage patterns.
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## Spectral Conventions
|
|
238
|
+
|
|
239
|
+
All functions in `qsp-fft` follow a consistent set of conventions:
|
|
240
|
+
|
|
241
|
+
| Convention | Detail |
|
|
242
|
+
|-----------|--------|
|
|
243
|
+
| **One-sided FFT** | All spectrum functions use `np.fft.rfft` / `np.fft.rfftfreq` and return only non-negative frequency components of length `n // 2 + 1` |
|
|
244
|
+
| **Frequency bins** | `frequency_bins(n, sample_rate)` returns bin centres in Hz; `sample_rate=1.0` gives normalised frequency |
|
|
245
|
+
| **Magnitude spectrum** | Raw `|FFT(signal)|` — not divided by `n`. Downstream callers should normalise if needed. |
|
|
246
|
+
| **Power spectrum** | `|FFT(signal)|²`, i.e., element-wise square of the magnitude spectrum |
|
|
247
|
+
| **Input signals** | All helpers accept real-valued 1-D NumPy arrays. Complex-valued input is not a primary target in the current release. |
|
|
248
|
+
| **Window conventions** | Window functions use the symmetric formula `0.5 * (1 - cos(2π k / (n-1)))` so that both endpoints are included in the taper |
|
|
249
|
+
| **Sample rate default** | Functions that accept `sample_rate` default to `1.0` (normalised units) so they are usable without a known sample rate |
|
|
250
|
+
|
|
251
|
+
These conventions should remain stable across releases. If they must change,
|
|
252
|
+
the change should be intentional, versioned, and documented.
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
## Future Extensions
|
|
257
|
+
|
|
258
|
+
See [docs/repo-roadmap.md](docs/repo-roadmap.md) for a detailed forward-looking
|
|
259
|
+
guide. In brief, appropriate future additions include:
|
|
260
|
+
|
|
261
|
+
- Additional window functions (Blackman, Kaiser, flat-top, …)
|
|
262
|
+
- Spectral-density helpers
|
|
263
|
+
- Short-time / block-based FFT utilities (STFT)
|
|
264
|
+
- Spectral peak extraction helpers
|
|
265
|
+
- More robust normalization and scaling options
|
|
266
|
+
- Spectral comparison utilities
|
|
267
|
+
|
|
268
|
+
Additions that do **not** belong here (they belong in downstream or sibling repos):
|
|
269
|
+
|
|
270
|
+
- Full plotting or reporting suites
|
|
271
|
+
- Detection or classification systems
|
|
272
|
+
- Equalizers, synchronization loops, or filtering pipelines
|
|
273
|
+
- Communications protocol logic
|
|
274
|
+
- Hardware or SDR interfaces
|
|
275
|
+
- End-to-end modem applications
|
|
276
|
+
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
## Running tests
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
pytest
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
---
|
|
286
|
+
|
|
287
|
+
## Running examples
|
|
288
|
+
|
|
289
|
+
```bash
|
|
290
|
+
python examples/spectrum_demo.py
|
|
291
|
+
python examples/window_demo.py
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
---
|
|
295
|
+
|
|
296
|
+
## Repository layout
|
|
297
|
+
|
|
298
|
+
```
|
|
299
|
+
qsp-fft
|
|
300
|
+
├── AGENTS.md
|
|
301
|
+
├── README.md
|
|
302
|
+
├── pyproject.toml
|
|
303
|
+
├── qsp/
|
|
304
|
+
│ └── fft/
|
|
305
|
+
│ ├── __init__.py
|
|
306
|
+
│ ├── spectrum.py
|
|
307
|
+
│ ├── windows.py
|
|
308
|
+
│ ├── analysis.py
|
|
309
|
+
│ └── utils.py
|
|
310
|
+
├── tests/
|
|
311
|
+
│ ├── test_spectrum.py
|
|
312
|
+
│ ├── test_windows.py
|
|
313
|
+
│ ├── test_analysis.py
|
|
314
|
+
│ └── test_package_api.py
|
|
315
|
+
├── examples/
|
|
316
|
+
│ ├── spectrum_demo.py
|
|
317
|
+
│ └── window_demo.py
|
|
318
|
+
└── docs/
|
|
319
|
+
├── architecture.md
|
|
320
|
+
├── api-overview.md
|
|
321
|
+
├── dependency-on-qsp-core.md
|
|
322
|
+
├── downstream-usage.md
|
|
323
|
+
└── repo-roadmap.md
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
---
|
|
327
|
+
|
|
328
|
+
## Publishing
|
|
329
|
+
|
|
330
|
+
Releases are automatically published to PyPI using GitHub Actions and PyPI Trusted Publishing.
|
|
331
|
+
|
|
332
|
+
---
|
|
333
|
+
|
|
334
|
+
## License
|
|
335
|
+
|
|
336
|
+
See [LICENSE](LICENSE).
|
qsp_fft-0.1.2/README.md
ADDED
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
<img src="https://github.com/RQM-Technologies-dev/qsp-fft/actions/workflows/ci.yml/badge.svg" alt="CI Status">
|
|
2
|
+
|
|
3
|
+
# qsp-fft
|
|
4
|
+
|
|
5
|
+
**Spectral-transform primitives library for the RQM Technologies QSP ecosystem.**
|
|
6
|
+
|
|
7
|
+
`qsp-fft` is the **Layer-1 QSP library** for reusable spectral-analysis
|
|
8
|
+
primitives. It provides windowing, spectral analysis, and frequency utilities
|
|
9
|
+
as a focused, composable building block for downstream signal-analysis systems.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Role in the QSP Ecosystem
|
|
14
|
+
|
|
15
|
+
`qsp-fft` is one layer in the RQM Technologies Quaternionic Signal Processing
|
|
16
|
+
(QSP) platform:
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
┌─────────────────────────────────────────────┐
|
|
20
|
+
│ Downstream / Application layer │
|
|
21
|
+
│ (quaternionic-modem, sensing pipelines, …) │
|
|
22
|
+
└─────────────────┬───────────────────────────┘
|
|
23
|
+
│ uses
|
|
24
|
+
┌─────────────────▼───────────────────────────┐
|
|
25
|
+
│ qsp-filter · qsp-modulation │
|
|
26
|
+
│ qsp-orientation · … │
|
|
27
|
+
└─────────────────┬───────────────────────────┘
|
|
28
|
+
│ uses
|
|
29
|
+
┌─────────────────▼───────────────────────────┐
|
|
30
|
+
│ qsp-fft │ ← THIS REPO
|
|
31
|
+
│ spectrum · windows · frequency bins │
|
|
32
|
+
└─────────────────┬───────────────────────────┘
|
|
33
|
+
│ imports
|
|
34
|
+
┌─────────────────▼───────────────────────────┐
|
|
35
|
+
│ qsp-core │
|
|
36
|
+
│ Quaternion · SU(2) helpers │
|
|
37
|
+
└─────────────────────────────────────────────┘
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
This repository provides:
|
|
41
|
+
|
|
42
|
+
- **FFT-based spectrum helpers** — magnitude spectrum, power spectrum
|
|
43
|
+
- **Frequency-bin generation** — one-sided frequency axes from FFT length and sample rate
|
|
44
|
+
- **Lightweight window functions** — rectangular, Hann, Hamming
|
|
45
|
+
- **Reusable building blocks** for downstream signal-analysis, communications, and sensing systems
|
|
46
|
+
|
|
47
|
+
`qsp-fft` is intended to support higher-level systems without becoming a full
|
|
48
|
+
signal-analysis application framework. It stays small, composable, and focused.
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Why This Repo Matters
|
|
53
|
+
|
|
54
|
+
Frequency-domain analysis is central to many signal-processing workflows.
|
|
55
|
+
`qsp-fft` provides the reusable spectral primitives that make the following
|
|
56
|
+
practical across the QSP ecosystem:
|
|
57
|
+
|
|
58
|
+
- **Waveform inspection** — verify spectral content of generated or received signals
|
|
59
|
+
- **Signal diagnostics** — identify dominant frequencies and energy distribution
|
|
60
|
+
- **Spectrum-based experiments** — prototype analysis algorithms on top of stable helpers
|
|
61
|
+
- **Communications prototyping** — inspect modulated waveforms before and after transmission
|
|
62
|
+
- **Downstream receiver and sensing pipelines** — feed clean spectral representations into classification and detection systems
|
|
63
|
+
|
|
64
|
+
Without a shared spectral layer, every downstream package would reimplement
|
|
65
|
+
the same FFT wrappers, window functions, and frequency-bin generators
|
|
66
|
+
inconsistently. `qsp-fft` is the single source of truth for these primitives.
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## QSP Perspective
|
|
71
|
+
|
|
72
|
+
Within the QSP ecosystem, spectral analysis is not just a convenience for
|
|
73
|
+
plotting frequency content. It is one of the primary ways structured signal
|
|
74
|
+
behavior becomes measurable and comparable across domains. `qsp-fft` provides
|
|
75
|
+
the reusable spectral primitives needed by downstream communication, sensing,
|
|
76
|
+
and analysis systems without embedding high-level application logic at the
|
|
77
|
+
library layer.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## What belongs here vs. what does not
|
|
82
|
+
|
|
83
|
+
### Belongs in qsp-fft
|
|
84
|
+
|
|
85
|
+
| Category | Examples |
|
|
86
|
+
|----------|---------|
|
|
87
|
+
| FFT wrappers / helpers | `magnitude_spectrum`, `power_spectrum` |
|
|
88
|
+
| Frequency-axis helpers | `frequency_bins` |
|
|
89
|
+
| Window functions | `rectangular_window`, `hann_window`, `hamming_window` |
|
|
90
|
+
| Spectral analysis primitives | `dominant_frequency_value`, `spectral_energy` |
|
|
91
|
+
| Utility helpers for spectral work | `next_power_of_two`, `normalise_signal` |
|
|
92
|
+
| Spectral-analysis demos / examples | `examples/spectrum_demo.py`, `examples/window_demo.py` |
|
|
93
|
+
|
|
94
|
+
### Does NOT belong in qsp-fft
|
|
95
|
+
|
|
96
|
+
| What | Where it belongs |
|
|
97
|
+
|------|-----------------|
|
|
98
|
+
| Generic quaternion algebra | `qsp-core` |
|
|
99
|
+
| Filtering and normalization pipelines | `qsp-filter` |
|
|
100
|
+
| Digital modulation / IQ / symbol schemes | `qsp-modulation` |
|
|
101
|
+
| IMU / orientation / rotation logic | `qsp-orientation` |
|
|
102
|
+
| Plotting-heavy dashboards | downstream application repos |
|
|
103
|
+
| Complete signal-analysis frameworks | downstream application repos |
|
|
104
|
+
| Application-specific detection / classification | downstream application repos |
|
|
105
|
+
| SDR / hardware integrations | downstream application repos |
|
|
106
|
+
| End-to-end modem or communication receiver logic | `quaternionic-modem` or equivalent |
|
|
107
|
+
| Large statistical analysis layers | downstream application repos |
|
|
108
|
+
|
|
109
|
+
`qsp-fft` is a **building-block spectral library**, not a full analysis application.
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Relationship to qsp-core
|
|
114
|
+
|
|
115
|
+
`qsp-core` is the intended home for shared quaternion primitives and
|
|
116
|
+
foundational math utilities. `qsp-fft` builds spectral-analysis helpers on
|
|
117
|
+
top of that foundation.
|
|
118
|
+
|
|
119
|
+
```
|
|
120
|
+
qsp-core → Quaternion class, SU(2) helpers, quaternion arithmetic
|
|
121
|
+
qsp-fft → FFT wrappers, window functions, spectral analysis helpers
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Current implementations in `qsp-fft` primarily rely on NumPy and standard
|
|
125
|
+
signal-processing math (`np.fft.rfft`, `np.fft.rfftfreq`). This is
|
|
126
|
+
acceptable: the spectral domain does not always require quaternion types
|
|
127
|
+
directly. However, when a future feature does require quaternion types (for
|
|
128
|
+
example, quaternion-valued FFT analysis), `qsp-fft` will import from
|
|
129
|
+
`qsp-core` rather than reimplement those primitives.
|
|
130
|
+
|
|
131
|
+
The dependency is declared in `pyproject.toml` so the architectural
|
|
132
|
+
relationship is explicit even where it is not yet exercised in code.
|
|
133
|
+
|
|
134
|
+
Install both packages:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
pip install qsp-core qsp-fft
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Or, for a local development install of this repo:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
pip install -e ".[dev]"
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## Quick start
|
|
149
|
+
|
|
150
|
+
```python
|
|
151
|
+
import numpy as np
|
|
152
|
+
from qsp.fft import magnitude_spectrum, frequency_bins, hann_window
|
|
153
|
+
|
|
154
|
+
# Build a simple sinusoidal signal
|
|
155
|
+
sample_rate = 1000 # Hz
|
|
156
|
+
n = 512
|
|
157
|
+
t = np.arange(n) / sample_rate
|
|
158
|
+
signal = np.sin(2 * np.pi * 50 * t) # 50 Hz tone
|
|
159
|
+
|
|
160
|
+
# Apply a Hann window and compute the spectrum
|
|
161
|
+
window = hann_window(n)
|
|
162
|
+
mag = magnitude_spectrum(signal * window)
|
|
163
|
+
freqs = frequency_bins(n, sample_rate)
|
|
164
|
+
|
|
165
|
+
peak_idx = int(np.argmax(mag))
|
|
166
|
+
print(f"Peak frequency: {freqs[peak_idx]:.1f} Hz") # → 50.0 Hz
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Relationship to qsp-filter and qsp-modulation
|
|
170
|
+
|
|
171
|
+
These three repositories are **complementary and often used together**, but
|
|
172
|
+
their responsibilities are distinct:
|
|
173
|
+
|
|
174
|
+
| Repository | Responsibility |
|
|
175
|
+
|------------|---------------|
|
|
176
|
+
| `qsp-fft` | Spectral transforms, spectrum extraction, frequency-bin generation, windowing |
|
|
177
|
+
| `qsp-filter` | Filtering pipelines, FIR/IIR design, normalization workflows |
|
|
178
|
+
| `qsp-modulation` | Modulation schemes, IQ generation, symbol-level primitives |
|
|
179
|
+
|
|
180
|
+
A typical analysis pipeline might apply `qsp-modulation` to generate a
|
|
181
|
+
waveform, run `qsp-fft` to inspect its spectrum, and then pass results through
|
|
182
|
+
`qsp-filter` — but each repo keeps its own scope clean.
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## Downstream Systems
|
|
187
|
+
|
|
188
|
+
`qsp-fft` is a building block for Layer-2 repositories and application-level
|
|
189
|
+
systems. Examples of downstream use include:
|
|
190
|
+
|
|
191
|
+
- **`quaternionic-modem`** — combines modulation, spectral analysis, and filtering into a cohesive communications pipeline
|
|
192
|
+
- **Communication-analysis pipelines** — use magnitude/power spectra to characterize channel conditions
|
|
193
|
+
- **Waveform inspection tools** — use frequency-bin helpers to label and display spectral data
|
|
194
|
+
- **Spectral diagnostics in sensor systems** — feed `spectral_energy` and `dominant_frequency_value` results into classification layers
|
|
195
|
+
- **Downstream experiments** — combine `qsp-fft`, `qsp-filter`, and `qsp-modulation` to prototype novel signal-processing algorithms
|
|
196
|
+
|
|
197
|
+
See [docs/downstream-usage.md](docs/downstream-usage.md) for concrete usage patterns.
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## Spectral Conventions
|
|
202
|
+
|
|
203
|
+
All functions in `qsp-fft` follow a consistent set of conventions:
|
|
204
|
+
|
|
205
|
+
| Convention | Detail |
|
|
206
|
+
|-----------|--------|
|
|
207
|
+
| **One-sided FFT** | All spectrum functions use `np.fft.rfft` / `np.fft.rfftfreq` and return only non-negative frequency components of length `n // 2 + 1` |
|
|
208
|
+
| **Frequency bins** | `frequency_bins(n, sample_rate)` returns bin centres in Hz; `sample_rate=1.0` gives normalised frequency |
|
|
209
|
+
| **Magnitude spectrum** | Raw `|FFT(signal)|` — not divided by `n`. Downstream callers should normalise if needed. |
|
|
210
|
+
| **Power spectrum** | `|FFT(signal)|²`, i.e., element-wise square of the magnitude spectrum |
|
|
211
|
+
| **Input signals** | All helpers accept real-valued 1-D NumPy arrays. Complex-valued input is not a primary target in the current release. |
|
|
212
|
+
| **Window conventions** | Window functions use the symmetric formula `0.5 * (1 - cos(2π k / (n-1)))` so that both endpoints are included in the taper |
|
|
213
|
+
| **Sample rate default** | Functions that accept `sample_rate` default to `1.0` (normalised units) so they are usable without a known sample rate |
|
|
214
|
+
|
|
215
|
+
These conventions should remain stable across releases. If they must change,
|
|
216
|
+
the change should be intentional, versioned, and documented.
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## Future Extensions
|
|
221
|
+
|
|
222
|
+
See [docs/repo-roadmap.md](docs/repo-roadmap.md) for a detailed forward-looking
|
|
223
|
+
guide. In brief, appropriate future additions include:
|
|
224
|
+
|
|
225
|
+
- Additional window functions (Blackman, Kaiser, flat-top, …)
|
|
226
|
+
- Spectral-density helpers
|
|
227
|
+
- Short-time / block-based FFT utilities (STFT)
|
|
228
|
+
- Spectral peak extraction helpers
|
|
229
|
+
- More robust normalization and scaling options
|
|
230
|
+
- Spectral comparison utilities
|
|
231
|
+
|
|
232
|
+
Additions that do **not** belong here (they belong in downstream or sibling repos):
|
|
233
|
+
|
|
234
|
+
- Full plotting or reporting suites
|
|
235
|
+
- Detection or classification systems
|
|
236
|
+
- Equalizers, synchronization loops, or filtering pipelines
|
|
237
|
+
- Communications protocol logic
|
|
238
|
+
- Hardware or SDR interfaces
|
|
239
|
+
- End-to-end modem applications
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
## Running tests
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
pytest
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## Running examples
|
|
252
|
+
|
|
253
|
+
```bash
|
|
254
|
+
python examples/spectrum_demo.py
|
|
255
|
+
python examples/window_demo.py
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## Repository layout
|
|
261
|
+
|
|
262
|
+
```
|
|
263
|
+
qsp-fft
|
|
264
|
+
├── AGENTS.md
|
|
265
|
+
├── README.md
|
|
266
|
+
├── pyproject.toml
|
|
267
|
+
├── qsp/
|
|
268
|
+
│ └── fft/
|
|
269
|
+
│ ├── __init__.py
|
|
270
|
+
│ ├── spectrum.py
|
|
271
|
+
│ ├── windows.py
|
|
272
|
+
│ ├── analysis.py
|
|
273
|
+
│ └── utils.py
|
|
274
|
+
├── tests/
|
|
275
|
+
│ ├── test_spectrum.py
|
|
276
|
+
│ ├── test_windows.py
|
|
277
|
+
│ ├── test_analysis.py
|
|
278
|
+
│ └── test_package_api.py
|
|
279
|
+
├── examples/
|
|
280
|
+
│ ├── spectrum_demo.py
|
|
281
|
+
│ └── window_demo.py
|
|
282
|
+
└── docs/
|
|
283
|
+
├── architecture.md
|
|
284
|
+
├── api-overview.md
|
|
285
|
+
├── dependency-on-qsp-core.md
|
|
286
|
+
├── downstream-usage.md
|
|
287
|
+
└── repo-roadmap.md
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
## Publishing
|
|
293
|
+
|
|
294
|
+
Releases are automatically published to PyPI using GitHub Actions and PyPI Trusted Publishing.
|
|
295
|
+
|
|
296
|
+
---
|
|
297
|
+
|
|
298
|
+
## License
|
|
299
|
+
|
|
300
|
+
See [LICENSE](LICENSE).
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "qsp-fft"
|
|
7
|
+
version = "0.1.2"
|
|
8
|
+
description = "Spectral-transform library built on qsp-core for the RQM Technologies ecosystem"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = { file = "LICENSE" }
|
|
11
|
+
requires-python = ">=3.9"
|
|
12
|
+
dependencies = [
|
|
13
|
+
"qsp-core>=0.1.0",
|
|
14
|
+
"numpy>=1.24",
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
[project.optional-dependencies]
|
|
18
|
+
dev = [
|
|
19
|
+
"pytest>=7.0",
|
|
20
|
+
"pytest-cov",
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
[tool.setuptools.packages.find]
|
|
24
|
+
where = ["."]
|
|
25
|
+
namespaces = true
|
|
26
|
+
include = ["qsp*"]
|
|
27
|
+
|
|
28
|
+
[tool.pytest.ini_options]
|
|
29
|
+
testpaths = ["tests"]
|