pyPhyNR
Python tools for NR resource grids, PDSCH/DMRS and complex OFDM waveform generation.
Version 0.2.0 adds composite waveform generation, relative carrier gains and optional equal average PSD. Carrier RB counts are selected from bandwidth and numerology; FFT size is derived from sampling rate divided by subcarrier spacing.
Installation
python -m pip install --upgrade pyPhyNR
Python 3.9 or later is required. Runtime dependencies are NumPy, SciPy and Matplotlib.
For the example notebooks, install pyPhyNR[notebooks] and select a Python kernel
with that package installed. For a source checkout, use
python -m pip install -e ".[notebooks]" from the repository root.
Single carrier
import pyPhyNR as pynr
signal = pynr.NRSignalBuilder(bandwidth_mhz=100, numerology=1, cell_id=1)
signal.configure_carrier(sample_rate=245.76e6).initialize_grid()
signal.add_pdsch(
start_rb=0,
num_rb=signal.carrier_config.n_resource_blocks,
start_symbol=0,
num_symbols=14,
slot_pattern=list(range(signal.carrier_config.numerology.slots_per_frame)),
modulation="QAM256",
).add_dmrs(dmrs_positions=[2, 11], clear_full_symbol=False)
iq = signal.generate_signal(target_rms=1.0)
pynr.utils.plot_frequency_domain(iq, signal.carrier_config)
Numerology 0 selects 15 kHz SCS and numerology 1 selects 30 kHz. For the example above, the carrier has 273 RBs and an 8192-point FFT. PDSCH can fill the carrier using its derived RB count, or occupy a smaller allocation using an explicit count.
Composite waveform
Populate a second carrier independently, then combine the two resource grids:
second = pynr.NRSignalBuilder(bandwidth_mhz=100, numerology=1, cell_id=2)
second.configure_carrier(sample_rate=245.76e6).initialize_grid()
second.add_pdsch(
start_rb=0,
num_rb=second.carrier_config.n_resource_blocks,
start_symbol=0,
num_symbols=14,
slot_pattern=list(range(second.carrier_config.numerology.slots_per_frame)),
modulation="QAM256",
).add_dmrs(dmrs_positions=[2, 11], clear_full_symbol=False)
composite = pynr.NRCompositeSignalBuilder(sample_rate=245.76e6, equal_psd=True)
composite.add_carrier(signal, frequency_offset_hz=-50e6)
composite.add_carrier(second, frequency_offset_hz=50e6, gain_db=0.0)
iq = composite.generate_signal(target_rms=1.0)
pynr.utils.plot_frequency_domain(iq, composite)
Frequency offsets are relative to output DC. gain_db=-3 lowers a carrier by 3 dB.
equal_psd=True sets each carrier's average power in proportion to its allocated
bandwidth; use it for mixed bandwidths such as NR100 + NR10 + NR5. Leave per-carrier
target_rms unset in this mode. The final target_rms sets the composite RMS while
preserving relative carrier powers. IQ amplitudes are not clipped.
Composite generation supports a common 15 or 30 kHz SCS, normal CP and one 10 ms frame. Carriers are synthesized directly at the output sampling rate without changing their input configurations. Overlapping allocations and carriers outside the output Nyquist interval are rejected. Equal PSD refers to average power per allocated Hz; differently loaded or bursty grids can have different active-symbol PSD.
Examples
- Two adjacent NR100 carriers:
notebooks/nr_2x100mhz_composite.ipynb - Mixed NR100 + NR10 + NR5:
notebooks/nr100_nr10_nr5_composite.ipynb - Single-carrier 64-QAM:
notebooks/nr20m_64qam_test.ipynb - Single-carrier 256-QAM:
notebooks/nr20m_256qam_test.ipynb - TDD waveform:
notebooks/nr20m_tdd_udc38_test.ipynb
Notebooks use the installed library and its plotting helpers. Optional TXT export uses NumPy. Download the notebooks in the source distribution from PyPI, or use this repository; generated IQ files and saved notebook outputs are excluded from the release.
Compatibility notes for 0.2.0
The existing pynr.NRSignalBuilder and pyPhyNR.core imports remain available.
Omit fft_size for automatic selection, including non-power-of-two FFTs such as
1920 at 57.6 Msps / 30 kHz. An explicit FFT size must equal sampling rate / SCS;
inconsistent values now raise an error instead of changing the waveform's SCS.
Notebook tools are an optional dependency via the notebooks extra. The historical
matlab_to_python_nr_gen helpers remain available for compatibility; new examples
use NRSignalBuilder.
This is an experimental signal-generation library, not a complete encoded NR link or an RF conformance certification tool. RF band/raster compatibility and other physical channels remain outside the composite generator's scope.
Build and release
python -m pip install ".[dev]"
python -m build
python -m twine check dist/*
python -m twine upload --repository-url https://upload.pypi.org/legacy/ dist/*
Use a PyPI API token through Twine's supported credential configuration.
License
MIT. Copyright kir812.
Metadata
Release files for pyPhyNR 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| pyphynr-0.2.0.tar.gz | 41.6 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pyphynr-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 84.3 kB
Release files / pyphynr-0.2.0.tar.gz
| Download URL | pyphynr-0.2.0.tar.gz |
|---|---|
| Size | 41.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7de90ebeb5cbc5b877967fd8c3feb6e38b7302fa1bd988bf7f7784a21cb36854
|
|
BLAKE2b-256 checksum How to use checksums |
43468739a47634653f7bf7f9c86d36d3a0626e674cb01eb9d96a5c73028b5658
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.5
|
Release files / pyphynr-0.2.0-py3-none-any.whl
| Download URL | pyphynr-0.2.0-py3-none-any.whl |
|---|---|
| Size | 42.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
64200e446c5f8033589cb8cddd4a09db92f5b576f4d9b396fa6fd9b5a2ae88bd
|
|
BLAKE2b-256 checksum How to use checksums |
50a4b61e2d2cbf5577924380a61c6c671bebaf497370dd5ecae7e049107a20d0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.5
|
Security for pyPhyNR 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.