System architecture

From a map action to an inspectable RF result

A.T.O.M is a local-first React and Go application. The browser owns planning state and map presentation; the Go service owns validation, bounded computation, spatial queries, and deterministic RF analysis. An optional sidecar adds 5G communication-path state without changing the radio model.

Primary runtimeSingle container
BackendGo 1.26.5 + Gin
FrontendReact + Leaflet
Project persistenceBrowser IndexedDB
Default RF capacity2 concurrent jobs

The shortest useful mental model

A planning action becomes a validated JSON request. The backend narrows the active validated dataset pack through an in-memory spatial index, executes the selected deterministic engine, and returns GeoJSON plus statistics. The browser then renders only the layers and result view relevant to that operation.

01Configure cellsMode, technology, power, geometry, and selected towers.
02Submit analysisAbortable REST request with a settings fingerprint.
03Query spatial dataR-tree bounds reduce building intersection and demand work.
04Execute RF modelBounded workers calculate propagation, scoring, gaps, or interference.
05Render evidenceLeaflet layers, focused KPIs, Inspector details, and reports.

Shared runtime policy

Core Lab scenarios, technology frequency bands, RF defaults, bandwidth choices, and validation limits originate in policy/rf-policy.json. A checked generator produces self-contained Go and JavaScript bindings for the API, adapter, and browser; CI rejects stale output. Measurement, interference, optimization, and recommendation requests also use one shared Go tower input type.

System context

The production image contains the built frontend, Go API, and default Ankara dataset pack. Basemap tiles remain an external dependency unless replaced or cached. Core Lab is opt-in and communicates through a separate adapter.

System boundarySolid nodes are part of the default A.T.O.M runtime
RF planner or reviewer Configures cells, runs analyses, inspects map objects, exports reports.
API consumer Submits the same JSON contracts directly to /api/*.
A.T.O.M web workspace Focused command bar, workflow rail, tool drawer, Inspector, Leaflet map, and report assembly.
A.T.O.M Go service Static frontend host, REST API, validation, resource controls, spatial index, and RF engines.
Validated dataset pack Manifest, provenance, hashes, tower points, building footprints, and demand metadata loaded from local files.
OpenStreetMap tile service Provides the visual basemap; RF computation does not depend on live map APIs.
Core Lab adapter Optional deterministic overlay or bridge to configured Open5GS status and metrics endpoints.
GitHub / Git LFS Distributes source and the large building dataset used by local builds.
Local-first does not mean the default basemap is offline

The RF engines and datasets run locally. Leaflet currently requests OpenStreetMap tiles over the network unless a local tile source is configured separately.

Runtime components

Frontend responsibilities stop at orchestration and presentation. Domain validation and RF calculations stay behind the Go API, while the data layer exposes bounded spatial candidates to each engine.

Container viewDefault app plus optional Core Lab boundary

React workspace

Command bar and workflow railActive plan context, RF run command, focused tool navigation, and availability states.
Tool drawer and InspectorSetup, propagation, interference, 5G Core, results, data, reports, and selected map-object details.
Request coordinatorAbortController channels, monotonic request IDs, latest-response checks, and settings invalidation.
Project workspaceVersioned IndexedDB projects, scenario snapshots, stale-result detection, import/export, and five-scenario result cache.
Leaflet map layersCanvas-backed towers, rays, gaps, interference samples, measurement residuals, candidate sites, Xn/N2/N3 routes, and selection geometry.
Report assemblerBuilds Markdown and printable HTML from current client state without a report API.

Go + Gin service

HTTP boundaryCORS, 1 MiB body limit, readiness/liveness, JSON binding, pointer-aware defaults, and validation.
RF capacity limiterTwo concurrent RF requests by default; saturated requests return 429 with Retry-After.
Propagation engineSector ray sampling, FSPL, antenna gain, polygon intersections, wall loss, and segment GeoJSON.
Planning enginesCoverage gaps, azimuth sweep, network evaluation, network optimization, candidate recommendation, and overlap scoring.
Interference engineAdaptive grid, serving-cell choice, linear power sums, RSRP, SINR, RSRQ, RSSI, and demand impact.
Measurement evaluatorPredicts 4G/5G RSRP at uploaded points, reports residual error, and offers holdout-tested global bias correction.
Core Lab proxy5G-only status, topology, sessions, events, and scenario requests with a 1.5 second adapter timeout.

Data and integrations

Building R-tree161k+ footprint bounds and exact polygon geometry held in memory for fast candidate queries.
Demand surfacePOI tags, residential weighting, density signals, confidence summary, and building centroids.
Tower storeLocal candidate records loaded from the active pack and exposed to planning and recommendation workflows.
Dataset manifestVersion, bounds, CRS, sources, licenses, filenames, and SHA-256 hashes validated before readiness succeeds.
Static frontend bundleVite build served by the same Go process in the production image.
Optional adapterCore functions, deterministic scenarios, Xn eligibility, N2 fallback, N3 state, and Open5GS probing.

Data preparation and spatial querying

The Python pipeline is not part of normal request handling. It prepares files ahead of time; the Go service loads those files once at startup and serves all analyses from memory.

01SourceOSM building geometry and OpenCellID-derived tower records.
02EnrichNormalize footprints and add POI, residential, and density demand signals.
03PackageWrite GeoJSON/CSV artifacts and a versioned manifest with provenance, bounds, CRS, and file hashes.
04IndexParse polygons, compute bounds, and populate an in-memory R-tree at startup.
05QuerySearch beam or cell bounds, then perform exact radius, sector, and intersection tests.
Runtime artifactPurposeLifecycleImportant consequence
ankara_buildings.geojsonFootprints and demand propertiesLoaded once into memoryFast requests, higher startup memory
ankara_5g_nodes.geojsonTower coordinates and cell identifiersLoaded once; also served to frontendNo live tower API dependency
manifest.jsonPack identity, provenance, schema, bounds, and hashesValidated before runtime readinessInvalid or incompatible packs fail /readyz
Building R-treeBounding-box candidate searchBuilt during startupAvoids scanning every polygon per ray
Demand summaryDataset confidence and countsComputed from loaded footprintsVisible in Data and reports
Analysis GeoJSONRays, gaps, and radio-quality samplesGenerated per requestNot stored server-side
Project scenariosExact inputs, model metadata, summaries, and recent layersStored in browser IndexedDBPortable without adding a server database

Principal request lifecycles

The browser deliberately serializes expensive per-cell rendering where needed. This keeps a network workflow inside the backend capacity budget while preserving a single cancellation boundary for the whole operation.

Run Sector

Single selected cell
BrowserBuild one normalized sector payload and start the current RF request channel.
Parallel API calls/api/simulate and /api/coverage-gaps execute together.
Go enginesTrace segmented rays and independently evaluate demand buildings below the service threshold.
CommitOnly the current request updates ray/gap layers, RF KPIs, Inspector data, and report state.

Evaluate or Optimize Network

Two to six selected cells
Score planEvaluation keeps supplied azimuths; optimization sweeps candidate directions and applies overlap penalties.
Return summaryBackend returns network score, demand coverage, overlap, and per-cell azimuth records.
Render sequentiallyThe frontend queues one /api/simulate call per selected cell to avoid RF-capacity collisions.
CombineRay collections merge client-side; Results selects the network evaluation or comparison view.

Analyze Interference

4G or 5G; two to six cells
Bound surfaceForm the union of selected-cell coverage bounds and adapt spacing to keep surface samples bounded.
Evaluate cellsApply sector/radius eligibility, FSPL, gain, wall loss, load, reuse channel, and receiver noise.
Select and sumStrongest RSRP serves; co-channel interference and noise are added in linear power.
PresentReturn SINR/RSRP/RSRQ/RSSI samples, demand impacts, percentiles, assumptions, and per-cell summaries.

Recommend Candidate Sites

4G or 5G network plan with a drawn area
Bound candidatesExclude selected cells, keep records inside the user polygon, and prefilter at most 50 by proximity to unmet demand.
Sweep deterministicallyEvaluate a bounded candidate set while keeping current-cell azimuths fixed and optimizing only the new candidate.
Explain rankingReturn the five strongest options with marginal coverage, demand, overlap, azimuth, score components, and explicit reasons.
Apply safelyApplying a recommendation creates a new stale scenario that requires analysis; the baseline snapshot remains unchanged.

Validate Measurements

CSV evidence for 4G or 5G
Parse locallyThe browser validates up to 5,000 ID, coordinate, technology, RSRP, and optional cell-ID rows.
PredictThe backend evaluates modeled RSRP at each point and returns residual GeoJSON, MAE, RMSE, median bias, and per-cell statistics.
Hold out evidenceWith at least 20 valid points, a deterministic split compares uncorrected and corrected error on data excluded from fitting.
Apply explicitlyAn accepted global path-loss bias becomes a project calibration profile and invalidates incompatible or older results.

Inspect and report

Client-side detail flow
Select objectA tower, gap, path, interference point, candidate, or measurement residual becomes the current map object.
Inspector takeoverThe drawer remembers its prior tool and shows complete persistent details while popups stay lightweight.
Restore contextBack returns to the previous tool; close returns keyboard focus to the map or originating control.
ExportCurrent evidence becomes Markdown or printable HTML; complete projects move between browsers as versioned .atom-project.json files.

5G communication-path overlay

Core Lab is intentionally independent from radio interference. It describes control and user-plane paths for selected 5G cells; Core scenarios do not alter RF propagation, and radio load does not alter Core function health.

Selected-cell communication pathsAvailable only in the 28 GHz 5G mode

NG-RAN

Selected tower to gNB mappingStable selected-cell ordering supplies IDs and coordinates to topology queries.
Xn-CDirect neighboring gNB control-plane coordination when distance and scenario eligibility pass.
Xn-UDirect user-plane forwarding associated with handover between eligible neighbors.

Fallback and session paths

N2 via AMFCoordination fallback when Xn is degraded or unavailable.
N3 via UPFUser-plane PDU-session traffic; UPF degradation affects this path without changing Xn-C.
Route decisionEach neighbor pair reports direct_xn, ng_fallback, or unreachable with a reason.

Core functions and scenarios

AMF / SMF / UPFAccess control, session management, and user-plane anchoring.
Service functionsNRF, UDM/UDR, AUSF, PCF, and NSSF health and interfaces.
Deterministic scenariosRegistration storm, function outages, policy degradation, UPF degradation, and Xn degradation/outage.
Adapter behavior is explicit

Without configured Open5GS endpoints, the adapter reports a deterministic simulated_overlay. With endpoints, it probes external state briefly and retains the same frontend-facing JSON contracts.

Resource and reliability controls

RF jobs are intentionally bounded. The frontend avoids stale commits and unnecessary concurrency; the backend rejects oversized or excess work before it can monopolize the process.

ControlCurrent behaviorUser-visible result
Request body limit1 MiB for incoming requests413 for oversized bodies
RF job limiter2 concurrent jobs by default through MAX_CONCURRENT_RF_REQUESTS429 plus Retry-After when saturated
Per-job workersAt most 4 Go workers for expensive RF operationsPredictable CPU pressure per request
Client cancellationSuperseded settings abort the active RF request channelOld work stops when possible
Latest-response checkRequest ID and settings fingerprint must still matchOld responses cannot replace newer results
Network render queuePer-cell ray requests run sequentiallyNetwork evaluation avoids self-generated overload
HTTP timeouts5s headers, 15s read, 120s write, 60s idleLong RF writes are allowed without unbounded connections
Liveness/healthz reports the process and loaded countsProcess monitoring remains independent of readiness
Readiness/readyz requires buildings, towers, and frontend bundle503 until the instance can serve the application

Deployment topology

The same interfaces are used in development and production; only asset serving and the optional Core adapter boundary change.

Local development

Vite serves the frontend on port 5173 and proxies API, health, and readiness requests to the Go service on port 8080.

  • Fast frontend refresh and source maps
  • Go service reads data from repository-relative paths
  • Core adapter can run separately on port 8090

Production container

A multi-stage Docker build compiles the React bundle and Go binary, then copies both plus the data into a non-root Alpine runtime.

  • One public port: 8080
  • Go serves both static frontend and API
  • Readiness healthcheck is built into the image

Optional Core Lab profile

The compose overlay enables the backend Core proxy and starts the adapter sidecar. The default app remains Core-free.

  • Stable proxy routes remain under /api/core/*
  • Adapter is internal to the compose network
  • Open5GS integration is optional

Internet-facing boundary

The API has no built-in authentication. Public deployments need a trusted reverse proxy or gateway for TLS, authentication, and external rate policy.

  • Keep /healthz and /readyz available to probes
  • Preserve the 120 second RF response window
  • Do not expose the adapter directly without need

Model and trust boundaries

Architecture quality includes stating what the system does not claim. These limits apply to the current implementation and reports.

Propagation limits

No diffraction, reflection-heavy multipath, fast fading, sidelobes, MIMO beamforming gain, scheduling, adjacent-channel leakage, or uplink model.

Data limits

Static OSM/OpenCellID-derived geometry and synthetic demand can be incomplete or stale. Confidence is context, not calibration.

Measurement limits

RSRP, SINR, RSRQ, RSSI, and coverage values remain deterministic planning estimates. Uploaded field data validates residuals; its optional global bias correction is not full propagation calibration.

Operational limits

No authentication, server-side project database, multi-user collaboration, or job queue is included. Project history is durable only in the current browser or an exported project file.