Skip to main content

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)

Source distribution for pyPhyNR 0.2.0
File Size Uploaded Provenance
pyphynr-0.2.0.tar.gz 41.6 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for pyPhyNR 0.2.0
File Interpreter ABI Platform
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.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page