Lab 9.2 — Read CI16 IQ and Analyze Spectrum¶
Goal¶
Read a CI16 IQ recording using metadata JSON, convert it to normalized complex samples, run basic quality checks and generate spectrum/time-domain report artifacts.
Executable files¶
| Environment | File | Output |
|---|---|---|
| Python | blocks/block_09_recording_and_analysis_tools/python/lab_9_2_read_ci16_iq_and_analyze.py |
synthetic CI16 file, plots and metrics JSON |
| JSON | blocks/block_09_recording_and_analysis_tools/assets/example_ci16_capture_metadata.json |
capture metadata |
Run from the repository root:
python blocks/block_09_recording_and_analysis_tools/python/lab_9_2_read_ci16_iq_and_analyze.py
Or analyze a real CI16 dataset manifest:
python blocks/block_09_recording_and_analysis_tools/python/lab_9_2_read_ci16_iq_and_analyze.py \
--manifest datasets/lab6_6_zynq_rx_observation/manifest_fm_103119454.yaml
Generated artifacts:
docs/assets/lab92_ci16_iq_spectrum.png
docs/assets/lab92_ci16_iq_time_preview.png
docs/assets/lab92_ci16_iq_metrics.json
blocks/block_09_recording_and_analysis_tools/assets/lab92_synthetic_ci16_tone.ci16
Processing chain¶
flowchart LR
META[Metadata JSON] --> GEN[Synthetic CI16 generator]
GEN --> FILE[CI16 IQ file]
FILE --> READ[CI16 reader]
READ --> FFT[FFT analysis]
READ --> QC[DC/clipping checks]
FFT --> METRICS[Peak, SNR, error]
QC --> METRICS
METRICS --> REPORT[Plots + metrics JSON]
Metrics¶
| Metric | Meaning |
|---|---|
sample_count_read |
number of complex samples read from file |
measured_peak_hz |
strongest FFT peak |
frequency_error_hz |
measured peak minus expected offset |
snr_db |
peak level minus median noise floor estimate |
dc_offset_magnitude |
magnitude of average complex sample |
clipping_fraction |
fraction of samples near full-scale |
quality_pass |
quick pass/fail based on metadata thresholds |
Transition to real captures¶
Replace the synthetic .ci16 file with a real recording and keep the same metadata fields:
real_capture.ci16 + real_capture.metadata.json -> reader -> FFT -> quality checks -> report
The manifest-driven mode accepts either:
- the original Lab 9.2 metadata JSON format; or
- a dataset-style YAML manifest with
file_name,sample_rate_hz,center_frequency_hz,endiannessandi_first.
What to expect¶
Samples read: 262144
Sample rate: 2400000 Hz
Center frequency: 915000000 Hz
Expected offset: 100000.000 Hz
Measured peak: 100012.207 Hz
Frequency error: 12.207 Hz
SNR estimate: 74.09 dB
DC offset magnitude: 0.011674
Clipping fraction: 0.000000e+00
Quality pass: True
- The synthetic capture carries a small deliberate DC offset (0.0117 of full scale). On a zero-IF receiver this is the spike at 0 Hz that Lab 6.5 calibrates out.
- As in Lab 6.4, the 12 Hz error is bin quantization and "SNR" is peak over median bin.
Exercises¶
- Run the reader on
datasets/lab6_6_zynq_rx_observation/manifest_fm_103119454.yaml(a real capture). Which quality numbers change most compared with the synthetic file, and why? - What
quality_passthresholds would you choose for DC offset and clipping for your own bench?
Report checklist¶
- Attach metadata JSON.
- Confirm CI16 file size and sample count.
- State sample rate and center frequency.
- Include spectrum plot.
- Include time-domain preview.
- Report peak frequency and frequency error.
- Report SNR, DC offset and clipping fraction.
- Conclude whether the capture is suitable for synchronization and demodulation.
Engineering conclusion template¶
The CI16 recording contains ____ complex samples at ____ MS/s. The expected signal offset is ____ kHz,
and the measured peak is ____ kHz. The estimated SNR is ____ dB, clipping fraction is ____,
and quality_pass is ____. The recording is / is not ready for further processing because ______.