Python API Documentation for Quadriga-Lib v0.10.1
Notes
Overview
Array antenna functions
Channel functions
Miscellaneous / Tools
| cart2geo | Transform Cartesian (x,y,z) coordinates to Geographic (az, el, length) coordinates |
| components | Returns the version numbers of all quadriga-lib sub-components |
| version | Returns the quadriga-lib version number |
| write_png | Write data to a PNG file |
Site-Specific Simulation Tools
Array antenna functions
calc_directivity - Calculates the directivity (in dBi) of array antenna elements
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:
arrayant
Dictionary containing the arrayant data with the following keys:
e_theta_re |
e-theta field component, real part |
Shape: (n_elevation, n_azimuth, n_elements) |
e_theta_im |
e-theta field component, imaginary part |
Shape: (n_elevation, n_azimuth, n_elements) |
e_phi_re |
e-phi field component, real part |
Shape: (n_elevation, n_azimuth, n_elements) |
e_phi_im |
e-phi field component, imaginary part |
Shape: (n_elevation, n_azimuth, n_elements) |
azimuth_grid |
Azimuth angles in [rad], -pi to pi, sorted |
Shape: (n_azimuth) |
elevation_grid |
Elevation angles in [rad], -pi/2 to pi/2, sorted |
Shape: (n_elevation) |
element_pos |
Antenna element (x,y,z) positions |
Shape: (3, n_elements) |
coupling_re |
Coupling matrix, real part |
Shape: (n_elements, n_ports) |
coupling_im |
Coupling matrix, imaginary part |
Shape: (n_elements, n_ports) |
center_freq |
Center frequency in [Hz], optional |
Scalar |
name |
Name of the array antenna object, optional |
String |
freq (optional)
An alternative value for the center frequency. Overwrites the value given in arrayant_in. If
neither freq not arrayant_in["center_freq") are given, an error is thrown.
azimuth_grid (optional)
Alternative azimuth angles for the output in [rad], -pi to pi, sorted, Shape: (n_azimuth_out),
If not given, arrayant_in["azimuth_grid") is used instead.
elevation_grid (optional)
Alternative elevation angles for the output in [rad], -pi/2 to pi/2, sorted, Shape: (n_elevation_out),
If not given, arrayant_in["elevation_grid") is used instead.
-
Output Arguments:
arrayant_out
Dictionary containing the arrayant data with the following keys:
e_theta_re |
e-theta field component, real part |
Shape: (n_elevation_out, n_azimuth_out, n_ports) |
e_theta_im |
e-theta field component, imaginary part |
Shape: (n_azimuth_out, n_azimuth_out, n_ports) |
e_phi_re |
e-phi field component, real part |
Shape: (n_azimuth_out, n_azimuth_out, n_ports) |
e_phi_im |
e-phi field component, imaginary part |
Shape: (n_azimuth_out, n_azimuth_out, n_ports) |
azimuth_grid |
Azimuth angles in [rad], -pi to pi, sorted |
Shape: (n_azimuth_out) |
elevation_grid |
Elevation angles in [rad], -pi/2 to pi/2, sorted |
Shape: (n_azimuth_out) |
element_pos |
Antenna element (x,y,z) positions, set to 0 |
Shape: (3, n_ports) |
coupling_re |
Coupling matrix, real part, identity matrix |
Shape: (n_ports, n_ports) |
coupling_im |
Coupling matrix, imaginary part, zero matrix |
Shape: (n_ports, n_ports) |
center_freq |
Center frequency in [Hz] |
Scalar |
name |
Name of the array antenna object, same as input |
String |
copy_element - Create copies of array antenna elements
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:
fn
Filename of the OBJ file, string
arrayant
Dictionary containing array antenna data with at least the following keys:
e_theta_re |
Real part of e-theta field component |
Shape: (n_elevation, n_azimuth, n_elements_c) |
e_theta_im |
Imaginary part of e-theta field component |
Shape: (n_elevation, n_azimuth, n_elements_c) |
e_phi_re |
Real part of e-phi field component |
Shape: (n_elevation, n_azimuth, n_elements_c) |
e_phi_im |
Imaginary part of e-phi field component |
Shape: (n_elevation, n_azimuth, n_elements_c) |
azimuth_grid |
Azimuth angles in [rad] -pi to pi, sorted |
Shape: (n_azimuth) |
elevation_grid |
Elevation angles in [rad], -pi/2 to pi/2, sorted |
Shape: (n_elevation) |
element_pos |
Antenna element (x,y,z) positions, optional |
Shape: (3, n_elements) |
name |
Name of the array antenna object |
String |
directivity_range
Directivity range of the antenna pattern visualization in dB
colormap
Colormap for the visualization, string, supported are 'jet', 'parula', 'winter', 'hot', 'turbo',
'copper', 'spring', 'cool', 'gray', 'autumn', 'summer', Optional, default = 'jet'
object_radius
Radius in meters of the exported object
icosphere_n_div
Map pattern to an Icosphere with given number of subdivisions
element
Antenna element indices, 0-based, empty = export all
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:
type
Antenna model type, string
res
Pattern resolution in [deg], scalar, default = 1 deg
freq
The center frequency in [Hz], scalar, default = 299792458 Hz
-
Input arguments for type `custom`, `3gpp` and `multibeam`:
az_3dB
3dB beam width in azimuth direction in [deg], scalar,
default for custom = 90 deg, default for 3gpp = 67 deg, multibeam = 120 deg
el_3db
3dB beam width in elevation direction in [deg], scalar,
default for custom = 90 deg, default for 3gpp = 67 deg, multibeam = 120 deg
rear_gain_lin
Isotropic gain (linear scale) at the back of the antenna, scalar, default = 0.0
-
Input arguments for type `3gpp` and `multibeam`:
M
Number of vertically stacked elements for 3gpp and multibeam, scalar, default = 1
N
Number of horizontally stacked elements for 3gpp, ula and multibeam, scalar, default = 1
pol
Polarization indicator to be applied for each of the M elements:
pol = 1 |
vertical polarization (default value), 3gpp and multibeam |
pol = 2 |
H/V polarized elements, results in 2NM elements, 3gpp and multibeam |
pol = 3 |
+/-45° polarized elements, results in 2NM elements, 3gpp and multibeam |
pol = 4 |
vertical polarization, combines elements in vertical direction, results in N elements, 3gpp only |
pol = 5 |
H/V polarization, combines elements in vertical direction, results in 2N elements, 3gpp only |
pol = 6 |
+/-45° polarization, combines elements in vertical direction, results in 2N elements, 3gpp only |
Polarization indicator is ignored when a custom pattern is provided.
tilt
The electric downtilt angle in [deg], Only relevant for pol = 4/5/6, 3gpp only, scalar, default = 0
spacing
Element spacing in [λ] for 3gpp, ula and multibeam, scalar, default = 0.5
Mg
Number of nested panels in a column, 3gpp only, scalar, default = 1
Ng
Number of nested panels in a row, 3gpp only, scalar, default = 1
dgv
Panel spacing in vertical direction in [λ], 3gpp only, scalar, default = 0.5
dgh
Panel spacing in horizontal direction in [λ], 3gpp only, scalar, default = 0.5
beam_az
Azimuth beam angles (degrees), multibeam only, Vector of length n_beams. Default: [0.0]
beam_el
Elevation beam angles (degrees), multibeam only, Vector of length n_beams. Default: [0.0]
beam_weight
Scaling factors for each beam, multibeam only, The vector must have the same length as beam_az and beam_el.
Values are normalized so that their sum equals 1. Can be used to prioritize beams.
Default: {1.0}
separate_beams
If set to true, create a separate beam for each angle pair (ignores weights), multibeam only
apply_weights
Switch to apply the beam-forming weights
pattern (optional)
Dictionary containing a custom pattern (default = empty) with at least the following keys:
e_theta_re |
Real part of e-theta field component |
Shape: (n_elevation, n_azimuth, n_elements_c) |
e_theta_im |
Imaginary part of e-theta field component |
Shape: (n_elevation, n_azimuth, n_elements_c) |
e_phi_re |
Real part of e-phi field component |
Shape: (n_elevation, n_azimuth, n_elements_c) |
e_phi_im |
Imaginary part of e-phi field component |
Shape: (n_elevation, n_azimuth, n_elements_c) |
azimuth_grid |
Azimuth angles in [rad] -pi to pi, sorted |
Shape: (n_azimuth) |
elevation_grid |
Elevation angles in [rad], -pi/2 to pi/2, sorted |
Shape: (n_elevation) |
-
Output Arguments:
arrayant
Dictionary containing the arrayant data with the following keys:
e_theta_re |
e-theta field component, real part |
Shape: (n_elevation, n_azimuth, n_elements) |
e_theta_im |
e-theta field component, imaginary part |
Shape: (n_elevation, n_azimuth, n_elements) |
e_phi_re |
e-phi field component, real part |
Shape: (n_elevation, n_azimuth, n_elements) |
e_phi_im |
e-phi field component, imaginary part |
Shape: (n_elevation, n_azimuth, n_elements) |
azimuth_grid |
Azimuth angles in [rad] -pi to pi, sorted |
Shape: (n_azimuth) |
elevation_grid |
Elevation angles in [rad], -pi/2 to pi/2, sorted |
Shape: (n_elevation) |
element_pos |
Antenna element (x,y,z) positions |
Shape: (3, n_elements) |
coupling_re |
Coupling matrix, real part |
Shape: (n_elements, n_ports) |
coupling_im |
Coupling matrix, imaginary part |
Shape: (n_elements, n_ports) |
center_freq |
Center frequency in [Hz], optional, default = 0.3 GHz |
Scalar |
name |
Name of the array antenna object |
String |
interpolate - Interpolate array antenna field patterns
-
Description:
This function interpolates polarimetric antenna field patterns for a given set of azimuth and
elevation angles.
-
Usage:
from quadriga_lib import arrayant
# Minimal example
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
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
vr,vi,hr,hi,az_local,el_local,gamma = arrayant.interpolate(arrayant, azimuth, elevation, orientation=ori, local_angles=1)
-
Input Arguments:
arrayant (required)
Dictionary containing array antenna data with at least the following keys:
e_theta_re |
Real part of e-theta field component |
Shape: (n_elevation, n_azimuth, n_elements) |
e_theta_im |
Imaginary part of e-theta field component |
Shape: (n_elevation, n_azimuth, n_elements) |
e_phi_re |
Real part of e-phi field component |
Shape: (n_elevation, n_azimuth, n_elements) |
e_phi_im |
Imaginary part of e-phi field component |
Shape: (n_elevation, n_azimuth, n_elements) |
azimuth_grid |
Azimuth angles in [rad] -pi to pi, sorted |
Shape: (n_azimuth) |
elevation_grid |
Elevation angles in [rad], -pi/2 to pi/2, sorted |
Shape: (n_elevation) |
element_pos |
Antenna element (x,y,z) positions, optional |
Shape: (3, n_elements) |
azimuth (required)
Azimuth angles in [rad] for which the field pattern should be interpolated. Values must be between -pi and pi.
| Option 1: |
Use the same angles for all antenna elements (planar wave approximation) |
|
Shape: (1, n_ang) |
| Option 2: |
Provide different angles for each array element (e.g. for spherical waves) |
|
Shape: (n_out, n_ang) |
elevation (required)
Elevation angles in [rad] for which the field pattern should be interpolated. Values must be between -pi/2 and pi/2.
| Option 1: |
Use the same angles for all antenna elements (planar wave approximation) |
|
Shape: (1, n_ang) |
| Option 2: |
Provide different angles for each array element (e.g. for spherical waves) |
|
Shape: [n_out, n_ang) |
element (optional)
The element indices for which the interpolation should be done. Optional parameter. Values must
be between 0 and n_elements-1. It is possible to duplicate elements, i.e. by passing [1,1,2].
If this parameter is not provided (or an empty array is passed), i_element is initialized
to [0:n_elements-1]. In this case, n_out = n_elements.
Shape: (1, n_out) or (n_out, 1) or empty ()
orientation (optional)
This (optional) 3-element vector describes the orientation of the array antenna or of individual
array elements using Euler angles in [rad].
Shape: (3, 1) or (3, n_out) or (3, 1, n_ang) or (3, n_out, n_ang) or empty ()
element_pos (optional)
Alternative positions of the array antenna elements in local cartesian coordinates (using units of [m]).
If this parameter is not given, element positions arrayant are used. If the arrayant has no
positions, they are initialzed to [0,0,0]. For example, when duplicating the fist element by setting
element = [1,1), different element positions can be set for the two elements in the output.
Shape: (3, n_out) or empty ()
complex (optional flag)
If set to 1, output is returned in complex notation. This reduces performance due to additional
copies of the data in memory. Default: 0, false
dist (optional flag)
Switch to calculate the effective distances for phase calculation. Default: 0, false
local_angles (optional flag)
Switch to return the angles in antenna-local coordinates. These differ from the input when the
orientation of the antenna is adjusted. Default: 0, false
fast_access (optional flag)
If arrayant data is provided as munpy.ndarray of type double in Fortran-continguous (column-major)
order, arrayant_interpolate can access the Python memory directly without a conversion of the
data. This will increase performance and is done by default. If the data is not in the correct
format, a conversion is done in the background. Setting fast_access to 1 will skip the conversion
and throw an error if the arrayant data is not correctly formatted. Default: 0, false (convert)
-
Derived inputs:
n_azimuth |
Number of azimuth angles in the filed pattern |
n_elevation |
Number of elevation angles in the filed pattern |
n_elements |
Number of antenna elements filed 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) |
-
Output Arguments:
vr
Real part of the interpolated e-theta (vertical) field component. Shape (n_out, n_ang)
vi
Imaginary part of the interpolated e-theta (vertical) field component. Shape (n_out, n_ang)
hr
Real part of the interpolated e-phi (horizontal) field component. Shape (n_out, n_ang)
hi
Imaginary part of the interpolated e-phi (horizontal) field component. Shape (n_out, n_ang)
dist (optional)
The effective distances between the antenna elements when seen from the direction of the
incident path. The distance is calculated by an projection of the array positions on the normal
plane of the incident path. This is needed for calculating the phase of the antenna response.
Only returned when dist flag is set to 1. Shape (n_out, n_ang)
azimuth_loc (optional)
The azimuth angles in [rad] for the local antenna coordinate system, i.e., after applying the
'orientation'. If no orientation vector is given, these angles are identical to the input
azimuth angles. Only returned when local_angles flag is set to 1. Shape (n_out, n_ang)
elevation_loc (optional)
The elevation angles in [rad] for the local antenna coordinate system, i.e., after applying the
'orientation'. If no orientation vector is given, these angles are identical to the input
elevation angles. Only returned when local_angles flag is set to 1. Shape (n_out, n_ang)
gamma (optional)
Polarization rotation angles in [rad], Only returned when local_angles flag is set to 1.
Shape (n_out, n_ang)
qdant_read - Reads array antenna data from QDANT files
qdant_write - Writes array antenna data to QDANT files
rotate_pattern - Rotates antenna patterns
-
Description:
This function transforms the radiation patterns of array antenna elements, allowing for
precise rotations around the three principal axes (x, y, z) of the local Cartesian coordinate system.
The 3 rotations are applies in the order: 1. rotation around the x-axis (bank angle);
2. rotation around the y-axis (tilt angle), 3. rotation around the z-axis (heading angle)
-
Usage:
from quadriga_lib import arrayant
arrayant_out = arrayant.rotate_pattern(arrayant, bank, tilt, head, usage, element);
-
Input Arguments:
arrayant
Dictionary containing the arrayant data with the following keys:
e_theta_re |
e-theta field component, real part |
Shape: (n_elevation, n_azimuth, n_elements) |
e_theta_im |
e-theta field component, imaginary part |
Shape: (n_elevation, n_azimuth, n_elements) |
e_phi_re |
e-phi field component, real part |
Shape: (n_elevation, n_azimuth, n_elements) |
e_phi_im |
e-phi field component, imaginary part |
Shape: (n_elevation, n_azimuth, n_elements) |
azimuth_grid |
Azimuth angles in [rad], -pi to pi, sorted |
Shape: (n_azimuth) |
elevation_grid |
Elevation angles in [rad], -pi/2 to pi/2, sorted |
Shape: (n_elevation) |
element_pos |
Antenna element (x,y,z) positions, optional |
Shape: (3, n_elements) |
coupling_re |
Coupling matrix, real part, optional |
Shape: (n_elements, n_ports) |
coupling_im |
Coupling matrix, imaginary part, optional |
Shape: (n_elements, n_ports) |
center_freq |
Center frequency in [Hz], optional |
Scalar |
name |
Name of the array antenna object, optional |
String |
x_deg (optional)
The rotation angle around x-axis (bank angle) in [degrees]
y_deg (optional)
The rotation angle around y-axis (tilt angle) in [degrees]
z_deg (optional)
The rotation angle around z-axis (heading angle) in [degrees]
usage (optional)
The optional parameter 'usage' can limit the rotation procedure either to the pattern or polarization.
usage = 0 |
Rotate both, pattern and polarization, adjusts sampling grid (default) |
usage = 1 |
Rotate only pattern, adjusts sampling grid |
usage = 2 |
Rotate only polarization |
usage = 3 |
Rotate both, but do not adjust the sampling grid |
element (optional)
The element indices for which the pattern should be transformed. Optional parameter. Values must
be between 1 and n_elements. If this parameter is not provided (or an empty array is passed),
all elements will be rotated by the same angles. Shape: (1, n_elements) or empty ()
-
Output Arguments:
arrayant_out
Dictionary containing the arrayant data with the following keys:
e_theta_re |
e-theta field component, real part |
Shape: (n_elevation, n_azimuth, n_elements) |
e_theta_im |
e-theta field component, imaginary part |
Shape: (n_elevation, n_azimuth, n_elements) |
e_phi_re |
e-phi field component, real part |
Shape: (n_elevation, n_azimuth, n_elements) |
e_phi_im |
e-phi field component, imaginary part |
Shape: (n_elevation, n_azimuth, n_elements) |
azimuth_grid |
Azimuth angles in [rad] -pi to pi, sorted |
Shape: (n_azimuth) |
elevation_grid |
Elevation angles in [rad], -pi/2 to pi/2, sorted |
Shape: (n_elevation) |
element_pos |
Antenna element (x,y,z) positions |
Shape: (3, n_elements) |
coupling_re |
Coupling matrix, real part |
Shape: (n_elements, n_ports) |
coupling_im |
Coupling matrix, imaginary part |
Shape: (n_elements, n_ports) |
center_freq |
Center frequency in [Hz], default = 0.3 GHz |
Scalar |
name |
Name of the array antenna object |
String |
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:
- The 3D Cartesian (local) coordinates of both the transmitter and the receiver.
- The azimuth/elevation departure and arrval angles.
- The polarization transfer matrix for each propagation path.
- Antenna models for both the transmitter and the receiver.
- The orientations of the antennas.
-
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:
ant_tx (required)
Dictionary containing the transmit (TX) arrayant data with the following keys:
e_theta_re |
e-theta field component, real part |
Shape: (n_elevation_tx, n_azimuth_tx, n_elements_tx) |
e_theta_im |
e-theta field component, imaginary part |
Shape: (n_elevation_tx, n_azimuth_tx, n_elements_tx) |
e_phi_re |
e-phi field component, real part |
Shape: (n_elevation_tx, n_azimuth_tx, n_elements_tx) |
e_phi_im |
e-phi field component, imaginary part |
Shape: (n_elevation_tx, n_azimuth_tx, n_elements_tx) |
azimuth_grid |
Azimuth angles in [rad], -pi to pi, sorted |
Shape: (n_azimuth_tx) |
elevation_grid |
Elevation angles in [rad], -pi/2 to pi/2, sorted |
Shape: (n_elevation_tx) |
element_pos |
Antenna element (x,y,z) positions, optional |
Shape: (3, n_elements_tx) |
coupling_re |
Coupling matrix, real part, optional |
Shape: (n_elements_tx, n_ports_tx) |
coupling_im |
Coupling matrix, imaginary part, optional |
Shape: (n_elements_tx, n_ports_tx) |
ant_rx (required)
Dictionary containing the receive (RX) arrayant data with the following keys:
e_theta_re |
e-theta field component, real part |
Shape: (n_elevation_rx, n_azimuth_rx, n_elements_rx) |
e_theta_im |
e-theta field component, imaginary part |
Shape: (n_elevation_rx, n_azimuth_rx, n_elements_rx) |
e_phi_re |
e-phi field component, real part |
Shape: (n_elevation_rx, n_azimuth_rx, n_elements_rx) |
e_phi_im |
e-phi field component, imaginary part |
Shape: (n_elevation_rx, n_azimuth_rx, n_elements_rx) |
azimuth_grid |
Azimuth angles in [rad], -pi to pi, sorted |
Shape: (n_azimuth_rx) |
elevation_grid |
Elevation angles in [rad], -pi/2 to pi/2, sorted |
Shape: (n_elevation_rx) |
element_pos |
Antenna element (x,y,z) positions, optional |
Shape: (3, n_elements_rx) |
coupling_re |
Coupling matrix, real part, optional |
Shape: (n_elements_rx, n_ports_rx) |
coupling_im |
Coupling matrix, imaginary part, optional |
Shape: (n_elements_rx, n_ports_rx) |
aod (required)
Departure azimuth angles in [rad], Shape: ( n_path )
eod (required)
Departure elevation angles in [rad], Shape: ( n_path )
aoa (required)
Arrival azimuth angles in [rad], Shape: ( n_path )
eoa (required)
Arrival elevation angles in [rad], Shape: ( n_path )
path_gain (required)
Path gain (linear scale), Shape: ( n_path )
path_length (required)
Total path length in meters, Shape: ( n_path )
M (required)
Polarization transfer matrix, interleaved complex values (ReVV, ImVV, ReVH, ImVH, ReHV, ImHV, ReHH, ImHH),
Shape: ( 8, n_path )
tx_pos (required)
Transmitter position in 3D Cartesian coordinates; Shape: (3)
tx_orientation (required)
3-element vector describing the orientation of the transmit antenna in Euler angles (bank, tilt, heading),
Shape: (3,1) or (1,3)
rx_pos (required)
Receiver position in 3D Cartesian coordinates, Shape: (3)
rx_orientation (required)]
3-element vector describing the orientation of the receive antenna in Euler angles,
Shape: (3)
center_freq (optional)
Center frequency in [Hz]; optional; If the value is not provided or set to 0, phase calculation
in coefficients is disabled, i.e. that path length has not influence on the results. This can be
used to calculate the antenna response for a specific angle and polarization. Scalar value
use_absolute_delays (optional)
If true, the LOS delay is included for all paths; Default is false, i.e. delays are normalized
to the LOS delay.
add_fake_los_path (optional)
If true, adds a zero-power LOS path as the first path in case where no LOS path was present.
Default: false
-
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:
coeff_re
Channel coefficients, real part, Shape: ( n_ports_tx, n_ports_rx, n_path )
coeff_im
Channel coefficients, imaginary part, Shape: ( n_ports_tx, n_ports_rx, n_path )
delays
Propagation delay in seconds, Shape: ( n_ports_tx, n_ports_rx, n_path )
rx_Doppler
Doppler weights for moving RX, Shape: ( 1, n_path )
-
Caveat:
- Input data is directly accessed from Python memory, without copying if it is provided in
double precision and is in F-contiguous (column-major) order
- Other formats (e.g. single precision inputs or C-contiguous (row-major) order) will be converted
to double automatically, causing additional computation steps.
- To improve performance of repeated computations (e.g. in loops), consider preparing the data
accordingly to avoid unecessary computations.
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:
- The 3D Cartesian (local) coordinates of both the transmitter and the receiver.
- The specific interaction positions of the propagation paths within the environment.
- The polarization transfer matrix for each propagation path.
- Antenna models for both the transmitter and the receiver.
- The orientations of the antennas.
-
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:
ant_tx (required)
Dictionary containing the transmit (TX) arrayant data with the following keys:
e_theta_re |
e-theta field component, real part |
Shape: (n_elevation_tx, n_azimuth_tx, n_elements_tx) |
e_theta_im |
e-theta field component, imaginary part |
Shape: (n_elevation_tx, n_azimuth_tx, n_elements_tx) |
e_phi_re |
e-phi field component, real part |
Shape: (n_elevation_tx, n_azimuth_tx, n_elements_tx) |
e_phi_im |
e-phi field component, imaginary part |
Shape: (n_elevation_tx, n_azimuth_tx, n_elements_tx) |
azimuth_grid |
Azimuth angles in [rad], -pi to pi, sorted |
Shape: (n_azimuth_tx) |
elevation_grid |
Elevation angles in [rad], -pi/2 to pi/2, sorted |
Shape: (n_elevation_tx) |
element_pos |
Antenna element (x,y,z) positions, optional |
Shape: (3, n_elements_tx) |
coupling_re |
Coupling matrix, real part, optional |
Shape: (n_elements_tx, n_ports_tx) |
coupling_im |
Coupling matrix, imaginary part, optional |
Shape: (n_elements_tx, n_ports_tx) |
ant_rx (required)
Dictionary containing the receive (RX) arrayant data with the following keys:
e_theta_re |
e-theta field component, real part |
Shape: (n_elevation_rx, n_azimuth_rx, n_elements_rx) |
e_theta_im |
e-theta field component, imaginary part |
Shape: (n_elevation_rx, n_azimuth_rx, n_elements_rx) |
e_phi_re |
e-phi field component, real part |
Shape: (n_elevation_rx, n_azimuth_rx, n_elements_rx) |
e_phi_im |
e-phi field component, imaginary part |
Shape: (n_elevation_rx, n_azimuth_rx, n_elements_rx) |
azimuth_grid |
Azimuth angles in [rad], -pi to pi, sorted |
Shape: (n_azimuth_rx) |
elevation_grid |
Elevation angles in [rad], -pi/2 to pi/2, sorted |
Shape: (n_elevation_rx) |
element_pos |
Antenna element (x,y,z) positions, optional |
Shape: (3, n_elements_rx) |
coupling_re |
Coupling matrix, real part, optional |
Shape: (n_elements_rx, n_ports_rx) |
coupling_im |
Coupling matrix, imaginary part, optional |
Shape: (n_elements_rx, n_ports_rx) |
fbs_pos (required)
First interaction point of the rays and the environment, Shape: ( 3, n_path )
lbs_pos (required)
Last interaction point of the rays and the environment; For single-bounce models, this must be
identical to fbs_pos, Shape: ( 3, n_path )
path_gain (required)
Path gain (linear scale), Shape: ( n_path )
path_length (required)
Total path length in meters, Shape: ( n_path )
M (required)
Polarization transfer matrix, interleaved complex values (ReVV, ImVV, ReVH, ImVH, ReHV, ImHV, ReHH, ImHH),
Shape: ( 8, n_path )
tx_pos (required)
Transmitter position in 3D Cartesian coordinates; Shape: (3)
tx_orientation (required)
3-element vector describing the orientation of the transmit antenna in Euler angles (bank, tilt, heading),
Shape: (3,1) or (1,3)
rx_pos (required)
Receiver position in 3D Cartesian coordinates, Shape: (3)
rx_orientation (required)]
3-element vector describing the orientation of the receive antenna in Euler angles,
Shape: (3)
center_freq (optional)
Center frequency in [Hz]; optional; If the value is not provided or set to 0, phase calculation
in coefficients is disabled, i.e. that path length has not influence on the results. This can be
used to calculate the antenna response for a specific angle and polarization. Scalar value
use_absolute_delays (optional)
If true, the LOS delay is included for all paths; Default is false, i.e. delays are normalized
to the LOS delay.
add_fake_los_path (optional)
If true, adds a zero-power LOS path as the first path in case where no LOS path was present.
Default: false
angles (optional flag)
Switch to return the angles in antenna-local coordinates. Default: 0, false
-
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:
coeff_re
Channel coefficients, real part, Shape: ( n_ports_rx, n_ports_tx, n_path )
coeff_im
Channel coefficients, imaginary part, Shape: ( n_ports_rx, n_ports_tx, n_path )
delays
Propagation delay in seconds, Shape: ( n_ports_rx, n_ports_tx, n_path )
aod (optional)
Azimuth of Departure angles in [rad], Shape: ( n_ports_rx, n_ports_tx, n_path ),
Only returned when angles flag is set to 1.
eod (optional)
Elevation of Departure angles in [rad], Shape: ( n_ports_rx, n_ports_tx, n_path ),
Only returned when angles flag is set to 1.
aoa (optional)
Azimuth of Arrival angles in [rad], Shape: ( n_ports_rx, n_ports_tx, n_path ),
Only returned when angles flag is set to 1.
eoa (optional)
Elevation of Arrival angles in [rad], Shape: ( n_ports_rx, n_ports_tx, n_path ),
Only returned when angles flag is set to 1.
-
Caveat:
- Input data is directly accessed from Python memory, without copying if it is provided in
double precision and is in F-contiguous (column-major) order
- Other formats (e.g. single precision inputs or C-contiguous (row-major) order) will be converted
to double automatically, causing additional computation steps.
- To improve performance of repeated computations (e.g. in loops), consider preparing the data
accordingly to avoid unecessary computations.
Channel functions
baseband_freq_response - Transforms the channel into frequency domain and returns the frequency response
-
Usage:
from quadriga_lib import channel
hmat = channel.baseband_freq_response( coeff, delay, bandwidth, carriers, pilot_grid, snap );
-
Input Arguments:
coeff
Channel coefficients, complex-valued, List of length n_snap,
Each list item is an munpy.ndarray of Shape ( n_rx, n_tx, n_path ) where n_path can be different
for each snapshot.
delay
Propagation delay in seconds, List of length n_snap,
Each list item is an munpy.ndarray of Shape ( n_rx, n_tx, n_path ) or ( 1, 1, n_path ) where
n_path can be different for each snapshot.
bandwidth
The baseband bandwidth in [Hz], scalar
carriers (optional)
Number of carriers, equally spaced across the bandwidth. The first entry of the generated spectrum
is equal to the center frequency f0. The spectrum is generated from f0 to f0+bandwidth. This
argument is only evaluated if pilot_grid is not provided. Default value = 128
pilot_grid (optional)
Sub-carrier positions relative to the bandwidth. The carrier positions are given relative to the
bandwidth where '0' is the begin of the spectrum (i.e., the center frequency f0) and '1' is
equal to f0+bandwidth. To obtain the channel frequency response centered around f0, the
input variable 'pilot_grid' must be set to '(-N/2:N/2)/N', where N is the number of sub-
carriers. Vector of length: ( n_carriers )
snap (optional)
Snapshot indices for which the frequency response should be generated (1-based index). If this
variable is not given, all snapshots are processed. Length: ( n_out )
-
Output Argument:
hmat
Freq. domain channel matrices (H), complex-valued, Shape ( n_rx, n_tx, n_carriers, n_out )
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:
fn
Filename of the OBJ file, string, required
max_no_paths (optional)
Maximum number of paths to be shown, optional, default: 0 = export all above gain_min
gain_max (optional)
Maximum path gain in dB (only for color-coding), optional, default = -60.0
gain_min (optional)
Minimum path gain in dB (for color-coding and path selection), optional, default = -140.0
colormap (optional)
Colormap for the visualization, string, supported are 'jet', 'parula', 'winter', 'hot', 'turbo',
'copper', 'spring', 'cool', 'gray', 'autumn', 'summer', optional, default = 'jet'
radius_max (optional)
Maximum tube radius in meters, optional, default = 0.05
radius_min (optional)
Minimum tube radius in meters, optional, default = 0.01
n_edges (optional)
Number of vertices in the circle building the tube, must be >= 3, optional, default = 5
rx_position
Receiver positions, required, size [3, n_snap] or [3, 1]
tx_position
Transmitter positions, required, size [3, n_snap] or [3, 1]
no_interact
Number interaction points of paths with the environment, required, uint32, Size [n_path, n_snap]
interact_coord
Interaction coordinates, required, Size [3, max(sum(no_interact)), n_snap]
center_freq
Center frequency in [Hz], required, Size [n_snap, 1] or scalar
coeff
Channel coefficients, complex valued, required only if path_polarization is not given,
Size [n_rx, n_tx, n_path, n_snap]
i_snap
(optional)
Snapshot indices, optional, 0-based, range [0 ... n_snap - 1]
get_ieee_indoor - Generate indoor MIMO channel realizations for IEEE TGn/TGac/TGax/TGah models
-
Description:
- Generates one or multiple indoor channel realizations based on IEEE TGn/TGac/TGax/TGah model definitions.
- 2D model: no elevation angles are used; azimuth angles and planar motion are considered.
- For 3D antenna models (default models from arrayant generate), only the azimuth cut at
elevation_grid = 0 is used
- Supports channel model types
A, B, C, D, E, F (as defined by TGn) via ChannelType.
- Can generate MU-MIMO channels (
n_users > 1) with per-user distances/floors and optional angle
offsets according to TGac.
- Optional time evolution via
observation_time, update_rate, and mobility parameters.
-
Declaration:
from quadriga_lib import channel
chan = 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 );
-
ap_array:
ap_array
Dictionary containing the access point array antenna with n_tx elements (= ports after element coupling)
e_theta_re |
e-theta field component, real part |
Shape: (n_elevation_ap, n_azimuth_ap, n_elements_ap) |
e_theta_im |
e-theta field component, imaginary part |
Shape: (n_elevation_ap, n_azimuth_ap, n_elements_ap) |
e_phi_re |
e-phi field component, real part |
Shape: (n_elevation_ap, n_azimuth_ap, n_elements_ap) |
e_phi_im |
e-phi field component, imaginary part |
Shape: (n_elevation_ap, n_azimuth_ap, n_elements_ap) |
azimuth_grid |
Azimuth angles in [rad], -pi to pi, sorted |
Shape: (n_azimuth_ap) |
elevation_grid |
Elevation angles in [rad], -pi/2 to pi/2, sorted |
Shape: (n_elevation_ap) |
element_pos |
Antenna element (x,y,z) positions, optional |
Shape: (3, n_elements_ap) |
coupling_re |
Coupling matrix, real part, optional |
Shape: (n_elements_ap, n_ports_ap) |
coupling_im |
Coupling matrix, imaginary part, optional |
Shape: (n_elements_ap, n_ports_ap) |
sta_array
Dictionary containing the mobile station array antenna with n_rx elements (= ports after element coupling)
e_theta_re |
e-theta field component, real part |
Shape: (n_elevation_sta, n_azimuth_sta, n_elements_sta) |
e_theta_im |
e-theta field component, imaginary part |
Shape: (n_elevation_sta, n_azimuth_sta, n_elements_sta) |
e_phi_re |
e-phi field component, real part |
Shape: (n_elevation_sta, n_azimuth_sta, n_elements_sta) |
e_phi_im |
e-phi field component, imaginary part |
Shape: (n_elevation_sta, n_azimuth_sta, n_elements_sta) |
azimuth_grid |
Azimuth angles in [rad], -pi to pi, sorted |
Shape: (n_azimuth_sta) |
elevation_grid |
Elevation angles in [rad], -pi/2 to pi/2, sorted |
Shape: (n_elevation_sta) |
element_pos |
Antenna element (x,y,z) positions, optional |
Shape: (3, n_elements_sta) |
coupling_re |
Coupling matrix, real part, optional |
Shape: (n_elements_sta, n_ports_sta) |
coupling_im |
Coupling matrix, imaginary part, optional |
Shape: (n_elements_sta, n_ports_sta) |
ChannelType
Channel model type as defined by TGn. String. Supported: A, B, C, D, E, F.
CarrierFreq_Hz = 5.25e9 (optional)
Carrier frequency in Hz.
tap_spacing_s = 10e-9 (optional)
Tap spacing in seconds. Must be equal to 10 ns / 2^k (TGn default = 10e-9).
n_users = 1 (optional)
Number of users (only for TGac, TGah). Output struct array length equals n_users.
observation_time = 0 (optional)
Channel observation time in seconds. 0 creates a static channel.
update_rate = 1e-3 (optional)
Channel update interval in seconds (only relevant when observation_time > 0).
speed_station_kmh = 0 (optional)
Station movement speed in km/h. Movement direction is AoA_offset. Only relevant when observation_time > 0.
speed_env_kmh = 1.2 (optional)
Environment movement speed in km/h. Default 1.2 for TGn, use 0.089 for TGac. Only relevant when observation_time > 0.
vector Dist_m = [4.99] (optional)
TX-to-RX distance(s) in meters. Length n_users or length 1 (same distance for all users).
vector n_floors = [0] (optional)
Number of floors for TGah model (per user), up to 4 floors. Length n_users or length 1.
uplink = false (optional)
Channel direction flag. Default is downlink; set to true to generate reverse (uplink) direction.
offset_angles = [] (optional)
Offset angles in degree for MU-MIMO channels. Empty uses model defaults (TGac auto for n_users > 1).
Shape [4, n_users] with rows: AoD LOS, AoD NLOS, AoA LOS, AoA NLOS.
n_subpath = 20 (optional)
Number of sub-paths per path/cluster used for Laplacian angular spread mapping.
Doppler_effect = 50 (optional)
Special Doppler effects: models D, E (fluorescent lights, value = mains freq.) and F (moving vehicle speed in km/h).
Use 0 to disable.
seed = -1 (optional)
Numeric seed for repeatability. -1 disables the fixed seed and uses the system random device.
KF_linear = NAN (optional)
Overwrites the model-specific KF-value. If this parameter is NAN (default) or negative, model defaults are used:
A/B/C (KF = 1 for d < dBP, 0 otherwise); D (KF = 2 for d < dBP, 0 otherwise); E/F (KF = 4 for d < dBP, 0 otherwise).
KF is applied to the first tap only. Breakpoint distance is ignored for KF_linear >= 0.
XPR_NLOS_linear = NAN (optional)
Overwrites the model-specific Cross-polarization ratio. If this parameter is NAN (default) or negative,
the model default of 2 (3 dB) is used. XPR is applied to all NLOS taps.
SF_std_dB_LOS = NAN (optional)
Overwrites the model-specific shadow fading for LOS channels. If this parameter is NAN (default),
the model default of 3 dB is used. SF_std_dB_LOS is applied to all LOS channels, where the
AP-STA distance d < dBP.
SF_std_dB_NLOS = NAN (optional)
Overwrites the model-specific shadow fading for LOS channels. If this parameter is NAN (default),
the model defaults are A/B: 4 dB, C/D: 5 dB, E/F: 6 dB. SF_std_dB_NLOS is applied to all NLOS channels,
where the AP-STA distance d >= dBP.
dBP_m = NAN (optional)
Overwrites the model-specific breakpoint distance. If this parameter is NAN (default) or negative,
the model defaults are A/B/C: 5 m, D: 10 m, E: 20 m, F: 30 m.
-
Returns:
chan
List of length n_users containing dictionaries of channel data with the following keys.
name |
Channel name |
String |
tx_position |
Transmitter positions (AP for downlink, STA for uplink) |
Shape: (3, 1) or (3, n_snap) |
rx_position |
Receiver positions (STA for downlink, AP for uplink) |
Shape: (3, 1) or (3, n_snap) |
tx_orientation |
Transmitter orientation, Euler angles (AP for downlink, STA for uplink) |
Shape: (3, 1) or (3, n_snap) |
rx_orientation |
Receiver orientation, Euler angles (STA for downlink, AP for uplink) |
Shape: (3, 1) or (3, n_snap) |
coeff |
Channel coefficients, complex valued |
list of [n_rx, n_tx, n_path_s] |
delay |
Propagation delays in seconds |
list of [n_rx, n_tx, n_path_s] |
path_gain |
Path gain before antenna, linear scale |
list of [n_path_s] |
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:
fn
Filename of the HDF5 file, string
nx (optional)
Number of elements on the x-dimension, Default = 65536
ny (optional)
Number of elements on the x-dimension, Default = 1
nz (optional)
Number of elements on the x-dimension, Default = 1
nw (optional)
Number of elements on the x-dimension, Default = 1
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:
fn
Filename of the HDF5 file, string
ix
Storage index for x-dimension, Default = 0
iy
Storage index for y-dimension, Default = 0
iz
Storage index for z-dimension, Default = 0
iw
Storage index for w-dimension, Default = 0
snap (optional)
Snapshot range, 0-based notation; optional; vector, default: empty = read all
-
Output Arguments:
data
Dictionary containing the data in the HDF file with the following keys:
par |
Dictionary of unstructured data |
Variable |
rx_position |
Receiver positions |
[3, n_snap] or [3, 1] |
tx_position |
Transmitter positions |
[3, n_snap] or [3, 1] |
coeff |
Channel coefficients, complex valued |
list of [n_rx, n_tx, n_path_s] |
delay |
Propagation delays in seconds |
list of [n_rx, n_tx, n_path_s] or [1, 1, n_path_s] |
center_freq |
Center frequency in [Hz] |
[n_snap] or scalar |
name |
Name of the channel |
String |
initial_pos |
Index of reference position, 1-based |
uint32, scalar |
path_gain |
Path gain before antenna, linear scale |
list of [n_path_s] |
path_length |
Path length from TX to RX phase center in m |
list of [n_path_s] |
polarization |
Polarization transfer function, complex valued |
list of [4, n_path_s] |
path_angles |
Departure and arrival angles {AOD, EOD, AOA, EOA} in rad |
list of [n_path, 4_s] |
path_fbs_pos |
First-bounce scatterer positions |
list of [3, n_path_s] |
path_lbs_pos |
Last-bounce scatterer positions |
list of [3, n_path_s] |
no_interact |
Number interaction points of paths with the environment |
uint32, list of [n_path_s] |
interact_coord |
Interaction coordinates |
list of [3, max(sum(no_interact))] |
rx_orientation |
Receiver orientation |
[3, n_snap] or [3] |
tx_orientation |
Transmitter orientation |
[3, n_snap] or [3] |
-
Caveat:
- Only datasets that are present in the HDF file are returned in the dictionary.
- Although the data is stored in single precision, it is converted to double precision by default.
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.
Theo 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:
fn
Filename of the HDF5 file, string
ix
Storage index for x-dimension, Default = 0
iy
Storage index for y-dimension, Default = 0
iz
Storage index for z-dimension, Default = 0
iw
Storage index for w-dimension, Default = 0
name
Name of the dataset; String
-
Output Argument:
dset
Output data. Type and size is defined by the dataspace in the file
-
Caveat:
- Only datasets that are present in the HDF file are returned in the dictionary.
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:
fn
Filename of the HDF5 file, string
ix
Storage index for x-dimension, Default = 0
iy
Storage index for y-dimension, Default = 0
iz
Storage index for z-dimension, Default = 0
iw
Storage index for w-dimension, Default = 0
-
Output Argument:
names
List of names of all these at the given location in the files; Cell array of strings
hdf5_read_layout - Read the storage layout of channel data inside an HDF5 file
hdf5_reshape_layout - Reshapes the storage layout inside an existing HDF5 file
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, rx_position, tx_position, ...
coeff_re, coeff_im, delay, center_freq, name, initial_pos, path_gain, path_length, ...
path_polarization, path_angles, path_fbs_pos, path_lbs_pos, no_interact, interact_coord, ...
rx_orientation, tx_orientation )
-
Input Arguments:
fn
Filename of the HDF5 file, string
ix
Storage index for x-dimension, Default = 0
iy
Storage index for y-dimension, Default = 0
iz
Storage index for z-dimension, Default = 0
iw
Storage index for w-dimension, Default = 0
par
Dictionary of unstructured data, can be empty if no unstructured data should be written
- Structured data: (double precision)
Each snapshot may have a different number of paths n_path_s. Variable-length data is provided as lists.
rx_pos |
Receiver positions |
[3, n_snap] or [3, 1] |
tx_pos |
Transmitter positions |
[3, n_snap] or [3, 1] |
coeff |
Channel coefficients, complex valued |
list of [n_rx, n_tx, n_path_s] |
delay |
Propagation delays in seconds |
list of [n_rx, n_tx, n_path_s] or [1, 1, n_path_s] |
center_freq |
Center frequency in [Hz] |
[n_snap] or scalar |
name |
Name of the channel |
String |
initial_pos |
Index of reference position, 1-based |
uint32, scalar |
path_gain |
Path gain before antenna, linear scale |
list of [n_path_s] |
path_length |
Path length from TX to RX phase center in m |
list of [n_path_s] |
polarization |
Polarization transfer function, complex valued |
list of [4, n_path_s] |
path_angles |
Departure and arrival angles {AOD, EOD, AOA, EOA} in rad |
list of [n_path, 4_s] |
path_fbs_pos |
First-bounce scatterer positions |
list of [3, n_path_s] |
path_lbs_pos |
Last-bounce scatterer positions |
list of [3, n_path_s] |
no_interact |
Number interaction points of paths with the environment |
uint32, list of [n_path_s] |
interact_coord |
Interaction coordinates |
list of [3, max(sum(no_interact))] |
rx_orientation |
Transmitter orientation |
[3, n_snap] or [3] |
tx_orientation |
Receiver orientation |
[3, n_snap] or [3] |
-
Output Arguments:
storage_dims
Size of the dimensions of the storage space, vector with 4 elements, i.e. [nx,ny,nz,nw].
-
Caveat:
- If the file exists already, the new data is added to the exisiting file
- If a new file is created, a storage layout is created to store the location of datasets in the file
- For
location = [ix] storage layout is [65536,1,1,1] or [ix,1,1,1] if (ix > 65536)
- For
location = [ix,iy] storage layout is [1024,64,1,1]
- For
location = [ix,iy,iz] storage layout is [256,16,16,1]
- For
location = [ix,iy,iz,iw] storage layout is [128,8,8,8]
- You can create a custom storage layout by creating the file first using "
hdf5_create_file"
- You can reshape the storage layout by using "
hdf5_reshape_storage", but the total number of elements must not change
- Inputs can be empty or missing.
- All structured data is written in single precision (but can can be provided as single or double)
- Unstructured datatypes are maintained in the HDF file
- Supported unstructured types: string, double, float, (u)int32, (u)int64
- Supported unstructured size: up to 3 dimensions
- Storage order of the unstructured data is maintained
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:
fn
Filename of the HDF5 file, string
ix
Storage index for x-dimension, Default = 0
iy
Storage index for y-dimension, Default = 0
iz
Storage index for z-dimension, Default = 0
iw
Storage index for w-dimension, Default = 0
name
Name of the dataset; String
-
Caveat:
- Throws an error if dataset already exists at this location
- Throws an error if file does not exist (use hdf5_create_file)
- Supported types: string, double, float, (u)int32, (u)int64
- Supported size: up to 3 dimensions
- Storage order is maintained
qrt_file_parse - Read metadata from a QRT file
-
Usage:
from quadriga_lib import channel
# Separate outputs
no_cir, no_orig, no_dest, cir_offset, orig_names, dest_names = channel.qrt_file_parse( fn )
# Output as tuple
data = channel.qrt_file_parse( fn )
-
Input Argument:
fn
Filename of the QRT file, string
-
Output Arguments:
no_cir
Number of channel snapshots per origin point
no_orig
Number of origin points (e.g., TXs)
no_dest
Number of destinations (RX)
cir_offset
CIR offset for each destination
orig_names
Names of the origin points (TXs), list of strings
dest_names
Names of the destination points (RXs), list of strings
qrt_file_read - Read ray-tracing data from QRT file
Miscellaneous / Tools
cart2geo - Transform Cartesian (x,y,z) coordinates to Geographic (az, el, length) coordinates
components - Returns the version numbers of all quadriga-lib sub-components
version - Returns the quadriga-lib version number
write_png - Write data to a PNG file
-
Description:
- Converts input data into a color-coded PNG file for visualization
- Support optional selection of a colormap, as well a minimum and maximum value limits
- Uses the LodePNG library for PNG writing
-
Declaration:
import quadriga_lib
quadriga_lib.tools.write_png( fn, data, colormap, min_val, max_val, log_transform )
-
Arguments:
fn
Filename of the PNG file, string, required
data
Data matrix, required, size [N, M]
colormap (optional)
Colormap for the visualization, string, supported are 'jet', 'parula', 'winter', 'hot', 'turbo',
'copper', 'spring', 'cool', 'gray', 'autumn', 'summer', optional, default = 'jet'
min_val (optional)
Minimum value. Values below this value will have be encoded with the color of the smallest value.
If NAN is provided (default), the lowest values is determined from the data.
max_val (optional)
Maximum value. Values above this value will have be encoded with the color of the largest value.
If NAN is provided (default), the largest values is determined from the data.
log_transform (optional)
If enabled, the data values are transformed to the log-domain (10*log10(data)) before processing.
Default: false (disabled)
Site-Specific Simulation Tools
icosphere - Construct a geodesic polyhedron (icosphere), a convex polyhedron made from triangles
-
Description:
An icosphere is constructed by subdividing faces of an icosahedron, a polyhedron with 20 faces,
12 vertices and 30 edges, and then projecting the new vertices onto the surface of a sphere. The
resulting mesh has 6 triangles at each vertex, except for 12 vertices which have 5 triangles.
The approximate equilateral triangles have roughly the same edge length and surface area.
-
Usage:
from quadriga_lib import RTtools
center, length, vert, direction = RTtools.icosphere( no_div, radius, direction_xyz )
-
Input Arguments:
no_div
Number of divisions per edge of the generating icosahedron. The resulting number of faces is
equal to no_face = 20 · no_div^2
radius
Radius of the sphere in meters
direction_xyz
Direction format indicator: 0 = Spherical (default), 1 = Cartesian
-
Output Arguments (tuple containing 4 values):
center
Position of the center point of each triangle; Shape: ( no_face, 3 )
length
Length of the vector pointing from the origin to the center point. This number is smaller than
1 since the triangles are located inside the unit sphere; Shape: ( no_face )
vert
The 3 vectors pointing from the center point to the vertices of each triangle; the values are
in the order [ v1x, v1y, v1z, v2x, v2y, v2z, v3x, v3y, v3z ]; Shape: ( no_face, 9 )
direction
The directions of the vertex-rays. If the format indicator direction_xyz is set to 0, the
output is in geographic coordinates (azimuth and elevation angle in rad); the values are in the
order ( v1az, v1el, v2az, v2el, v3az, v3el ];Shape: ( no_face, 6 ) If the format indicator
direction_xyz is set to 1, the output is in Cartesian coordinates and the values are in the
order [ v1x, v1y, v1z, v2x, v2y, v2z, v3x, v3y, v3z ]; Shape: ( no_face, 9 )
mitsuba_xml_file_write - Write geometry and material data to a Mitsuba 3 XML scene file.
-
Description:
Converts a triangular surface mesh into the XML format understood by Mitsuba 3
www.mitsuba-renderer.org.
The generated file can be loaded directly by NVIDIA Sionna RT for differentiable radio-propagation
simulations.
- Converts a 3D geometry mesh into Mitsuba 3 XML format for use with rendering tools.
- Enables exporting models from
quadriga-lib to be used with Mitsuba 3 or Sionna RT:
- Mitsuba 3: Research-oriented retargetable rendering system.
- NVIDIA Sionna: Hardware-accelerated differentiable ray tracer for wireless propagation, built on Mitsuba 3.
- Supports grouping faces into named objects and assigning materials by name.
- Optionally maps materials to ITU default presets used by Sionna RT.
-
Usage:
from quadriga_lib import RTtools
RTtools.mitsuba_xml_file_write( fn, vert_list, face_ind, obj_id, mtl_id, obj_names, mtl_names, bsdf, map_to_itu )
-
Input Arguments:
fn
Output file name (including path and .xml extension).
vert_list
Vertex list, size [n_vert, 3], each row is a vertex (x, y, z) in Cartesian coordinates [m].
face_ind
Face indices (0-based), size [n_mesh, 3], each row defines a triangle via vertex indices.
obj_id (input)
Object indices (1-based), size [n_mesh]. Assigns each triangle to an object.
mtl_id (input)
Material indices (1-based), size [n_mesh]. Assigns each triangle to a material.
obj_names
List of object names. Length must be equal to max(obj_ind).
mtl_names
List of material names. Length must be equal to max(mtl_ind).
bsdf = [] (optional input)
Material reflectivity data (BSDF parameters), size [len(mtl_names), 17]. If omitted, the null BSDF is used.
Note that Sionna RT ignores all BSDF parameters. They are only used by the Mitsuma rendering system.
See obj_file_read for a definition of the data fields.
map_to_itu = false (optional input)
If true, maps material names to ITU-defined presets used by Sionna RT. Default: false
-
See also:
obj_file_read - Reads a triangulated 3D polygon mesh from a Wavefront OBJ file
-
Description:
The function imports a polygon mesh from an OBJ file. The OBJ file format is a straightforward data
format, representing 3D geometry. It details the position of each vertex and defines polygons as lists
of these vertices. By default, vertices are arranged in a counter-clockwise order, eliminating the
need for explicit declaration of face normals. When exporting the mesh from software like Blender,
it's essential to triangulate the mesh and include material definitions. If the material name
exists in the material database, the function loads the corresponding properties.
Otherwise, it defaults to using standard properties.
-
Usage:
from quadriga_lib import RTtools
# Return as separate variables
mesh, mtl_prop, vert_list, face_ind, obj_ind, mtl_ind, obj_names, mtl_names, bsdf = RTtools.obj_file_read( fn )
# Return as tuple with 8 elements
data = RTtools.obj_file_read( fn )
-
Input Arguments:
fn
Filename of the OBJ file, string
-
Output Arguments:
mesh, data[0]
Vertices of the triangular mesh in global Cartesian coordinates. Each face is described by 3 points
in 3D-space. Hence, a face has 9 values in the order [ v1x, v1y, v1z, v2x, v2y, v2z, v3x, v3y, v3z ];
Size: [ no_mesh, 9 ]
mtl_prop, data[1]
Material properties of each mesh element; If no material is defined for an object, the properties
for vacuum are used. Size: [ no_mesh, 5 ]
vert_list, data[2]
List of vertices found in the OBJ file; Size: [ no_vert, 3 ]
face_ind, data[3]
Triangular faces are defined by three vertices. Vertex indices match the corresponding vertex elements
of the previously defined vert_list (0-based).
uint32; Size: [ no_mesh, 3 ]
obj_id, data[4]
Mesh elements in the OBJ file can be grouped into objects (e.g. 12 triangles define the walls of a
cube). Each object is identified by a unique ID (1-based index of obj_names).
uint32; Size: [ no_mesh, 1 ]
mtl_id, data[5]
Each mesh element gets assigned a material and each unique material gets assigned an ID (1-based
index of mtl_names). Different faces of an object can have different materials. If no material is
defined in the OBJ file, the id is set to 0 and no entry is made in mtl_names.
uint32; Size: [ no_mesh, 1 ]
obj_names, data[6]
Names of the objects in the OBJ file; List of strings
mtl_names, data[7]
Names of the materials in the OBJ file; List of strings
bsdf, data[8]
Principled BSDF (Bidirectional Scattering Distribution Function) values extracted from the
.MTL file. Size [mtl_names.size(), 17]. Values are:
| 0 |
Base Color Red |
Range 0-1 |
Default = 0.8 |
| 1 |
Base Color Green |
Range 0-1 |
Default = 0.8 |
| 2 |
Base Color Blue |
Range 0-1 |
Default = 0.8 |
| 3 |
Transparency (alpha) |
Range 0-1 |
Default = 1.0 (fully opaque) |
| 4 |
Roughness |
Range 0-1 |
Default = 0.5 |
| 5 |
Metallic |
Range 0-1 |
Default = 0.0 |
| 6 |
Index of refraction (IOR) |
Range 0-4 |
Default = 1.45 |
| 7 |
Specular Adjustment to the IOR |
Range 0-1 |
Default = 0.5 (no adjustment) |
| 8 |
Emission Color Red |
Range 0-1 |
Default = 0.0 |
| 9 |
Emission Color Green |
Range 0-1 |
Default = 0.0 |
| 10 |
Emission Color Blue |
Range 0-1 |
Default = 0.0 |
| 11 |
Sheen |
Range 0-1 |
Default = 0.0 |
| 12 |
Clearcoat |
Range 0-1 |
Default = 0.0 |
| 13 |
Clearcoat roughness |
Range 0-1 |
Default = 0.0 |
| 14 |
Anisotropic |
Range 0-1 |
Default = 0.0 |
| 15 |
Anisotropic rotation |
Range 0-1 |
Default = 0.0 |
| 16 |
Transmission |
Range 0-1 |
Default = 0.0 |
-
Material properties:
Each material is defined by its electrical properties. Radio waves that interact with a building will
produce losses that depend on the electrical properties of the building materials, the material
structure and the frequency of the radio wave. The fundamental quantities of interest are the electrical
permittivity (ϵ) and the conductivity (σ). A simple regression model for the frequency dependence is
obtained by fitting measured values of the permittivity and the conductivity at a number of frequencies.
The five parameters returned in mtl_prop then are:
- Real part of relative permittivity at f = 1 GHz (a)
- Frequency dependence of rel. permittivity (b) such that ϵ = a · f^b
- Conductivity at f = 1 GHz (c)
- Frequency dependence of conductivity (d) such that σ = c· f^d
- Fixed attenuation in dB applied to each transition
A more detailed explanation together with a derivation can be found in ITU-R P.2040. The following
list of material is currently supported and the material can be selected by using the usemtl tag
in the OBJ file. When using Blender, the simply assign a material with that name to an object or face.
In addition, custom properties can be set by assigning adding the 5 properties after the material
name, separated by :, e.g.:
usemtl custom::2.1:0.1:0.1:0.5:20
The following materials are defined by default:
| Name |
a |
b |
c |
d |
Att |
max fGHz |
|
| vacuum / air |
1.0 |
0.0 |
0.0 |
0.0 |
0.0 |
100 |
|
| textiles |
1.5 |
0.0 |
5e-5 |
0.62 |
0.0 |
100 |
|
| plastic |
2.44 |
0.0 |
2.33e-5 |
1.0 |
0.0 |
100 |
|
| ceramic |
6.5 |
0.0 |
0.0023 |
1.32 |
0.0 |
100 |
|
| sea_water |
80.0 |
-0.25 |
4.0 |
0.58 |
0.0 |
100 |
|
| sea_ice |
3.2 |
-0.022 |
1.1 |
1.5 |
0.0 |
100 |
|
| water |
80.0 |
-0.18 |
0.6 |
1.52 |
0.0 |
20 |
|
| water_ice |
3.17 |
-0.005 |
5.6e-5 |
1.7 |
0.0 |
20 |
|
| itu_concrete |
5.24 |
0.0 |
0.0462 |
0.7822 |
0.0 |
100 |
|
| itu_brick |
3.91 |
0.0 |
0.0238 |
0.16 |
0.0 |
40 |
|
| itu_plasterboard |
2.73 |
0.0 |
0.0085 |
0.9395 |
0.0 |
100 |
|
| itu_wood |
1.99 |
0.0 |
0.0047 |
1.0718 |
0.0 |
100 |
|
| itu_glass |
6.31 |
0.0 |
0.0036 |
1.3394 |
0.0 |
100 |
|
| itu_ceiling_board |
1.48 |
0.0 |
0.0011 |
1.075 |
0.0 |
100 |
|
| itu_chipboard |
2.58 |
0.0 |
0.0217 |
0.78 |
0.0 |
100 |
|
| itu_plywood |
2.71 |
0.0 |
0.33 |
0.0 |
0.0 |
40 |
|
| itu_marble |
7.074 |
0.0 |
0.0055 |
0.9262 |
0.0 |
60 |
|
| itu_floorboard |
3.66 |
0.0 |
0.0044 |
1.3515 |
0.0 |
100 |
|
| itu_metal |
1.0 |
0.0 |
1.0e7 |
0.0 |
0.0 |
100 |
|
| itu_very_dry_ground |
3.0 |
0.0 |
0.00015 |
2.52 |
0.0 |
10 |
|
| itu_medium_dry_ground |
15.0 |
-0.1 |
0.035 |
1.63 |
0.0 |
10 |
|
| itu_wet_ground |
30.0 |
-0.4 |
0.15 |
1.3 |
0.0 |
10 |
|
| itu_vegetation |
1.0 |
0.0 |
1.0e-4 |
1.1 |
0.0 |
100 |
|
| irr_glass |
6.27 |
0.0 |
0.0043 |
1.1925 |
23.0 |
100 |
|
point_cloud_aabb - Calculates the axis-aligned bounding box (AABB) for a 3D point cloud or a set of sub-clouds
point_cloud_segmentation - Rearranges elements of a point cloud into smaller sub-clouds
-
Description:
This function processes a large 3D point cloud by clustering closely spaced points and recursively
partitioning it into smaller sub-clouds, each below a specified size threshold. It minimizes the
axis-aligned bounding box of each sub-cloud while striving to maintain a target number of points
per cluster.
Sub-clouds are aligned to a specified SIMD vector size (e.g., for AVX or CUDA), with padding applied
as needed. The function outputs a reorganized version of the input points (pointsR), where points
are grouped by sub-cloud, and provides forward and reverse index maps to track the reordering. This
organization is particularly useful for optimizing spatial processing tasks such as bounding volume
hierarchies or GPU batch execution.
-
Usage:
from quadriga_lib import RTtools
# Output as tuple
data = RTtools.point_cloud_segmentation( points, target_size, vec_size )
# Unpacked outputs
points_out, sub_cloud_ind, forward_ind, reverse_ind = RTtools.point_cloud_segmentation( points, target_size, vec_size )
-
Input Arguments:
points
Points in 3D-Cartesian space; Size: [ n_points, 3 ]
target_size (optional)
The target number of elements of each sub-cloud. Default value = 1024. For best performance, the
value should be around 10 * sgrt( n_points )
vec_size (optional)
Vector size for SIMD processing (e.g. 8 for AVX2, 32 for CUDA). Default value = 1.
For values > 1,the number of rows for each sub-cloud in the output is increased to a multiple
of vec_size. For padding, zero-sized triangles are placed at the center of the AABB of
the corresponding sub-cloud.
-
Output Arguments:
points_out, data[0]
Points in 3D-Cartesian space; singe or double precision; Size: [ n_points_out, 3 ]
sub_cloud_ind, data[1]
Start indices of the sub-clouds in 0-based notation. Type: uint32; Vector of length [ n_sub_cloud ]
forward_ind, data[2]
Indices for mapping elements of "points_in" to "points_out"; 1-based;
Length: [ n_points_out ]; For vec_size > 1, the added elements not contained in the input
are indicated by zeros.
reverse_ind, data[3]
Indices for mapping elements of "points_out" to "points"; 0-based; Length: [ n_points ]
point_inside_mesh - Test whether 3D points are inside a triangle mesh using raycasting
-
Description:
- Uses raycasting to determine whether each 3D point lies inside a triangle mesh.
- Requires that the mesh is watertight and all normals are pointing outwards.
- For each point, multiple rays are cast in various directions.
- If any ray intersects a mesh element with a negative incidence angle, the point is classified as inside.
- Output can be binary (0 = outside, 1 = inside) or labeled with object indices.
-
Usage:
from quadriga_lib import RTtools
result = RTtools.point_inside_mesh( points, mesh, obj_ind, distance )
-
Input Arguments:
points (input)
3D point coordinates to test, size [n_points, 3].
mesh (input)
Triangular mesh faces. Each row represents a triangle using 3 vertices in row-major format
(x1,y1,z1,x2,y2,z2,x3,y3,z3), size [n_mesh, 9].
obj_ind (optional input)
Optional object index for each mesh element (1-based), size [n_mesh]. If provided, the return
vector will contain the index of the enclosing object instead of binary values.
distance (optional input)
Optional distance in meters from objects that should be considered as inside the object.
Possible range: 0 - 20 m. Using this parameter significantly increases computation time.
-
Output Arguments:
result
For each point: Returns 0 if the point is outside the mesh (or all objects), 1 if inside
(or close to) any mesh object (if obj_ind not given), or returns the 1-based object index
if obj_ind is provided. Size: [n_points]
ray_point_intersect - Calculates which 3D points are intersected by volumetric ray beams
-
Description:
Unlike traditional ray tracing (rays are infinitesimal lines), beam tracing models rays as
volumes. Each beam is defined by a triangular wavefront whose three vertices diverge as the
beam propagates, capturing real-world spread (e.g., radio-wave divergence) and enabling realistic
energy distribution across the beam’s cross-section. Because beams have volume, intersection tests
are volumetric rather than line-to-geometry.
A ray beam is specified by:
- An origin point.
- Three aperture vectors from the origin to the vertices of an initial triangular wavefront
that defines the beam’s cross-section at the origin.
- Three per-vertex direction vectors (one per vertex) that govern how each vertex, and thus the
triangle, diverges as the beam extends. Directions need not be normalized.
What the function does
- Tests whether each point in a 3D Cartesian point cloud lies inside any of the defined ray beams.
- For every input point, returns a list of 0-based ray indices of beams that intersect that point.
Performance & usage notes
- Optional support for pre-segmented point clouds (e.g., from point_cloud_segmentation) to reduce computation.
- All internal computations use single-precision floats for speed.
- Utilizes AVX2 vectorization when supported by the CPU.
- For best accuracy, use a small tube radius and well-distributed points.
-
Usage:
from quadriga_lib import RTtools
hit_count, ray_ind = RTtools.ray_point_intersect( orig, trivec, tridir, points, sub_cloud_ind, target_size )
-
Input Arguments:
orig
Ray origins in 3D Cartesian coordinates; Shape: (n_ray, 3)
trivec
Three vectors from each ray’s origin to the vertices of the triangular propagation tube (beam);
Order per row: [v1x, v1y, v1z, v2x, v2y, v2z, v3x, v3y, v3z]; Shape: (n_ray, 9)
tridir
Directions of the three vertex rays in Cartesian coordinates. Normalization not required.
Order per row: [d1x, d1y, d1z, d2x, d2y, d2z, d3x, d3y, d3z]; Shape: (n_ray, 9)
points
3D Cartesian coordinates of the point cloud to test. Shape: (n_points, 3)
sub_cloud_ind (optional)
0-based start indices of sub-clouds used to partition points for performance. If not provided
(empty array), sub-clouds may be computed automatically. Passing a scalar 0 disables sub-cloud calculation.
Shape: (n_sub_cloud,) (strictly increasing; typically starts with 0)
target_size (optional)
Desired sub-cloud size used only if sub_cloud_ind is not given or empty (guides automatic segmentation).
If it is not given (set to 0) and sub_cloud_ind is empty or also not given, the optimal valued is computed
from the number of points.
-
Output Arguments:
hit_count
Number of ray beams that hit a point. Shape: (n_points, )
ray_ind
List of length n_points; each list entry is a 1-D array of 0-based ray indices that hit that point.
Entries may be empty if no hit was detected.
-
See also:
ray_triangle_intersect - Calculates the intersection of rays and triangles in three dimensions
-
Description:
- This function implements the Möller–Trumbore ray-triangle intersection algorithm, known for its
efficiency in calculating the intersection of a ray and a triangle in three-dimensional space.
This method achieves its speed by eliminating the need for precomputed plane equations of the plane
containing the triangle.
- The algorithm defines the ray using two points: an origin and a destination. Similarly, the triangle
is specified by its three vertices.
- To enhance performance, this implementation leverages AVX2 intrinsic functions and OpenMP, when
available, to speed up the computational process.
-
Usage:
from quadriga_lib import RTtools
# Output as tuple
data = RTtools.ray_triangle_intersect( orig, dest, mesh, sub_mesh_index )
# Unpacked outputs
fbs, sbs, no_interact, fbs_ind, sbs_ind = RTtools.ray_triangle_intersect( orig, dest, mesh, sub_mesh_index )
-
Input Arguments:
orig
Ray origins in 3D Cartesian coordinates; Size: [ no_ray, 3 ]
dest
Ray destinations in 3D Cartesian coordinates; Size: [ no_ray, 3 ]
mesh
Vertices of the triangular mesh in global Cartesian coordinates. Each face is described by 3 points
in 3D-space. Hence, a face has 9 values in the order [ v1x, v1y, v1z, v2x, v2y, v2z, v3x, v3y, v3z ];
Size: [ no_mesh, 9 ]
sub_mesh_index (optional)
Start indices of the sub-meshes in 0-based notation. If this parameter is not given, intersections
are calculated for each mesh element, leading to poor performance for large meshes.
Vector of length [ n_sub_mesh ]
-
Output Arguments:
fbs, data[0]
First interaction point between the rays and the triangular mesh. If no interaction was found, the
FBS location is equal to dest. Size: [ no_ray, 3 ]
sbs, data[1]
Second interaction point between the rays and the triangular mesh. If no interaction was found, the
SBS location is equal to dest. Size: [ no_ray, 3 ]
no_interact, data[2]
Total number of interactions between the origin point and the destination; uint32; Length: [ no_ray ]
fbs_ind, data[3]
Index of the triangle that was hit by the ray at the FBS location; 1-based; uint32; Length: [ no_ray ]
sbs_ind, data[4]
Index of the triangle that was hit by the ray at the SBS location; 1-based; uint32; Length: [ no_ray ]
-
Caveat:
- All internal computation are done in single precision to achieve an additional 2x improvement in
speed compared to double precision when using AVX2 intrinsic instructions
-
See also:
triangle_mesh_aabb - Calculate the axis-aligned bounding box (AABB) of a triangle mesh and its sub-meshes
triangle_mesh_segmentation - Rearranges elements of a triangle mesh into smaller sub-meshes
-
Description:
This function processes the elements of a large triangle mesh by clustering those that are
closely spaced. The resulting mesh retains the same elements but rearranges their order.
The function aims to minimize the size of the axis-aligned bounding box around each cluster,
referred to as a sub-mesh, while striving to maintain a specific number of elements within
each cluster.
This approach is particularly useful in computer graphics and simulation applications where
managing computational resources efficiently is crucial. By organizing the mesh elements into
compact clusters, the function enhances rendering performance and accelerates computational
tasks, such as collision detection and physics simulations. It allows for quicker processing
and reduced memory usage, making it an essential technique in both real-time graphics rendering
and complex simulation environments.
-
Usage:
from quadriga_lib import RTtools
# Output as tuple
data = RTtools.triangle_mesh_segmentation( triangles, target_size, vec_size, mtl_prop )
# Unpacked outputs
triangles_out, sub_mesh_index, mesh_index, mtl_prop_out = RTtools.triangle_mesh_segmentation( triangles, target_size, vec_size, mtl_prop )
-
Input Arguments:
triangles
Vertices of the triangular mesh in global Cartesian coordinates. Each face is described by 3
points in 3D-space: [ v1x, v1y, v1z, v2x, v2y, v2z, v3x, v3y, v3z ]; Size: [ n_triangles, 9 ]
target_size (optional)
The target number of elements of each sub-mesh. Default value = 1024. For best performance, the
value should be around sgrt( n_triangles )
vec_size (optional)
Vector size for SIMD processing (e.g. 8 for AVX2, 32 for CUDA). Default value = 1.
For values > 1,the number of rows for each sub-mesh in the output is increased to a multiple
of vec_size. For padding, zero-sized triangles are placed at the center of the AABB of
the corresponding sub-mesh.
mtl_prop_in (optional)
Material properties of each mesh element; Size: [ n_triangles, 5 ]
If this is not provided, the corresponding mtl_prop_out will be empty.
-
Output Arguments:
triangles_out, data[0]
Vertices of the clustered mesh in global Cartesian coordinates; Size: [ n_triangles_out, 9 ]
sub_mesh_index, data[1]
Start indices of the sub-meshes in 0-based notation. Type: int; Vector of length [ n_sub_mesh ]
mesh_index, data[2]
Indices for mapping elements of "triangles_in" to "triangles_out"; 1-based;
Length: [ n_triangles_out ]; For vec_size > 1, the added elements not contained in the input
are indicated by zeros.
mtl_prop_out, data[3]
Material properties for the sub-divided triangle mesh elements. The values for the new faces are
copied from mtl_prop_in; Size: [ n_triangles_out, 5 ]; For vec_size > 1, the added elements
will contain the vacuum / air material.