Quadriga-Lib
C++/MEX/Python Utility library for radio channel modelling and simulations
Python API Documentation for Quadriga-Lib v0.11.5


Notes

Overview
Array antenna functions
Channel functions
Channel generation functions
Miscellaneous / Tools
Site-specific simulation tools




Array antenna functions



calc_directivity - Calculates the directivity (in dBi) of array antenna elements

Description:
Directivity is a parameter of an antenna or which measures the degree to which the radiation emitted is concentrated in a single direction. It is the ratio of the radiation intensity in a given direction from the antenna to the radiation intensity averaged over all directions. Therefore, the directivity of a hypothetical isotropic radiator is 1, or 0 dBi. Usage:
from quadriga_lib import arrayant
directivity = arrayant.calc_directivity(arrayant, element)
Input Arguments:
Output Argument:


combine_pattern - Calculate effective radiation patterns for array antennas

Description:
An array antenna consists of multiple individual elements. Each element occupies a specific position relative to the array's phase-center, its local origin. Elements can also be inter-coupled, represented by a coupling matrix. By integrating the element radiation patterns, their positions, and the coupling weights, one can determine an effective radiation pattern observable by a receiver in the antenna's far field. Leveraging these effective patterns is especially beneficial in antenna design, beamforming applications such as in 5G systems, and in planning wireless communication networks in complex environments like urban areas. This streamlined approach offers a significant boost in computation speed when calculating MIMO channel coefficients, as it reduces the number of necessary operations. The function arrayant_combine_pattern is designed to compute these effective radiation patterns. Usage:
from quadriga_lib import arrayant

# Minimal example
arrayant_out = arrayant.combine_pattern(arrayant)

# Optional inputs: freq, azimuth_grid, elevation_grid
arrayant_out = arrayant.combine_pattern(arrayant, freq, azimuth_grid, elevation_grid)
Input Arguments:
Output Arguments:


copy_element - Create copies of array antenna elements

Description:
Copies one or more antenna elements to new positions within the arrayant, expanding the element count if necessary. Supports both single-frequency arrayants (3D pattern fields) and multi-frequency arrayants (4D pattern fields). For multi-frequency inputs, element copying is applied consistently across all frequency entries. The function auto-detects whether the input is single-frequency or multi-frequency by inspecting the dimensionality of the e_theta_re field (3D = single, 4D = multi). Usage:
from quadriga_lib import arrayant

# Single-frequency: copy element 0 to position 1
arrayant_out = arrayant.copy_element(ant, source_element=[0], dest_element=[1])

# Single-frequency: copy element 0 to positions 2 and 3
arrayant_out = arrayant.copy_element(ant, source_element=[0], dest_element=[2, 3])

# Multi-frequency (4D patterns): same interface
speaker_out = arrayant.copy_element(speaker, source_element=[0], dest_element=[1])

# Copy multiple sources to multiple destinations (must be same length)
arrayant_out = arrayant.copy_element(ant, source_element=[0, 1], dest_element=[2, 3])
Input Arguments:
Output Arguments:


export_obj_file - Creates a Wavefront OBJ file for visualizing the shape of the antenna pattern

Usage:
from quadriga_lib import arrayant
arrayant.export_obj_file( fn, arrayant, directivity_range, colormap,
                object_radius, icosphere_n_div, i_element )
Input Arguments:


generate - Generates predefined array antenna models

Description:
This functions can be used to generate a variety of pre-defined array antenna models, including 3GPP array antennas used for 5G-NR simulations. The first argument is the array type. The following input arguments are then specific to this type. Usage:
from quadriga_lib import arrayant

# Isotropic radiator, vertical polarization
arrayant = arrayant.generate('omni', res)

# Short dipole radiating with vertical polarization
arrayant = arrayant.generate('dipole', res)

# Half-wave dipole radiating with vertical polarization
arrayant = arrayant.generate('half-wave-dipole', res)

# Cross-polarized isotropic radiator
arrayant = arrayant.generate('xpol', res)

# A unified linear array with isotropic patterns
arrayant = arrayant.generate('ula', res=30, N=4, freq=2.4e9, spacing=0.7)

# An antenna with a custom 3dB beam with (in degree)
arrayant = arrayant.generate('custom', res, az_3dB, el_3db, rear_gain_lin)

# 3GPP-NR antenna model (example for 2x2, V-polarized, 0.7λ spacing)
arrayant = arrayant.generate('3gpp', M=2, N=2, freq=3.7e9, pol=1, spacing=0.7)

# Planar multi-element antenna with support for multiple beam directions
arrayant = arrayant.generate('multibeam', M=6, N=6, freq=3.7e9, pol=1, spacing=0.7, az=[-30.0, 30.0], el=[0.0, 0.0])
Input Arguments:
Input arguments for type `custom`, `3gpp` and `multibeam`:
Input arguments for type `3gpp` and `multibeam`:
Output Arguments:


generate_speaker - Generates a parametric loudspeaker directivity model

Description:
This function generates frequency-dependent loudspeaker radiation patterns by combining a driver directivity model with an enclosure radiation modifier and a Butterworth-style bandpass frequency response. Returns a multi-frequency arrayant dictionary where the pattern fields are 4D arrays (the 4th dimension is frequency) and center_freq is a 1D array of frequency samples in Hz. Multi-driver speakers (e.g. two-way systems) are modelled by generating each driver separately and combining them via arrayant_concat_multi. Crossover behavior emerges naturally from overlapping bandpass responses.

Three driver types are supported: Four enclosure radiation types modify the base driver pattern: The frequency response follows a Butterworth-style bandpass filter. If no frequency vector is provided, third-octave band center frequencies are auto-generated covering the range from one band below the lower cutoff to one band above the upper cutoff, clipped to 20–20000 Hz. Usage:
from quadriga_lib import arrayant

# Default piston driver (4-inch, 80 Hz – 12 kHz)
speaker = arrayant.generate_speaker()

# Horn tweeter with custom coverage
speaker = arrayant.generate_speaker(
    driver_type='horn',
    radius=0.025,
    lower_cutoff=1500.0,
    upper_cutoff=20000.0,
    radiation_type='hemisphere',
    hor_coverage=90.0,
    ver_coverage=60.0
)

# Omnidirectional subwoofer with steep rolloff
speaker = arrayant.generate_speaker(
    driver_type='omni',
    radius=0.165,
    lower_cutoff=30.0,
    upper_cutoff=300.0,
    lower_rolloff_slope=24.0,
    upper_rolloff_slope=24.0,
    sensitivity=90.0,
    radiation_type='monopole'
)

# Piston driver at specific frequencies
import numpy as np
speaker = arrayant.generate_speaker(
    frequencies=np.array([100.0, 500.0, 1000.0, 5000.0, 10000.0]),
    angular_resolution=5.0
)
Input Arguments:
Output Argument:


get_channels_multifreq - Calculate channel coefficients for spherical waves across multiple frequencies

Description:
Usage:
from quadriga_lib import arrayant
import numpy as np

coeff_re, coeff_im, delays = arrayant.get_channels_multifreq( ant_tx, ant_rx,
    fbs_pos, lbs_pos, path_gain, path_length, M, tx_pos, tx_orientation, rx_pos, rx_orientation,
    freq_in, freq_out, use_absolute_delays, add_fake_los_path, propagation_speed )
Input Arguments:
Derived inputs:
n_freq_in Number of input frequency samples (columns of path_gain, slices of M)
n_freq_out Number of output frequency samples (length of freq_out)
n_path Number of propagation paths (columns of fbs_pos)
n_ports_tx Number of TX antenna ports after coupling
n_ports_rx Number of RX antenna ports after coupling

Output Arguments:
Example:
from quadriga_lib import arrayant
import numpy as np

# Build a 2-way speaker as TX (source)
tx_woofer = arrayant.generate_speaker(
    driver_type='piston', radius=0.083,
    lower_cutoff=50.0, upper_cutoff=3000.0,
    lower_rolloff_slope=12.0, upper_rolloff_slope=24.0, sensitivity=87.0,
    radiation_type='hemisphere', baffle_width=0.20, baffle_height=0.30,
    frequencies=np.array([100.0, 500.0, 1000.0, 5000.0, 10000.0]),
    angular_resolution=10.0)

# Omnidirectional microphone as RX (single-frequency, clamped for all output frequencies)
rx = arrayant.generate('omni')

# Simple LOS path setup
fbs_pos = np.array([[0.5], [0.0], [0.0]])     # Scatterer at RX position
lbs_pos = np.array([[0.5], [0.0], [0.0]])
path_length = np.array([1.0])                 # 1 meter distance

# Frequency-flat path gain and scalar Jones matrix at two input frequencies
freq_in = np.array([100.0, 10000.0])
path_gain = np.ones((1, 2))                   # Unit gain at both frequencies
M = np.zeros((2, 1, 2))                       # Scalar pressure (2 rows)
M[0, 0, 0] = 1.0; M[0, 0, 1] = 1.0            # ReVV = 1 at both frequencies

# Compute channel at 3 output frequencies using speed of sound
freq_out = np.array([200.0, 1000.0, 5000.0])
coeff_re, coeff_im, delays = arrayant.get_channels_multifreq(
    tx_woofer, rx, fbs_pos, lbs_pos, path_gain, path_length, M,
    np.zeros(3),                               # TX at origin
    np.zeros(3),                               # TX orientation (no rotation)
    np.array([1.0, 0.0, 0.0]),                 # RX at (1, 0, 0)
    np.zeros(3),                               # RX orientation (no rotation)
    freq_in, freq_out,
    propagation_speed=343.0)                   # Speed of sound for acoustics

# coeff_re.shape = (1, n_tx_ports, 1, 3) — one RX port, one path, 3 output frequencies
Caveat:
See also:


get_channels_planar - Calculate channel coefficients for planar waves

Description:
In this function, the wireless propagation channel between a transmitter and a receiver is calculated, based on a single transmit and receive position. Additionally, interaction points with the environment, which are derived from either Ray Tracing or Geometric Stochastic Models such as QuaDRiGa, are considered. The calculation is performed under the assumption of planar wave propagation. For accurate execution of this process, several pieces of input data are required:

Usage:
from quadriga_lib import arrayant

coeff_re, coeff_im, delays, rx_Doppler = arrayant.get_channels_planar( ant_tx, ant_rx, 
    aod, eod, aoa, eoa, path_gain, path_length, M, tx_pos, tx_orientation, rx_pos, rx_orientation, 
    center_freq, use_absolute_delays, add_fake_los_path );
Input Arguments:
Derived inputs:
n_azimuth_tx Number of azimuth angles in the TX antenna pattern
n_elevation_tx Number of elevation angles in the TX antenna pattern
n_elements_tx Number of physical antenna elements in the TX array antenna
n_ports_tx Number of ports (after coupling) in the TX array antenna
n_azimuth_rx Number of azimuth angles in the RX antenna pattern
n_elevation_rx Number of elevation angles in the RX antenna pattern
n_elements_rx Number of physical antenna elements in the RX array antenna
n_ports_rx Number of ports (after coupling) in the RX array antenna
n_path Number of propagation paths

Output Arguments:
Caveat:


get_channels_spherical - Calculate channel coefficients from path data and antenna patterns

Description:
In this function, the wireless propagation channel between a transmitter and a receiver is calculated, based on a single transmit and receive position. Additionally, interaction points with the environment, which are derived from either Ray Tracing or Geometric Stochastic Models such as QuaDRiGa, are considered. The calculation is performed under the assumption of spherical wave propagation. For accurate execution of this process, several pieces of input data are required:

Usage:
from quadriga_lib import arrayant

# Return only coefficients and delays
coeff_re, coeff_im, delays = arrayant.get_channels_spherical( ant_tx, ant_rx, 
    fbs_pos, lbs_pos, path_gain, path_length, M, tx_pos, tx_orientation, rx_pos, rx_orientation, 
    center_freq, use_absolute_delays, add_fake_los_path );

# Return additional departure and arrival angles
coeff_re, coeff_im, delays, aod, eod, aoa, eoa = arrayant.get_channels_spherical( ant_tx, ant_rx, 
    fbs_pos, lbs_pos, path_gain, path_length, M, tx_pos, tx_orientation, rx_pos, rx_orientation, 
    center_freq, use_absolute_delays, add_fake_los_path, angles=1 );
Input Arguments:
Derived inputs:
n_azimuth_tx Number of azimuth angles in the TX antenna pattern
n_elevation_tx Number of elevation angles in the TX antenna pattern
n_elements_tx Number of physical antenna elements in the TX array antenna
n_ports_tx Number of ports (after coupling) in the TX array antenna
n_azimuth_rx Number of azimuth angles in the RX antenna pattern
n_elevation_rx Number of elevation angles in the RX antenna pattern
n_elements_rx Number of physical antenna elements in the RX array antenna
n_ports_rx Number of ports (after coupling) in the RX array antenna
n_path Number of propagation paths

Output Arguments:
Caveat:


interpolate - Interpolate array antenna field patterns

Description:
Usage:
from quadriga_lib import arrayant

# Minimal example (single-frequency, 3D patterns)
vr,vi,hr,hi = arrayant.interpolate(arrayant, azimuth, elevation)

# Output as complex type
v,h = arrayant.interpolate(arrayant, azimuth, elevation, complex=1)

# Generate projected distance (single-frequency only)
vr,vi,hr,hi,dist = arrayant.interpolate(arrayant, azimuth, elevation, dist=1)
v,h,dist = arrayant.interpolate(arrayant, azimuth, elevation, complex=1, dist=1)

# Additional inputs
vr,vi,hr,hi = arrayant.interpolate(arrayant, azimuth, elevation, element, orientation, element_pos)

# Output angles in antenna-local coordinates (single-frequency only)
vr,vi,hr,hi,az_local,el_local,gamma = arrayant.interpolate(arrayant, azimuth, elevation, orientation=ori, local_angles=1)

# Multi-frequency interpolation (4D patterns)
vr,vi,hr,hi = arrayant.interpolate(speaker, azimuth, elevation, frequency=freqs)
v,h = arrayant.interpolate(speaker, azimuth, elevation, frequency=freqs, complex=1)

# Single-frequency arrayant with frequency duplication (output is 3D, duplicated across freqs)
vr,vi,hr,hi = arrayant.interpolate(ant, azimuth, elevation, frequency=freqs)
Input Arguments:
Derived inputs:
n_azimuth Number of azimuth angles in the field pattern
n_elevation Number of elevation angles in the field pattern
n_elements Number of antenna elements in the field pattern of the array antenna
n_ang Number of interpolation angles
n_out Number of antenna elements in the generated output (may differ from n_elements)
n_freq Number of frequency entries in the multi-frequency arrayant (4D input only)
n_freq_out Number of target frequencies (multi-frequency path only)

Output Arguments (single-frequency path):
Output Arguments (multi-frequency path):


qdant_read - Reads array antenna data from QDANT files

Description:
Usage:
from quadriga_lib import arrayant

# Read a single antenna entry (default: first entry)
data = arrayant.qdant_read('antenna.qdant')
data = arrayant.qdant_read('antenna.qdant', id=2)

# Read all entries as multi-frequency arrayant (4D patterns)
data = arrayant.qdant_read('speaker.qdant', id=0)
Input Arguments:
Output Arguments:
See also:


qdant_write - Writes array antenna data to QDANT files

Description:
Usage:
from quadriga_lib import arrayant

# Single-frequency: write with optional ID
id_in_file = arrayant.qdant_write('antenna.qdant', ant)
id_in_file = arrayant.qdant_write('antenna.qdant', ant, id=2)

# Multi-frequency (4D patterns): writes all frequencies sequentially
arrayant.qdant_write('speaker.qdant', speaker)
Input Arguments:
Output Argument:
# See also:


rotate_pattern - Rotates antenna patterns

Description:
Usage:
from quadriga_lib import arrayant

# Single-frequency: rotate all elements by 45 deg bank
arrayant_out = arrayant.rotate_pattern(ant, x_deg=45.0)

# Single-frequency: rotate only elements 0 and 1 (0-based)
arrayant_out = arrayant.rotate_pattern(ant, z_deg=90.0, element=[0, 1])

# Multi-frequency (4D patterns): same interface
speaker_out = arrayant.rotate_pattern(speaker, y_deg=10.0)
Input Arguments:
Output Arguments:




Channel functions



baseband_freq_response - Compute the frequency-domain channel response from time-domain coefficients

Description:
Usage:
import quadriga_lib

# Single-frequency with bandwidth + carriers
hmat = quadriga_lib.channel.baseband_freq_response( coeff=coeff, delay=delay, bandwidth=100e6 )

# Single-frequency with freq_in + freq_out
hmat = quadriga_lib.channel.baseband_freq_response( coeff=coeff, delay=delay,
    freq_in=np.array([2.0e9]), freq_out=np.linspace(1.95e9, 2.05e9, 128) )

# Multi-frequency with separate re/im
hmat = quadriga_lib.channel.baseband_freq_response( coeff_re=cre, coeff_im=cim, delay=delay,
    freq_in=freq_in, freq_out=freq_out )
Input Arguments:
Output Argument:


channel_export_obj_file - Export path data to a Wavefront OBJ file for visualization in Blender

Description:
This function exports path data to a Wavefront OBJ file, which can be used for visualization in 3D software such as Blender. It supports various colormaps for color-coding the paths based on their gain values. In addition, the function allows you to control the maximum number of paths displayed, set gain thresholds for color-coding and selection. Usage:
from quadriga_lib import channel

channel.channel_export_obj_file( fn, max_no_paths, gain_max, gain_min, colormap, radius_max,
    radius_min, n_edges, rx_position, tx_position, no_interact, interact_coord, center_freq,
    coeff, i_snap )
Input Arguments:


hdf5_create_file - Create a new HDF5 channel file with a custom storage layout

Description:
Quadriga-Lib offers an HDF5-based method for storing and managing channel data. A key feature of this library is its ability to organize multiple channels within a single HDF5 file while enabling access to individual data sets without the need to read the entire file. In this system, channels can be structured in a multi-dimensional array. For instance, the first dimension might represent the Base Station (BS), the second the User Equipment (UE), and the third the frequency. However, it is important to note that the dimensions of the storage layout must be defined when the file is initially created and cannot be altered thereafter. The function quadriga_lib.channel.hdf5_create_file is used to create an empty file with a predetermined custom storage layout. Usage:
from quadriga_lib import channel
channel.hdf5_create_file( fn, nx, ny, nz, nw )
Input Arguments:


hdf5_read_channel - Reads channel data from HDF5 files

Description:
Quadriga-Lib provides an HDF5-based solution for storing and organizing channel data. This data comprises various well-defined sets, including channel coefficients, positions of transmitters and receivers, as well as path data that reflects the interaction of radio waves with the environment. Typically, these datasets are multi-dimensional, encompassing data for n_rx receive antennas, n_tx transmit antennas, n_path propagation paths, and n_snap snapshots. Snapshots are particularly useful for recording data across different locations (such as along a trajectory) or various frequencies. It is important to note that not all datasets include all these dimensions.

The library also supports the addition of extra datasets of any type or shape, which can be useful for incorporating descriptive data or analysis results. To facilitate data access, the function quadriga_lib.channel.hdf5_read_channel is designed to read both structured and unstructured data from the file. Usage:
from quadriga_lib import channel
data = channel.hdf5_read_channel( fn, ix, iy, iz, iw, snap )
Input Arguments:
Output Arguments:
Caveat:


hdf5_read_dset - Read a single unstructured dataset from an HDF5 file

Description:
Quadriga-Lib offers a solution based on HDF5 for storing and organizing channel data. In addition to structured datasets, the library facilitates the inclusion of extra datasets of various types and shapes. This feature is particularly beneficial for integrating descriptive data or analysis results. The function quadriga_lib.channel.hdf5_read_dset retrieves a single unstructured dataset. The output type of the function is defined by the datatype in the file. An empty matrix is returned if the dataset does not exist in the file. Usage:
from quadriga_lib import channel
dset = channel.hdf5_read_dset( fn, ix, iy, iz, iw, name )
Input Arguments:
Output Argument:
Caveat:


hdf5_read_dset_names - Read the names of unstructured data fields from an HDF5 file

Description:
Quadriga-Lib offers a solution based on HDF5 for storing and organizing channel data. In addition to structured datasets, the library facilitates the inclusion of extra datasets of various types and shapes. This feature is particularly beneficial for integrating descriptive data or analysis results. Users can add any number of such unstructured datasets, each identified by a unique dataset name. The function quadriga_lib.channel.hdf5_read_dset_names retrieves the names of all these datasets, returning them as a list of strings. Usage:
from quadriga_lib import channel
names = channel.hdf5_read_dset_names( fn, ix, iy, iz, iw );
Input Arguments:
Output Argument:


hdf5_read_layout - Read the storage layout of channel data inside an HDF5 file

Description:
Quadriga-Lib provides an HDF5-based solution for the storage and organization of channel data. A notable feature of this library is its capacity to manage multiple channels within a single HDF5 file. In this framework, channels can be arranged in a multi-dimensional array format. The function quadriga_lib.channel.hdf5_read_layout is designed to read the storage layout from an existing file. Furthermore, it also generates an array that marks the locations within the layout where data already exists. This functionality aids in efficiently managing and accessing channel data within the HDF5 file structure. Usage:
from quadriga_lib import channel
storage_dims, has_data = channel.hdf5_read_layout( fn )
Input Argument:
Output Arguments:


hdf5_reshape_layout - Reshapes the storage layout inside an existing HDF5 file

Description:
Quadriga-Lib provides an HDF5-based solution for the storage and organization of channel data. A notable feature of this library is its capacity to manage multiple channels within a single HDF5 file. In this framework, channels can be arranged in a multi-dimensional array format. Once an HDF5 file has been created, the number of channels in the storage layout is fixed. However, it is possible to reshape the layout using quadriga_lib.channel.hdf5_reshape_layout. Usage:
from quadriga_lib import channel
channel.hdf5_reshape_layout( fn, storage_dims );
Input Arguments:


hdf5_write_channel - Writes channel data to HDF5 files

Description:
Quadriga-Lib provides an HDF5-based solution for storing and organizing channel data. This function can be used to write structured and unstructured data to an HDF5 file. Usage:
from quadriga_lib import channel

storage_dims = channel.hdf5_write_channel( fn, ix, iy, iz, iw, par, rx_pos, tx_pos, ...
   coeff, delay, center_freq, name, initial_pos, path_gain, path_length, ...
   polarization, path_angles, path_fbs_pos, path_lbs_pos, no_interact, interact_coord, ...
   rx_orientation, tx_orientation )
Input Arguments:
Output Arguments:
Caveat:


hdf5_write_dset - Writes unstructured data to a HDF5 file

Description:
Quadriga-Lib offers a solution based on HDF5 for storing and organizing channel data. In addition to structured datasets, the library facilitates the inclusion of extra datasets of various types and shapes. This feature is particularly beneficial for integrating descriptive data or analysis results. The function quadriga_lib.channel.hdf5_write_dset writes a single unstructured dataset. Usage:
from quadriga_lib import channel
channel.hdf5_write_dset( fn, ix, iy, iz, iw, name, data );
Input Arguments:
Caveat:


qrt_file_parse - Read metadata from a QRT file

Usage:
from quadriga_lib import channel

# Separate outputs
no_cir, no_orig, no_dest, no_freq, cir_offset, orig_names, dest_names, version, fGHz, cir_pos, cir_orientation, orig_pos, orig_orientation = channel.qrt_file_parse( fn )

# Output as tuple
data = channel.qrt_file_parse( fn )
Input Argument:
Output Arguments:


qrt_file_read - Read ray-tracing data from QRT file

Usage:
from quadriga_lib import channel
data = channel.qrt_file_read( fn, i_cir, i_orig, downlink )
Input Arguments:
Output Arguments:


quantize_delays - Fixes the path delays to a grid of delay bins

Description:
Usage:
import quadriga_lib
coeff_re_q, coeff_im_q, delay_q = quadriga_lib.channel.quantize_delays(
    coeff_re, coeff_im, delay, tap_spacing=5e-9, max_no_taps=48, power_exponent=1.0, fix_taps=0)
Arguments:
Returns:




Channel generation functions



get_ieee_indoor - Generate indoor MIMO channel realizations for IEEE TGn/TGac/TGax/TGah models
Usage:
chan = quadriga_lib.channel.get_ieee_indoor( ap_array, sta_array, ChannelType, CarrierFreq_Hz,
   tap_spacing_s, n_users, observation_time, update_rate, speed_station_kmh, speed_env_kmh,
   Dist_m, n_floors, uplink, offset_angles, n_subpath, Doppler_effect, seed,
   KF_linear, XPR_NLOS_linear, SF_std_dB_LOS, SF_std_dB_NLOS, dBP_m, n_walls, wall_loss )
Inputs:
Output:
See also:




Miscellaneous / Tools



acdf - Calculate the empirical averaged cumulative distribution function (CDF)

Description:
Usage:
import quadriga_lib
result = quadriga_lib.tools.acdf( data, bins, n_bins )
Arguments:
Returns:
Example:
import numpy as np
import quadriga_lib

data = np.random.randn(10000, 5)
result = quadriga_lib.tools.acdf(data)
bins = result["bins"]   # 201 bin centers
Sh = result["Sh"]       # Individual CDFs, shape (201, 5)
Sc = result["Sc"]       # Averaged CDF, shape (201,)
mu = result["mu"]       # Mean quantiles, shape (9,)
sig = result["sig"]     # Std of quantiles, shape (9,)


calc_angular_spread - Calculate azimuth and elevation angular spreads with spherical wrapping

Description:
Usage:
import quadriga_lib
as_spread, es_spread, orientation, phi, theta = quadriga_lib.tools.calc_angular_spread( az, el, powers)
as_spread, es_spread, orientation, phi, theta = quadriga_lib.tools.calc_angular_spread(
    az, el, powers, wrapping=True, calc_bank_angle=True, quantize=0.0)
Arguments:
Returns:
Example:
import numpy as np
import quadriga_lib

az = [np.array([0.1, -0.1, 0.05]), np.array([0.2, -0.2, 0.1, -0.1])]
el = [np.array([0.0, 0.0, 0.0]), np.array([0.05, -0.05, 0.0, 0.0])]
powers = [np.array([1.0, 1.0, 0.5]), np.array([2.0, 1.0, 1.5, 0.5])]
as_spread, es_spread, orient, phi, theta = quadriga_lib.tools.calc_angular_spread(az, el, powers)


calc_cross_polarization_ratio - Calculate the cross-polarization ratio (XPR) for linear and circular polarization bases

Description:
Usage:
import quadriga_lib
xpr, pg = quadriga_lib.tools.calc_cross_polarization_ratio( powers, M, path_length, tx_pos, rx_pos )
xpr, pg = quadriga_lib.tools.calc_cross_polarization_ratio( powers, M, path_length, tx_pos, rx_pos, include_los, window_size )
Arguments:
Returns:


calc_delay_spread - Calculate the RMS delay spread in [s]

Description:
Usage:
import quadriga_lib
ds, mean_delay = quadriga_lib.tools.calc_delay_spread(delays, powers, threshold=100.0, granularity=0.0)
Arguments:
Returns:
Example:
import numpy as np
import quadriga_lib

delays = [np.array([0.0, 1e-6, 2e-6])]
powers = [np.array([1.0, 0.5, 0.25])]
ds, mean_delay = quadriga_lib.calc_delay_spread(delays, powers)


calc_rician_k_factor - Calculate the Rician K-Factor from channel impulse response data

Description:
Usage:
import quadriga_lib
kf, pg = quadriga_lib.tools.calc_rician_k_factor( powers, path_length, tx_pos, rx_pos, window_size=0.01 )
Arguments:
Returns:


cart2geo - Transform Cartesian (x,y,z) coordinates to Geographic (az, el, length) coordinates

Description:
This function transforms Cartesian (x,y,z) coordinates to Geographic (azimuth, elevation, length) coordinates. A geographic coordinate system is a three-dimensional reference system that locates points on the surface of a sphere. A point has three coordinate values: azimuth, elevation and length where azimuth and elevation measure angles. In the geographic coordinate system, the elevation angle θ = 90° points to the zenith and θ = 0° points to the horizon. Usage:
import quadriga_lib
geo_coords = quadriga_lib.tools.cart2geo(cart_coords)
Input Argument:
Output Arguments:


components - Returns the version numbers of all quadriga-lib sub-components

Usage:
components = quadriga_lib.components()


version - Returns the quadriga-lib version number

Usage:
version = quadriga_lib.version();
Caveat:


write_png - Write data to a PNG file

Description:
Declaration:
import quadriga_lib

quadriga_lib.tools.write_png( fn, data, colormap, min_val, max_val, log_transform )
Arguments:




Site-specific simulation tools



calc_diffraction_gain - Calculate diffraction gain for multiple TX-RX pairs using a 3D triangular mesh
Usage:
# Output as tuple
data = quadriga_lib.RTtools.calc_diffraction_gain( orig, dest, mesh, mtl_prop, center_frequency,
    lod, verbose, sub_mesh_index, use_kernel, gpu_id, scalar_mode )

# Unpacked outputs
gain, coord = RTtools.calc_diffraction_gain( orig, dest, mesh, mtl_prop, center_frequency,
    lod, verbose, sub_mesh_index, use_kernel, gpu_id, scalar_mode )
Inputs:
Outputs:
See also:


icosphere - Construct a geodesic polyhedron from recursive icosahedron subdivision
Usage:
# Output as tuple
data = quadriga_lib.RTtools.icosphere( no_div, radius, direction_xyz )

# Unpacked outputs
center, length, vert, direction = quadriga_lib.RTtools.icosphere( no_div, radius, direction_xyz )
Inputs:
Outputs:


mitsuba_xml_file_write - Write a triangular mesh to a Mitsuba 3 XML scene file
Usage:
quadriga_lib.RTtools.mitsuba_xml_file_write( fn, vert_list, face_ind, obj_id, mtl_id, obj_names, mtl_names, bsdf, map_to_itu )
Input Arguments:
See also:


obj_file_read - Read a Wavefront .obj file and extract geometry and material information
Usage:
# Return as separate variables
mesh, mtl_prop, vert_list, face_ind, obj_ind, mtl_ind, obj_names, mtl_names, bsdf = 
    quadriga_lib.RTtools.obj_file_read( fn )

# Return as tuple with 9 elements
data = RTtools.obj_file_read( fn )

# Use a custom material definition file
data = RTtools.obj_file_read( fn, materials_csv )
Inputs:
Outputs:
Default material table:
See also:


point_cloud_aabb - Compute the axis-aligned bounding boxes (AABB) of a 3D point cloud
Usage:
aabb = quadriga_lib.RTtools.point_cloud_aabb( points, sub_cloud_ind, vec_size )
Input Arguments:
Output Argument:
See also:


point_cloud_segmentation - Reorganize a point cloud into spatial sub-clouds for efficient processing
Usage:
# Output as tuple
data = quadriga_lib.RTtools.point_cloud_segmentation( points, target_size, vec_size )

# Unpacked outputs
points_out, sub_cloud_ind, forward_ind, reverse_ind =
    quadriga_lib.RTtools.point_cloud_segmentation( points, target_size, vec_size )
Inputs:
Outputs:


point_inside_mesh - Test whether 3D points are inside a triangle mesh using raycasting
Usage:
result = quadriga_lib.RTtools.point_inside_mesh( points, mesh, obj_ind, distance )
Input Arguments:
Output Arguments:
See also:


ray_point_intersect - Calculate intersections of ray beams with points in 3D space
Usage:
hit_count, ray_ind = quadriga_lib.RTtools.ray_point_intersect( orig, trivec, tridir, points, sub_cloud_ind, use_kernel, gpu_id )
Inputs:
Outputs:
See also:


ray_triangle_intersect - Compute ray-triangle intersections in 3D using the Möller–Trumbore algorithm
Usage:
# Output as tuple
data = RTtools.ray_triangle_intersect( orig, dest, mesh, sub_mesh_index, aabb, use_kernel, gpu_id )

# Unpacked outputs
fbs, sbs, no_interact, fbs_ind, sbs_ind = RTtools.ray_triangle_intersect( orig, dest, mesh, sub_mesh_index, aabb, use_kernel, gpu_id )
Inputs:
Outputs:
See also:


triangle_mesh_aabb - Calculate the axis-aligned bounding box (AABB) of a triangle mesh and its sub-meshes
Usage:
aabb = quadriga_lib.RTtools.triangle_mesh_aabb( triangles, sub_mesh_index, vec_size )
Inputs:
Output:
See also:


triangle_mesh_segmentation - Reorganize a 3D triangular mesh into spatially clustered sub-meshes for faster processing
Usage:
# Output as tuple
data = quadriga_lib.RTtools.triangle_mesh_segmentation( triangles, target_size, vec_size, mtl_prop )

# Unpacked outputs
triangles_out, sub_mesh_index, mesh_index, mtl_propR = 
    quadriga_lib.RTtools.triangle_mesh_segmentation( triangles, target_size, vec_size, mtl_prop )
Inputs:
Outputs: