Skip to content

Pipelines

DeepMIMO pipelines are end-to-end workflows that take a geographic location (GPS bounding box) all the way through ray tracing to a finished DeepMIMO dataset — with no manual steps and no proprietary GUI tools required.

deepmimo/pipelines/
  ├── osm_to_mitsuba.py      ← OSM → Mitsuba scene (core of the no-Blender pipeline)
  ├── txrx_placement.py      ← TX / RX grid generation
  ├── sionna_rt/             ← Sionna RT pipeline driver
  │   ├── sionna_raytracer.py
  │   └── sionna_utils.py
  └── utils/
      ├── geo_utils.py       ← Coordinate conversion, satellite imagery
      ├── osm_utils.py       ← Building queries and placement validation
      └── pipeline_utils.py  ← BS positioning, scenario management

What are pipelines?

A pipeline chains together several independent steps so a single function call can produce a complete ray tracing dataset from nothing but a set of GPS coordinates:

  1. Scene generation — download building footprints from OpenStreetMap and extrude them into 3D meshes (PLY + Mitsuba XML), or use an existing scene from Blender/Wireless InSite.
  2. TX / RX placement — convert GPS BS coordinates and UE grids into the local Cartesian system expected by the ray tracer.
  3. Ray tracing — run Sionna RT (or Wireless InSite) on the scene with the configured antennas.
  4. Export & convert — serialize the path data and convert it to the standardized DeepMIMO format.

The OSM pipeline (documented below) is the primary no-dependency workflow: it requires only pip install 'deepmimo[sionna]' and an internet connection.


OSM → Mitsuba Scene

The osm_to_mitsuba module converts a GPS bounding box into a Mitsuba 2 scene that Sionna RT can load directly. It queries the Overpass API for building footprints, extrudes each polygon into a closed 3D mesh, and writes the result as a scene.xml + PLY mesh collection.

Typical usage

from deepmimo.pipelines.osm_to_mitsuba import generate_scene

scene_folder = generate_scene(
    minlat=48.1355, minlon=11.5735,
    maxlat=48.1395, maxlon=11.5795,
    scene_folder="my_munich_scene",
)
# scene_folder/
#   scene.xml              — Mitsuba scene description
#   meshes/ground.ply      — flat ground plane
#   meshes/building_N.ply  — one PLY mesh per OSM building
#   osm_gps_origin.txt     — origin lat/lon for coordinate recovery

import sionna.rt as sionna_rt
scene = sionna_rt.load_scene(scene_folder + "/scene.xml", merge_shapes=False)

How it works

GPS bbox
  │
  ▼
Overpass API  →  list of (footprint_xy, height) per building
  │
  ▼
_extrude_footprint()  →  3D vertices + triangle indices per building
  │                       (bottom ring + top ring + side walls + roof fan)
  ▼
_write_ply()  →  building_N.ply (ASCII PLY, one file per building)
  │
  ▼
_write_mitsuba_xml()  →  scene.xml (ITU concrete material + shape refs)

Heights come from OSM tags in order of priority:

Tag Behaviour
height Parse float, strip " m" suffix
building:height Same
building:levels Multiply by 3 m per floor
(none) Default 10 m

The coordinate origin is the centre of the GPS bounding box, converted to UTM via utm.from_latlon. All PLY vertices are in local metres relative to this origin. The origin is saved to osm_gps_origin.txt so downstream code can recover GPS coordinates.

API reference

Generate a Mitsuba scene from OpenStreetMap building data.

Downloads building footprints for the given GPS bounding box, extrudes them into 3D meshes, creates a ground plane, and writes a Mitsuba XML scene file that Sionna RT can load directly.

Parameters:

Name Type Description Default
minlat float

South boundary latitude.

required
minlon float

West boundary longitude.

required
maxlat float

North boundary latitude.

required
maxlon float

East boundary longitude.

required
scene_folder str

Output directory. Created if it does not exist.

required
ground_padding float

Ground plane extends this many metres beyond the bounding box on each side (default 30 m).

GROUND_PADDING
verbose bool

Print progress messages.

True

Returns:

Type Description
str

Path to the generated scene folder (not the XML file), matching

str

the convention of raytrace_sionna and the Blender-based pipeline.

Download building footprints from OpenStreetMap for a GPS bounding box.

Tries Overpass API mirrors first; falls back to the OSM main API if all mirrors are unavailable. Each returned dict has:

  • coords: list of (lon, lat) tuples forming the closed polygon
  • height: estimated building height in metres

Parameters:

Name Type Description Default
minlat float

South boundary latitude.

required
minlon float

West boundary longitude.

required
maxlat float

North boundary latitude.

required
maxlon float

East boundary longitude.

required

Returns:

Type Description
list[dict[str, Any]]

List of building dicts, each with coords and height keys.


TX / RX Placement

txrx_placement converts pipeline configuration dicts into numpy position arrays.

Typical usage

from deepmimo.pipelines.txrx_placement import gen_plane_grid

# Generate a UE grid covering the scene
rx_pos = gen_plane_grid(
    min_coord1=xmin + 10, max_coord1=xmax - 10,
    min_coord2=ymin + 10, max_coord2=ymax - 10,
    spacing=30.0,
    fixed_coord=1.5,      # UE height in metres
    normal="z",           # grid lies in XY plane
)
# rx_pos: (N, 3) array of [x, y, z] positions

API reference

Generate a grid of points on a plane perpendicular to a major axis.

Parameters:

Name Type Description Default
min_coord1 float

Minimum value for first planar coordinate

required
max_coord1 float

Maximum value for first planar coordinate

required
min_coord2 float

Minimum value for second planar coordinate

required
max_coord2 float

Maximum value for second planar coordinate

required
spacing float

Grid spacing in meters

required
fixed_coord float

Value for the coordinate along the normal axis

required
normal str

Normal axis of the plane ('x', 'y', or 'z'). Defaults to 'z'

'z'

Returns:

Type Description
ndarray

np.ndarray: Grid points with shape (N, 3) where N is the number of points

Generate user grid in Cartesian coordinates.

Parameters:

Name Type Description Default
rt_params dict[str, Any]

Ray tracing parameters Required Parameters: - min_lat, min_lon, max_lat, max_lon (float): GPS coordinates of the area - origin_lat, origin_lon (float): Origin GPS coordinates - grid_spacing (float): Grid spacing in meters - ue_height (float): UE height in meters

required

Returns:

Type Description
ndarray

np.ndarray: User grid positions in Cartesian coordinates

Generate transmitter positions from GPS coordinates.

Parameters:

Name Type Description Default
rt_params dict[str, Any]

Ray tracing parameters dict with keys bs_lats, bs_lons, bs_heights (lists of floats) and origin_lat, origin_lon (floats for the local origin).

required

Returns:

Type Description
ndarray

list[list[float]]: Transmitter positions in Cartesian coordinates


Geographic Utilities

geo_utils handles all coordinate system conversions between GPS (lat/lon), UTM metres, and the local Cartesian system used inside the pipeline.

Coordinate systems

System Unit Used for
GPS (WGS 84) degrees Overpass API queries, scenario naming
UTM metres (absolute) intermediate conversion via utm package
Local Cartesian metres (relative) scene XML, Sionna positions, DeepMIMO dataset

The local Cartesian origin is always the centre of the GPS bounding box.

Satellite imagery

If you have a Google Maps Static API key, fetch_satellite_view downloads a 640 × 640 satellite image of the scene area:

from deepmimo.pipelines.utils.geo_utils import fetch_satellite_view

img_path = fetch_satellite_view(
    minlat=48.1355, minlon=11.5735,
    maxlat=48.1395, maxlon=11.5795,
    api_key="YOUR_GOOGLE_MAPS_API_KEY",
    save_dir="./satellite/",
)

API reference

Convert latitude and longitude to UTM coordinates.

Transforms GPS coordinates to Universal Transverse Mercator (UTM) coordinates, which provide a flat representation of the Earth's surface in meters.

Parameters:

Name Type Description Default
lat float | ndarray

Latitude in degrees

required
long float | ndarray

Longitude in degrees

required

Returns:

Type Description
tuple[float | ndarray, float | ndarray]

tuple[float | np.ndarray, float | np.ndarray]: Tuple containing: - x (easting): Distance in meters east from zone origin - y (northing): Distance in meters north from equator

Note

UTM zones and hemisphere information are discarded. For high-precision applications where zone transitions matter, additional handling may be needed.

Convert a GPS bounding box to a Cartesian bounding box.

Transforms a geographic bounding box defined by min/max latitude and longitude into a local Cartesian coordinate system centered at the specified origin.

Parameters:

Name Type Description Default
minlat float

Minimum latitude in degrees

required
minlon float

Minimum longitude in degrees

required
maxlat float

Maximum latitude in degrees

required
maxlon float

Maximum longitude in degrees

required
origin_lat float

Origin latitude in degrees

required
origin_lon float

Origin longitude in degrees

required
pad float

Padding to add to the bounding box in meters

0

Returns:

Type Description
tuple[float, float, float, float]

tuple[float, float, float, float]: Tuple containing: - xmin: Minimum x coordinate in meters from origin - ymin: Minimum y coordinate in meters from origin - xmax: Maximum x coordinate in meters from origin - ymax: Maximum y coordinate in meters from origin

Note

The resulting coordinates are in meters relative to the origin point, making them suitable for local area calculations and visualizations.

Convert GPS coordinates to relative Cartesian coordinates.

Transforms GPS coordinates into a local Cartesian coordinate system centered at the specified origin point. Useful for local area calculations where a flat Earth approximation is acceptable.

Parameters:

Name Type Description Default
lat float | ndarray

Latitude in degrees

required
lon float | ndarray

Longitude in degrees

required
origin_lat float

Origin latitude in degrees

required
origin_lon float

Origin longitude in degrees

required

Returns:

Type Description
tuple[float | ndarray, float | ndarray]

tuple[float | np.ndarray, float | np.ndarray]: Tuple containing: - x: Distance in meters east from origin - y: Distance in meters north from origin

Note

For areas spanning more than a few kilometers, consider using a proper projection system to account for Earth's curvature.

Calculate distance between two points in meters using Haversine formula.

The Haversine formula determines the great-circle distance between two points on a sphere given their latitudes and longitudes. This implementation assumes a spherical Earth with radius EARTH_RADIUS.

Parameters:

Name Type Description Default
lat1 float

First point latitude in degrees

required
lon1 float

First point longitude in degrees

required
lat2 float

Second point latitude in degrees

required
lon2 float

Second point longitude in degrees

required

Returns:

Name Type Description
float float

Distance between points in meters

Example

dist = haversine_distance(40.7128, -74.0060, 34.0522, -118.2437) print(f"Distance between NY and LA: {dist/1000:.1f} km")

Fetch a satellite view image of a bounding box using Google Maps Static API.

Downloads and saves a satellite image for the specified geographic area. The image is centered on the bounding box with a fixed zoom level.

Parameters:

Name Type Description Default
minlat float

Minimum latitude in degrees

required
minlon float

Minimum longitude in degrees

required
maxlat float

Maximum latitude in degrees

required
maxlon float

Maximum longitude in degrees

required
api_key str

Google Maps API key for authentication

required
save_dir str

Directory to save the satellite view image

required

Returns:

Type Description
str | None

Optional[str]: Path to the saved image file, or None if the request fails

Note
  • Image size is fixed at 640x640 pixels (maximum for free tier)
  • Zoom level is fixed at 18 (detailed view)
  • Requires a valid Google Maps API key with Static Maps API enabled
  • API calls may incur charges depending on your Google Maps API plan

Pipeline Utilities

pipeline_utils provides helpers for reading pipeline outputs and placing base stations.

Typical usage

from deepmimo.pipelines.utils.pipeline_utils import get_origin_coords

# After generate_scene(), recover the coordinate origin
origin_lat, origin_lon = get_origin_coords(osm_scene_folder)

API reference

Read the origin coordinates from the OSM folder.

Parameters:

Name Type Description Default
osm_folder str

Path to the OSM folder

required

Returns:

Type Description
tuple[float, float]

tuple[float, float]: Origin coordinates (latitude, longitude)


OSM Building Utilities

osm_utils provides helpers for querying and validating building data — useful when you need to place a base station at a specific GPS location and ensure it does not overlap with any building.

Typical usage

from deepmimo.pipelines.utils.osm_utils import get_buildings, find_nearest_clear_location

# Find a clear outdoor BS location near a given GPS point
buildings = get_buildings(lat=48.137, lon=11.576)
clear_lat, clear_lon = find_nearest_clear_location(
    original_lat=48.137, original_lon=11.576, buildings=buildings
)

API reference

Get all significant buildings in the area as Building instances.

Parameters:

Name Type Description Default
lat float

Latitude of the center point

required
lon float

Longitude of the center point

required
radius float

Search radius in meters, defaults to SEARCH_RADIUS

SEARCH_RADIUS

Returns:

Type Description
list[Building]

list[Building]: List of Building instances

Find nearest location that maintains minimum distance from all buildings.

Uses multiple strategies to find a suitable location: 1. Checks if original point is already clear of buildings 2. Moves away from nearest building edge 3. Uses spiral search pattern 4. Uses random walk with increasing distance 5. Falls back to moving north if all else fails

Parameters:

Name Type Description Default
original_lat float

Original latitude

required
original_lon float

Original longitude

required
buildings list[Building]

List of Building instances

required

Returns:

Type Description
tuple[float, float]

tuple[float, float]: Tuple of (latitude, longitude) for location clear of buildings

Check if point maintains minimum distance from all building footprints.

Parameters:

Name Type Description Default
point Point

Point to check

required
buildings list[Building]

List of Building instances

required

Returns:

Name Type Description
bool bool

True if point maintains minimum distance from all buildings