adaptive-sensing is a research and prototype system for adaptive electronic-warfare spectrum surveillance.
Its purpose is to control a receiver that cannot listen to the entire radio-frequency spectrum at once. The receiver has a fixed set of frequency channels and can observe only one channel during each short time window, called a dwell. The system must decide:
The project simulates this problem using synthetic radar/emitter data, evaluates multiple scheduling strategies, trains predictive models, and presents the results through a tactical web dashboard.
The central idea is:
Instead of repeatedly listening to the loudest channel, choose the next scan based on the expected long-term mission value of discovering previously unseen emitters while still maintaining safe coverage of the whole spectrum.
The repository calls this system Q-Scheduler.
The main data flow is:
Radar/emitter dataset
|
v
Dataset loading and PDW parsing
|
v
RF/time-frequency environment
|
v
Simulated receiver observations
|
v
Historical and causal feature extraction
|
v
Activity and mission-value prediction
|
v
Candidate scan actions
|
v
Scheduler/planner chooses next channel
|
v
Safety gate approves or vetoes the action
|
v
Receiver observes the selected channel
|
+----> Evaluation metrics and benchmark reports
|
+----> Frontend dashboard and comparison visualizations
The system has four broad layers:
| Layer | Location | Purpose |
|---|---|---|
| Research and simulation backend | backend/src/ | Receiver simulation, features, schedulers, evaluation |
| Advanced Q-Scheduler backend | backend/q_scheduler/ | Predictive models and mission-level planning |
| API layer | backend/api/server.py | Exposes comparisons and live streams to the dashboard |
| Operator dashboard | frontend/ew-dashboard/ | Visualizes spectrum activity, scan decisions, threats, and policy comparisons |
The repository also contains a large body of documentation and experimental artifacts under docs/ and reports/.
The project models a receiver with approximately 36 frequency channels:
A simple receiver would scan channel 0, then channel 1, then channel 2, and so on. This guarantees coverage, but it may miss a short-lived emitter that transmits while the receiver is listening elsewhere.
A naïve adaptive scheduler has the opposite problem: it may discover many pulses on one busy channel and keep returning there, starving the rest of the spectrum.
This project therefore tries to balance:
The main objective is cumulative undiscovered-emitter time, represented in the documentation as J. Lower J means emitters were discovered earlier.
This is the primary project explanation. It covers:
It is written partly for technical evaluators and partly for Smart India Hackathon judges.
This is the system’s formal architecture specification. It defines:
This file describes the intended architecture at a conceptual level, including some structures that have since evolved in the implementation.
Contains repository-level GitHub configuration, likely including workflows, issue or contribution settings, and automation metadata.
Contains detailed technical specifications and phase-by-phase validation reports. Important documents include:
DATASET_ARCHITECTURE.md — dataset structure and data assumptionsOBSERVABILITY_RULES.md — rules preventing the scheduler from using future or hidden informationPHASE1_VALIDATION.md — initial dataset validationPHASE2_RF_ENVIRONMENT.md — RF environment and receiver simulationPHASE3_BASELINES.md — baseline scheduler definitionsPHASE4_FEATURE_ENGINEERING.md — engineered state featuresPHASE5_2_ML_MODELS.md — predictive ML modelsPHASE6_REINFORCEMENT_LEARNING.md — RL-related workPHASE7.md and related files — later planning, predictive, and causal-state workCOUNTERFACTUAL_ENVIRONMENT_AUDIT.md — checks around counterfactual evaluationPOST_RESTRUCTURE_VALIDATION.md — validation after repository restructuringThese documents function as the project’s research notebook and audit trail.
Contains generated experiment outputs rather than core source code. There are many CSV, JSON, Markdown, PNG, and NumPy artifacts covering:
The reports directory is useful for verifying research claims and comparing policies, but it is not generally needed to understand the runtime architecture.
The repository-level scripts currently focus on later validation and experiment execution, including:
run_phase6_3_candidate_a_validation.pyrun_phase6_3_candidate_b_validation.pyrun_phase6_3_single_scenario.pyThese scripts execute specific research experiments and generate trace or validation artifacts.
The backend is Python-based. Its dependencies include NumPy, SciPy, h5py, Matplotlib, FastAPI, Uvicorn, and pytest.
This package is responsible for bringing raw scenario data into the system.
dataset_loader.pyDefines structures such as:
RawPDWTableScenarioDataDatasetLoaderIt loads and represents pulse data and scenario-level metadata.
scan_parser.pyDefines receiver and transmitter metadata:
ChannelConfigReceiverConfigTransmitterMetadataIt parses the hardware configuration of the receiver and the metadata describing simulated emitters.
preprocessing.pyProvides data validation and time-unit conversion helpers, including conversion between microseconds and seconds.
hardware_constants.pyContains receiver-specific timing and channel rules, such as canonical dwell durations and wideband-channel identification.
This package simulates the physical RF world and the receiver’s limited view of it.
rf_environment.pyRepresents the RF environment containing channels, emitters, pulses, and activity over time.
receiver.pyImplements the receiver simulator. It models what the receiver actually observes after selecting a channel and dwell duration.
actions.pyDefines the scan action taken by the receiver, such as selecting a channel and observing it for a specific dwell.
observations.pyDefines the observation returned after a dwell. This is the information available to the scheduler, rather than the full hidden ground truth.
time_frequency_grid.pyRepresents activity on a two-dimensional time/frequency grid.
phase7_environment.pyProvides a later-stage environment for the Phase 7 planning and learning experiments.
rl_environment.pyContains reinforcement-learning environment abstractions such as discrete, box, and dictionary spaces.
synthetic_world.pyCreates small synthetic scenarios for development and testing. It includes helpers for generating four-channel receivers and synthetic pulse streams.
reward.pyDefines reward configuration and reward breakdown calculations for learning-based schedulers.
potential.pyImplements potential-based state shaping, especially around channel staleness.
lagrangian.pyProvides constraint-pressure and dual-variable logic for constrained scheduling experiments.
This package converts receiver history into scheduler features.
extractor.pyThe main feature-extraction layer. It produces structured spectrum feature state from the receiver’s observation history.
types.pyDefines the feature data structures:
FeatureConfigActivityFeaturesStalenessFeaturesTemporalFeaturesSpectralFeaturesSpatialFeaturesCrossBandFeaturesBandFeaturesactivity.py — tracks recent activity by bandstaleness.py — tracks how long each channel has gone without observationtemporal.py — extracts temporal pulse behaviorspectral.py — extracts frequency and spectral behaviorspatial.py — tracks angle-of-arrival informationcross_band.py — captures relationships between channelscausal_temporal.py — tracks temporal state without using future datacompact_state.py — turns the state into compact vector representationsTogether, these modules provide the information needed for a scheduler to make an informed decision without seeing the hidden future.
This contains the general predictive-model framework.
predictor_service.pyProvides a service layer for loading and querying predictive models.
models/activity/This package contains activity-prediction models:
base.py — abstract predictor interfacehistorical_rate.py — predicts based on historical activity ratepersistence.py — predicts that recent activity will continuelogistic.py — logistic-regression-based predictorgradient_boosting.py — gradient-boosting predictordataset.py — builds model-training datasetstargets.py — creates prediction targetssplits.py — controls scenario-level data splitsevaluator.py — evaluates prediction qualitypipeline.py — training, prediction, calibration, and reproducibility pipelineconfig.py — model and pipeline configurationThe package supports both simple baselines and more sophisticated learned predictors.
This contains the scheduler implementations that choose the next scan action.
base.py — abstract BaseScheduleractions.py — converts between channel actions and adaptive action representationscandidate.py — generates candidate channels and opportunitiespolicies.py — reusable candidate-selection policiesaction_value.py — computes action values and feasibilityrandom.py — random channel selectionsequential.py — fixed cyclic sweepgreedy.py — immediate activity or recency-based selectionucb.py — upper-confidence-bound explorationthompson.py — Thompson samplingwhittle.py — Whittle-index-style schedulingoracle.py — clairvoyant reference scheduler using privileged informationhierarchical.py — hierarchical schedulingdqn_scheduler.py — deep Q-network-based schedulersmartscan.py — adaptive scoring based on sensing valuetemporal_predictor_scheduler.py — uses temporal activity predictionshort_horizon_planner.py — short-term planning baselineresidual.py — residual policy and safety gate logicvalue.py — opportunity-value and SmartScan scoringdqn.py — neural Q-network, replay buffer, and DDQN implementationprioritized_replay.py — staleness-stratified prioritized replayThis package contains both simple reference policies and more experimental learned or value-based schedulers.
This package determines whether a scheduler is actually useful.
counterfactual_replay.pyReplays scenarios and evaluates what would have happened if a different action had been selected. It includes:
metrics.pyComputes performance measures such as:
ground_truth.pyCompares scan histories against the complete hidden scenario ground truth.
engine.py and runner.pyProvide general experiment execution and result collection.
benchmark_harness.pyRuns canonical benchmark experiments, builds schedulers, evaluates scenarios, and computes aggregate statistics.
Contains the general backend test suite. The repository currently contains approximately 68 test files in this area.
These tests enforce:
Contains exploratory research notebooks:
phase2_environment_demo.ipynbphase4_feature_exploration.ipynbThese are useful for understanding the project interactively rather than through production-style modules.
Contains compressed train, validation, and test CSV datasets for temporal modeling.
backend/q_scheduler/ subsystemThis is the most specialized part of the backend. It implements the mission-level Q-Scheduler rather than only the generic scheduler framework.
Its main decision is between:
Contains configuration definitions for different research phases:
phase4b2_config.pyphase5_config.pyphase6_config.pypilot_config.pyq_h_v2_config.pyThese define feature schemas, cohort sizes, evaluation parameters, thresholds, and model paths.
Contains training and evaluation dataset construction tools:
This package creates supervised examples from simulated decisions and counterfactual outcomes.
Contains the mission-level predictive models.
q_h_bundle.pyLoads frozen multi-horizon Q_H regressors. These estimate the expected improvement or degradation in mission objective from taking a candidate action.
The repository includes several time horizons, such as:
mission_risk_bundle.pyLoads the mission-risk model. This predicts the probability that an override will produce a positive mission outcome.
train_qh.pytrain_mission_risk.pymission_risk_factory.pyq_h_v2_training_preparation.pyThese prepare and train the predictive models.
models/q_h/ contains frozen Q-H model files and metadata.models/mission_risk/ contains the mission-risk model and its feature schema.models/q_h_v2/ contains schema and metadata for the newer model version.This is the central planning package.
decision_planner.pyThe main planner that routes candidate actions through the available policy logic.
discovery_gate.pyImplements anti-repetition behavior. Once a channel has produced a useful discovery, the scheduler should not repeatedly return there simply because it remains active.
opportunity_cost.pyCalculates the cost of diverting from the normal raster. It considers whether:
dynamic_keep.pyCalculates a dynamic threshold for deciding whether an override is valuable enough to beat the KEEP action.
contextual_gate.pyAllows a previously suppressed channel to become eligible again when new temporal or burst evidence appears.
safety_feasibility.pyPerforms safety prechecks on candidate actions.
planner_types.pyDefines the planner’s core data structures, including candidates, policies, configurations, and inference results.
Contains CausalTemporalEpisodeTracker and related channel episode tracking logic.
It maintains state such as:
It is designed to ensure that planning decisions only use information available at the current point in time.
Analyzes periodic emitter behavior.
periodic_analyzer.py — PRI autocorrelation and harmonic analysisperiodic_types.py — result data structuressynthetic_benchmarks.py — synthetic periodic-signal generationreal_data_smoke_test.py — smoke tests against real scenario filesadversarial_audit.py — stress tests for periodic analysisThis supports detection of radar pulse trains and intelligent re-entry into channels with periodic activity.
Contains specialized evaluation tools:
baseline_evaluator.py — evaluates the sequential sweepcanonical_four_way_evaluation.py — compares several scheduler familiesplanner_ablation.py — runs model and policy ablationscounterfactual.py — constructs counterfactual targetsmission_risk_evaluator.py — evaluates risk predictionqh_evaluator.py — validates Q-H modelsprotected_data_guard.py — prevents accidental use of protected holdout dataaction_space_audit.py — checks candidate-action parityq_h_v2_leakage_audit.py — searches for feature leakageContains approximately 32 focused tests for the advanced planner subsystem, including:
This is the FastAPI entry point for the dashboard-facing backend.
It exposes:
| Endpoint | Purpose |
|---|---|
GET / | Basic API/root response |
GET /api/training_curves | Returns training-curve data |
GET /api/policies | Lists available comparison policies |
GET /api/configs | Lists available STARE scenario configurations |
GET /api/comparison/{config_id} | Runs a complete sequential-versus-adaptive comparison |
GET /api/stream/{config_id} | Streams comparison steps using Server-Sent Events |
The available policies are:
da — Discovery-Awareopp_cost — Opportunity-Costdynamic_keep — Dynamic KEEPshp — Short-Horizon PlannerThe server:
It also maintains in-memory caches for scenario data, heatmaps, emitter metadata, preprocessing results, and comparison results.
The API expects scenario data in external runtime locations such as:
stare/
scan/
Those directories are not present in the attached repository, so a fresh checkout will need the corresponding scenario data before the API can run successfully.
The frontend is a Next.js application located at:
frontend/ew-dashboard/
It uses:
src/app/page.tsxThe main dashboard page.
It provides:
The page loads pre-generated JSON from paths such as:
/data/config_list.json
/data/test_stats.json
/data/config_0.json
src/app/compare/page.tsxA thin route wrapper that displays ComparisonPage.
src/app/radar/page.tsxA more focused radar-style view containing:
src/app/layout.tsxDefines global layout, metadata, viewport settings, and application-level wrappers.
src/app/globals.cssContains the dashboard’s global styling and visual theme.
src/app/loading.tsxDisplays the loading UI while a page is being prepared.
src/app/error.tsxProvides the route-level error boundary.
SpectrumWaterfall.tsx — time/frequency waterfall displayFrequencySpectrum.tsx — frequency distribution chartAmplitudeDistribution.tsx — pulse-amplitude distributionPRFHistogram.tsx — pulse-repetition-frequency visualizationAoAPolarPlot.tsx — angle-of-arrival plotScatterPlot.tsx — pulse feature scatter plotBandEmitterHeatmap.tsx — emitter activity by bandEmitterFeatureSpace.tsx — emitter feature-space visualizationInterceptionRatioOverTime.tsx — interception performance over timeCumulativeDetectionCurve.tsx — cumulative discovery behaviorTrainingCurves.tsx — ML training and validation curvesScanTimeline.tsx — scan progression over the missionDecisionLog.tsx — chronological scheduler decisionsDatasetExplorer.tsx — scenario-level dataset statisticsEmitterDetailPanel.tsx — details for the selected emitterSidebar.tsx — channel/scenario navigationStatusBar.tsx — system status and mission indicatorsLoadingSkeleton.tsx — loading placeholdersThe src/components/compare/ directory is dedicated to policy comparison:
ComparisonPage.tsx — orchestrates the comparison screenComparisonTopBar.tsx — policy and scenario controlsComparisonMetrics.tsx — comparison metricsComparisonRadarScope.tsx — visual radar comparisonComparisonWaterfall.tsx — sequential versus adaptive waterfallComparisonTimeline.tsx — side-by-side scan timelineComparisonThreatMatrix.tsx — threat-discovery comparisonComparisonDivergenceBanner.tsx — highlights policy divergenceDivergenceLog.tsx — records moments where the policies choose differentlyemitterColors.ts — consistent emitter coloring utilitiesThe src/components/radar/ directory provides the more tactical operator view:
RadarScope.tsxMissionScoreboard.tsxThreatBandList.tsxRadarEventFeed.tsxMissionTimeline.tsxCentral playback state for moving through mission time.
It manages:
Animates numeric dashboard values.
Provides animation-frame utilities, interpolation, and clamping.
Defines the structure of scenario JSON data and test-stat records.
Defines policy identifiers and comparison types. It includes the four supported policy IDs and helper functions for displaying policy names.
Reads HDF5 scan files and converts them into dashboard-friendly JSON.
It extracts information such as:
The generated files are written to:
frontend/ew-dashboard/public/data/
Converts dataset-level CSV statistics into test_stats.json for the dashboard.
The scripts expect a repository-level scan/ directory. In the attached copy, that directory is not present, and the generated public/data/ files are also not present. Therefore, the frontend source exists, but the default dashboard data must be generated or supplied before it can operate as intended.
The fixed baseline. It visits channels in order and provides predictable coverage.
Its strength is reliability and coverage. Its weakness is that it cannot react to short-lived opportunities.
Chooses a channel based mainly on immediate pulse or discovery opportunity. It is useful as a legacy or myopic baseline, but it can over-focus on currently active channels.
Prioritizes channels containing emitters that have not yet been discovered. It also uses an anti-repetition memory to avoid repeatedly scanning an already-understood channel.
Improves on Discovery-Aware behavior by charging an explicit cost for leaving the nominal raster. It asks:
Computes a dynamic hurdle for overriding the raster. The scheduler remains with the nominal scan unless the best candidate exceeds the current KEEP threshold.
The system does not allow an adaptive policy to divert indefinitely.
The safety gate projects future channel revisit times and vetoes an override if it would cause a channel to remain unvisited beyond the allowed starvation limit. The documentation describes this limit as approximately 2.30 seconds, slightly longer than the nominal 2.15-second sweep to provide limited maneuvering slack.
When an override is rejected, the system falls back to the scheduled raster action.
This is important because the adaptive policy is not allowed to sacrifice broad spectrum surveillance merely to chase a locally attractive signal.
The most operationally relevant files are:
backend/api/server.py
backend/src/data/
backend/src/environment/
backend/src/features/
backend/src/schedulers/
backend/src/evaluation/
backend/q_scheduler/planner/
backend/q_scheduler/models/
backend/q_scheduler/state/
frontend/ew-dashboard/src/
These areas are primarily for experimentation, validation, and scientific analysis:
backend/notebooks/
backend/q_scheduler/evaluation/
backend/q_scheduler/scripts/
scripts/
reports/
docs/
They are still important, but they are not all part of the live request path.
The repository contains both a general scheduler framework and a more specialized Q-Scheduler framework.
backend/src/schedulers/ contains the broader family of scheduling strategies, while backend/q_scheduler/ contains the newer mission-level planning architecture.
The dashboard has two data paths.
The main dashboard uses pre-generated JSON files under public/data/, while the comparison/training functionality communicates with the FastAPI backend.
Some runtime inputs are external to the repository.
The API expects stare/ and scan/ scenario data directories, but they are not included in the attached copy.
The project is heavily research-oriented.
The many phase reports, audits, manifests, traces, and statistical outputs show that the authors focused not only on implementing a scheduler but also on proving that it does not use future information and that its reported improvements are reproducible.
The most important conceptual distinction is immediate reward versus mission value.
The project deliberately moves away from “which channel has the most pulses right now?” toward “which action most improves discovery over the entire mission while preserving coverage?”
In short, this is an adaptive RF surveillance research platform: it simulates a constrained EW receiver, learns or estimates which scan actions are valuable, compares multiple scheduling policies, enforces coverage safety, and exposes the resulting behavior through an operator-style dashboard.
comments (0)