Model reference

Algorithms and RF Physics

The deterministic propagation, geometry, optimization, and radio-quality methods behind A.T.O.M results.

A.T.O.M combines deterministic planning equations with computational geometry to produce inspectable RF estimates. It is not a calibrated propagation solver or a substitute for field measurements.

Concept 4D: Urban Short-Range Propagation

The production planning default for 2.6 GHz and 28 GHz is urban_short_range, a deterministic 3GPP TR 38.901 UMa outdoor-to-outdoor median path-loss baseline. It uses known Tx/Rx heights and one shared footprint-height-los-v1 centerline classifier across rays, surfaces, interference, and network scoring. Known building heights can clear a footprint when the roof stays below the Tx-to-Rx line; unknown-height intersections are conservative NLOS. Missing footprint data, unknown LOS/NLOS, unsupported endpoint cases, or out-of-envelope distances produce an explicit applicability result and use legacy_fspl_walls as the reported fallback.

The urban formula uses metres, GHz, base-10 logarithms, and the 3GPP breakpoint:

d3D = sqrt(d2D^2 + (hBS - hUT)^2)
dBP' = 4 (hBS - 1) (hUT - 1) fc_Hz / 3e8
PL_LOS = PL1 or PL2 at dBP'
PL_NLOS = max(PL_LOS, 13.54 + 39.08 log10(d3D) + 20 log10(fc_GHz) - 0.6(hUT - 1.5))

The urban path-loss result is not combined with FSPL or the legacy wall heuristic. The research_sub_thz mode is the explicit 140 GHz safety profile, while the separate Concept 4D design note records scope, limitations, fallback policy, and references.

Concept 4F.1: Height-Aware Centerline Obstruction

The height-aware branch keeps the equations above unchanged and changes only the urban LOS/NLOS input. For each footprint interval [t_entry, t_exit], it compares the roof evidence with h_los(t) = h_tx + (h_rx - h_tx)t on flat ground. Exact roof contact is deterministic obstruction; no Fresnel or diffraction margin is applied. Explicit height tags are observed_tag, building:levels uses 3 m per level and is derived_from_levels, and the existing generic 9 m fallback is unavailable evidence and therefore conservative NLOS. See the Concept 4F.1 design note for the result metadata, multipart identity contract, terrain status, and Ankara audit.

Concept 4E: Building Entry

The separate Concept 4E design note evaluates a representative building facade in one batched analysis. It first evaluates the Concept 4D outdoor baseline to the facade, then subtracts the deterministic median O2I external-wall term from 3GPP TR 38.901 V19.4.0, §7.4.3.1. Indoor depth is fixed at zero, so no interior loss, room/floor geometry, or whole-building claim is produced. Outdoor NLOS does not receive a second legacy wall loss. At 28 GHz the standard low/high terms are evaluated from the glass/concrete compositions; at 2.6 GHz the single-frequency 20 dB compatibility value is used for both API scenarios. Material tags are evidence only, and the deterministic median omits random shadow-fading draws.

Concept 4G.2: Receiver Noise and Sensitivity

Concept 4G.2 adds a deterministic receiver usability contract while preserving the manual -115 dBm default. Manual mode uses the configured per-cell threshold. Opt-in derived mode uses the rounded 290 K reference -174 dBm/Hz and evaluates:

Nfloor = -174 + 10 log10(B_noise_Hz) + NF_dB
Sensitivity = Nfloor + RequiredSNR_dB + ReceiverMargin_dB
RxMargin = ReceivedPower_dBm - Sensitivity_dBm

Usability is strict (received_power_dbm > sensitivity_dbm). Noise-equivalent receiver bandwidth is independent of interference SCS/resource-element bandwidth. The same resolved threshold is surfaced in link diagnostics, static reach, building-entry indoor scenarios, surfaces, interference carrier admission, optimization, and reports, while building service (> -100 dBm), raw surface values, and interference RSRP/SINR/RSRQ serviceability retain their separate semantics. See the standalone note for equations, references, canonical evidence, and non-claims.

Concept 4H.1: Interference and Radio Quality

Concept 4H.1 formalizes the existing interference path as an inspectable planning contract. Propagation first returns total received carrier power. The path then applies a declared uniform full-carrier-to-reference-resource conversion, sums desired/interfering powers in mW on that same basis, and adds independent kTB thermal noise at the serving subcarrier spacing. RSRP, RSSI, RSRQ, and SINR are labeled planning approximations rather than UE measurements. Serving selection, exact co-channel matching, deterministic load, serving-only receiver-sensitivity admission, finite per-cell interference horizons, failure reasons, a per-cell power ledger, and a scenario fingerprint are returned with the result. Radio-quality diagnostics never feed the canonical propagation-only optimizer.

Concept 4H.2: Interference-Aware Optimization

Concept 4H.2 adds the optional radio_quality soft objective. It evaluates the existing 4H.1 planning policy (RSRP >= -110 dBm, SINR >= 0 dB, RSRQ >= -20 dB) over one fixed, candidate-independent row-major union grid. The serviceable fraction is a stable utility; no-carrier points remain denominator failures. A positive priority adds the utility to composite ranking and Pareto dominance, while a zero priority leaves the propagation-only candidate, score, recommendation, and Pareto dimensions unchanged. Stored raw candidate metrics support local priority reranking and the same fixed-domain counterfactual used by per-cell explanations.

The optimizer prepares geometry once and keeps the candidate hot loop compact: azimuth-dependent antenna/link evaluation, automatic strongest eligible serving selection, exact co-channel linear power summation, thermal noise, and aggregate serviceability/outage/percentile metrics. It does not call the public interference endpoint per candidate. The reported result is conditional on the finite per-cell effective-radius compatibility horizon and is not a network-wide interference, throughput, MCS, scheduler, indoor, adjacent channel, or 140 GHz model. The 140 GHz research profile returns unsupported_radio_quality_model and renormalizes available objectives.

Radio Frequency Physics Foundation

Free-Space Path Loss (FSPL)

The fundamental free-space term uses the current ITU-R P.525-5 (2024-11) equation as a mathematical reference:

L=20log10(d[m])+20log10(f[GHz])+32.45L = 20 \log_{10}(d[m]) + 20 \log_{10}(f[GHz]) + 32.45

Simplification (practical form):

L[dB]=20log10(d[m])+20log10(f[GHz])+32.45L[dB] = 20 \log_{10}(d[m]) + 20 \log_{10}(f[GHz]) + 32.45

Legacy Received Power Calculation

The selectable compatibility mode is legacy_fspl_walls (historically reported as fspl-walls-2p5d-v3). Its link budget is:

Prx[dBm]=Ptx+GtxLsystem+CLFSPLLbuildingAhorizontalAverticalP_{rx}[dBm] = P_{tx} + G_{tx} - L_{system} + C - L_{FSPL} - L_{building} - A_{horizontal} - A_{vertical}

Where:

  • PtxP_{tx} and GtxG_{tx} are the absolute transmit-power and antenna-gain terms
  • LsystemL_{system} is the configured system loss and CC is the signed global calibration offset
  • LFSPLL_{FSPL} uses the slant distance between the transmitter and receiver, with meter/GHz units
  • LbuildingL_{building} is cumulative frequency-dependent, material-agnostic building-boundary loss
  • AhorizontalA_{horizontal} and AverticalA_{vertical} are relative analytic antenna-pattern attenuations

This compatibility mode uses horizontal building-footprint geometry and height-aware FSPL; it does not use the urban roof classifier, terrain, diffraction, reflection, fast fading, or multipath. A positive CC raises predicted received power by the same global dB offset. The separate path-profile workflow is an advanced point-to-point diagnostic with its own path-profile-diagnostic-v1 contract; it does not alter network RF.

2.5D Point-To-Point Profiles

For a selected transmitter and receiver, the engine samples a geodesic path at a bounded spacing. Each sample contains ground elevation plus any intersecting building height. Antenna and receiver elevations are their local ground elevations plus configured height above ground.

The result reports direct geometric line-of-sight clearance and a 60% first-Fresnel-zone clearance check. Fresnel concern is a separate geometry diagnostic and does not change LOS/NLOS classification:

r1 = sqrt(lambda * d1 * d2 / (d1 + d2))

The isolated Concept 4F.2 workflow represents each known flat-roof footprint by deterministic entry and exit roof-edge candidates. It exposes the signed P.526-16 equation (26) parameter and applies equation (31) for v > -0.78; the candidate with maximum applicable v is selected. Generic fallback heights are unavailable evidence. The diagnostic compares FSPL plus explicit single-edge loss against canonical UMa; it never adds diffraction to UMa NLOS. Deygout/multiple-edge, reflection, and terrain-clutter coupling are not implemented.

The inspectable loss budget keeps FSPL, horizontal/vertical antenna attenuation, system loss, wall penetration, diffraction, clutter, vegetation, gas, rain, and calibration as separate signed components. Shadow sigma produces sensitivity bounds and is not injected as a random field, preserving determinism.

The terrain-profile and urban-short-range labels use the current recorded scopes of ITU-R P.1812-8 (2025-09) and ITU-R P.1411-13 (2025-09), while retaining A.T.O.M's existing runtime conditions and limits. The knife-edge, material, gas, and rain controls are informed by P.526-16, P.2040-4, P.676, and P.838; A.T.O.M does not claim full Recommendation conformance.

Frequency Dependence

FSPL increases with frequency squared:

Lf2L \propto f^2

Consequence: Same distance results in substantially higher loss as frequency rises, which is why mmWave and Sub-THz coverage shrink quickly in urban settings.


Building Penetration Model

Legacy Generation-Specific Wall Loss

The selectable legacy_fspl_walls mode applies a fixed loss each time a ray crosses a building boundary. OSM building tags are still used for demand scoring and diagnostics, but wall penetration is intentionally frequency-driven in that compatibility mode:

if frequency_ghz < 10:
    loss_4g = 8 dB
elif frequency_ghz < 100:
    loss_5g = 30 dB
else:
    loss_6g = 80 dB

Cumulative Wall Loss

If a ray intersects multiple buildings, losses are cumulative:

Ltotal_walls=i=1nLi(f)L_{total\_walls} = \sum_{i=1}^{n} L_i(f)

Example: Ray through two building boundaries at 5G frequency:

  • Building 1: +30 dB
  • Building 2: +30 dB
  • Total: +60 dB additional loss

Raytracing Algorithm

Overview

A.T.O.M uses a deterministic segmented sector raytracer:

  1. Define the antenna azimuth and beam width
  2. Split the selected sector into configurable rays
  3. Split each ray into short segments
  4. Query the R-Tree for buildings intersecting each segment
  5. Evaluate the selected shared propagation model at each physical endpoint; only the explicit legacy mode applies cumulative wall dB
  6. Apply the effective per-cell receiver sensitivity threshold
  7. Color each segment by received power
  8. Serialize the segments as GeoJSON

Pseudocode

func TraceSector(tx Location, req SimulationRequest) GeoJSON {
    result := GeoJSON{}
    if req.rays * ceil(req.radius_m / 25) > 25_000 {
        return error("simulation response feature limit exceeded")
    }
    maxDistance := req.radius_m
    receiverSensitivity := effectiveReceiverSensitivity(req)

    for angle in sector_angles(req.azimuth, req.beam_width, req.rays) {
        current := tx
        wallLoss := 0.0

        for segmentEnd in stepped_points(tx, angle, maxDistance) {
            segment := LineSegment{current, segmentEnd}
            intersections := rtree.Query(segment.Bounds())

            for building in intersections {
                if segment_intersects_polygon(segment, building.Polygon) {
                    wallLoss += penetration_loss(req.frequency_ghz)
                }
            }

            distance := haversine_distance(tx, segmentEnd)
            fspl := 20*log10(distance) + 20*log10(req.frequency_ghz) + 32.45
            txGain := effectiveTxAntennaGain(req)
            patternLoss := sharedAntennaPatternLoss(req, segmentEnd)
            propagationLoss := fspl + wallLoss
            rxPower := req.tx_power_dbm + txGain - patternLoss + req.rx_antenna_gain_dbi - req.system_loss_db - req.polarization_loss_db + req.calibration_offset_db - propagationLoss

            if rxPower <= receiverSensitivity {
                break
            }

            result.Add(LineString{current, segmentEnd}, rxPower)
            current = segmentEnd
        }
    }

    return result
}

Computational Geometry: Polygon Intersection

Problem: Does a ray (line segment) intersect a building (polygon)?

Solution: Query the R-Tree's segment bounding box, then test each candidate polygon with exact segment-edge intersections and point-in-polygon checks. Duplicate boundary points for the same building are collapsed within the current 5 cm tolerance, and intersections are processed in distance order.

func SegmentIntersectsPolygon(segment Line, polygon Polygon) bool {
    // Test the segment against all polygon edges
    for i := 0; i < len(polygon.Edges); i++ {
        edge := polygon.Edges[i]
        if SegmentIntersectsSegment(segment, edge) {
            return true
        }
    }
    
    // Test if segment start/end is inside the polygon
    return PointInPolygon(segment.Start, polygon) ||
           PointInPolygon(segment.End, polygon)
}

func SegmentIntersectsSegment(s1, s2 Line) bool {
    // Standard 2D line intersection test
    // (Cross product method)
    d1 := cross_product(s2.Start - s1.Start, s1.Dir)
    d2 := cross_product(s2.End - s1.Start, s1.Dir)
    d3 := cross_product(s1.Start - s2.Start, s2.Dir)
    d4 := cross_product(s1.End - s2.Start, s2.Dir)
    
    return ((d1 > 0 && d2 < 0) || (d1 < 0 && d2 > 0)) &&
           ((d3 > 0 && d4 < 0) || (d3 < 0 && d4 > 0))
}

Complexity: O(log n) per ray thanks to R-Tree spatial indexing.


Spatial Indexing: R-Tree

Why R-Tree?

RF simulations require millions of queries:

  • Naive approach (linear scan): O(n) per query × 90,000 rays = 1+ billion operations
  • R-Tree approach (spatial index): O(log n) per query × 90,000 rays = 1+ million operations
  • Speedup: 1000× faster

R-Tree Structure

An R-Tree organizes rectangles (bounding boxes) in a balanced tree:

Root
├─ Node A (covers buildings 1-5)
│  ├─ Building 1 bbox
│  ├─ Building 2 bbox
│  └─ Building 3 bbox
├─ Node B (covers buildings 6-10)
│  ├─ Building 6 bbox
│  └─ Building 7 bbox
└─ Node C (covers buildings 11-15)
   └─ Building 11 bbox

Query Algorithm

func RTtree.Query(ray LineSegment) []Building {
    candidates := []Building{}
    
    // Recursively check which nodes overlap with ray
    func traverse(node *RNode) {
        if node.bbox.Intersects(ray) {
            if node.IsLeaf() {
                candidates.append(node.buildings)
            } else {
                for child in node.Children {
                    traverse(child)
                }
            }
        }
    }
    
    traverse(rtree.Root)
    return candidates
}

Result: Typically 5-20 building candidates per ray (vs 12,000 total buildings).


Sector Eligibility

Hard Sector Model

A.T.O.M uses the configured azimuth and beam width as a hard geometric eligibility boundary:

Azimuth = 45°, Beam Width = 65°
Coverage: 12.5° to 77.5°

              ↑ 0°
              |
        /─────────────\
       /               \
      |    Main Lobe     |
      | (relative loss=0dB)|
       \               /
        \─────────────/
             θ = 65°

Eligibility Function

func IsInsideSector(direction float64, antennaAzimuth float64,
                    beamWidth float64) bool {
    offset := abs(normalize_angle(direction - antennaAzimuth))
    return offset <= beamWidth / 2
}

Samples outside the configured sector or radius do not contribute. Configured antenna gain is applied separately in the link budget; the diagram's zero value means zero relative preset attenuation at boresight. Version 1 does not model sidelobes or a continuous vendor antenna diagram.


Deterministic Optimization: Sweep & Score Algorithm

Problem Statement

Find: The antenna azimuth that best serves demand-weighted coverage

Constraints:

  • Distance range: 25 m to 5 km
  • Beam width: user configured
  • Frequency: user selected

Algorithm

func OptimizeAzimuth(tx Location, request SimulationRequest) float64 {
    bestAzimuth := 0.0
    bestScore := 0.0
    
    // Sweep all azimuths in 10° increments
    for azimuth := 0; azimuth < 360; azimuth += 10 {
        // Run simulation at this azimuth
        rays := TraceSector(tx, request.withAzimuth(azimuth))
        
        // Track unique buildings reached by the sector
        demandScore := 0.0
        residentialScore := 0.0
        hitBuildings := NewSet()
        for ray in rays {
            for building in ray.hitBuildings {
                if hitBuildings.add(building.id) {
                    demandScore += building.demandWeight * 10000
                    residentialScore += building.residentialDemand * 10000
                }
            }
        }
        
        // Coverage is capped and used as a tie-breaker
        coverageTieBreaker := 0.0
        for ray in rays {
            coverageTieBreaker += min(ray.distance, 500) / 500 * 100
        }
        score := demandScore + residentialScore + coverageTieBreaker
        
        // Track best
        if score > bestScore {
            bestScore = score
            bestAzimuth = azimuth
        }
    }
    
    return bestAzimuth
}

Complexity Analysis

  • Loop iterations: 360° / 10° = 36
  • Per iteration:
    • Ray tracing: O(90,000 rays × log n intersections) ~1 second
    • Coverage calculation: O(90,000)
  • Total time: ~36 seconds (naive)
  • Optimized time: ~250 ms (with parallelization)

Parallelization

Go's Goroutines enable embarrassingly parallel optimization:

// Create worker pool
type Job struct {
    azimuth float64
}

type Result struct {
    azimuth float64
    coverage float64
}

// Dispatch all azimuths to workers
jobs := make(chan Job, 36)
results := make(chan Result, 36)

// 4 workers process in parallel
for w := 1; w <= 4; w++ {
    go worker(jobs, results)
}

for azimuth := 0; azimuth < 360; azimuth += 10 {
    jobs <- Job{azimuth}
}

// Collect results
for i := 1; i <= 36; i++ {
    result := <-results
    if result.coverage > bestCoverage {
        bestCoverage = result.coverage
        bestAzimuth = result.azimuth
    }
}

Result: 4× speedup on quad-core machine.

Network Objective Model

Network azimuth optimization keeps the existing RF evaluation and hard feasibility checks separate from preference scoring. Each feasible evaluated configuration stores raw measurements and stable utilities. Demand and residential measurements use the same indexed BuildingFootprint unit for both numerator and denominator; multipart source geometries remain separate suffixed footprints because the RF engine has no stable logical-building ID to merge safely:

  • Demand: served relevant demand weight / relevant demand weight inside the fixed selected-cell radius-union domain. Demand relevance uses the existing building-centroid convention.
  • Residential: covered relevant residential footprints / residential footprints intersecting the fixed selected-cell radius-union domain.
  • Propagation reach: the existing capped aggregate usable-ray-reach score / towers × rays × 100, the stable maximum of that metric. The legacy objective ID remains coverage for compatibility; it does not mean spatial-area coverage.
  • Overlap: 1 - (overlapping covered buildings / covered buildings).

Utilities are clamped to [0, 1]; they are not normalized against the current candidate set. The optimization domain is prepared once per request from the logical union of each selected cell's configured service-radius envelope and is independent of candidate azimuths. User priorities are 0–100 values; unavailable objectives are marked N/A and excluded from the effective-priority denominator without mutating their configured values. The composite score is the weighted utility sum over available objectives, exposed as score = composite_score × 100. Hard constraint violations exclude candidates from the feasible Pareto frontier; they are not converted into score penalties. The same stored frontier can therefore be re-ranked when priorities change without repeating RF evaluation.


Performance Characteristics

Benchmarks (Ankara Dataset)

Operation Time Scaling
Load GeoJSON 500 ms O(n) where n=12,000 buildings
Build R-Tree 1 second O(n log n)
Single ray trace < 1 μs O(log n)
Up to 25,000 returned ray features Bounded O(n log n) parallelized
Network optimization See BenchmarkCanonicalAnkaraNetworkOptimization in the repository Fixed-domain entity discovery is prepared once; candidate RF scoring remains the dominant work
API response < 100 ms p99 Network + serialization

Memory Usage

Component Size
Buildings (GeoJSON) 80 MB (disk) → 40 MB (RAM)
R-Tree indices 150 MB
Tower locations 2 MB
Returned ray features per request 25,000 maximum
Total footprint ~200 MB typical

Validation & Limitations

Response Complexity Bound

Before ray allocation, the API requires rays × ceil(radius_m / 25) ≤ 25,000. The same atomic budget is shared by all ray workers and counts additional features created when building intersections split a 25-meter base segment. If the actual count reaches the ceiling, workers cancel the request before response assembly and serialization. Response assembly independently checks the ceiling, sizes its flattened slice from the actual count, and releases the per-ray slices when the top-level operation finishes.

Model Confidence

Aspect Status Notes
FSPL equation Deterministic Standard free-space equation
Wall attenuation Approximation Fixed by selected frequency family
Wall intersection Deterministic Binary geometric intersection against loaded footprints
Field calibration Not completed Validate estimates before deployment decisions

Model Limitations

  1. Flat Earth: No terrain elevation (can add with GeoTIFF)
  2. No multipath: Doesn't model reflections/scattering
  3. Ideal antennas: Assumes perfect omnidirectional at low freq
  4. Static buildings: Doesn't model moving obstructions
  5. Weather: No rain/weather fading

When to Use A.T.O.M

Good for:

  • Network planning and site selection
  • Quick feasibility studies
  • Education and training
  • Comparison between sites
  • Coverage mapping

Not suitable for:

  • Detailed link budget analysis
  • Precise handover prediction
  • Interference modeling
  • Non-stationary targets

Next: Explore the API Reference to integrate A.T.O.M into your systems.