Loading…
Freq (MHz) dB Source Type Conf Evidence Date File

What this shows. Every row currently on the page is one power measurement. Its horizontal position is the frequency it was taken at; its vertical position is when it was taken (oldest at the bottom, newest at the top); its colour is how loud it was.

How to read it. A bright vertical stripe means one frequency was loud on many captures — a persistent emitter. A bright blob means a single capture stood out — a burst or a transient. A faint or empty column means that band was quiet throughout. The time gridlines on the left are UTC; the frequency gridlines on the bottom are MHz.

Watch the colour. Colour is normalised to this page: the strongest row on screen is drawn at the top of the ramp, the weakest at the bottom, and everything else is scaled between them. The header shows the actual dBFS range the ramp is mapped to. Two pages with different ranges will colour the same physical power differently, so do not compare colours across pages — use the Compare tab for that, since it is baselined per frequency bucket.

What it does not show. No absolute power axis, no detection markers, and no IQ. Rows are drawn in arrival order, so a single frequency scanned twice in one second will draw two pixels at nearly the same y position — they are both real measurements, not a duplicate bug.

What this shows. The distribution of power across every row currently on the page, regardless of frequency or time. The horizontal axis is power in dBFS, bucketed into 2 dB bins. The vertical axis is how many rows fell into each bin.

How to read it. The tall narrow peak on the left is the noise floor — most measurements are quiet, and they pile up there. Anything to the right of that peak is signal: rows where a receiver saw something louder than the floor. A second hump to the right of the noise peak usually means a persistent emitter at a specific power. A long thin tail with no second peak means intermittent strong signals — a handful of loud moments scattered across a lot of quiet. A clearly bimodal shape (two distinct peaks) almost always means two different sources or two different gain settings are mixed in the current filter.

Median marker. The dashed orange line is the median power of all rows on the page. If the median sits inside the noise peak, the page is dominated by quiet measurements. If it sits noticeably to the right, more than half the rows are signal.

What it does not show. This is not a spectrum. The x-axis is power, not frequency, so two entirely different emitters at the same power end up in the same bar. To see which frequencies are loud, use the Heatmap tab. To see which individual rows are loudest, use Strongest.

Freq (MHz) dB Source Type

What this shows. The daily analysis report for the chosen UTC day. Each row is one record produced by the analysis pipeline on the ASUS. Nothing is filtered or capped — every observation that reached the analyser reaches this view.

Pick a record type. The Type dropdown lists the record types present in that day's report. Each type has its own columns:

  • prf_cluster — repeated periodicities observed in telemetry. freq_hz is the RF frequency the rate was seen at, or empty if the only source was the soundcard. prf_hz is the pulse repetition rate. spread is how many distinct frequency buckets that rate appeared in.
  • pulse_train — frequency bins whose power varied by more than 6 dB across the run.
  • band_activity — per 1 MHz band statistics across all receivers.
  • cross_device_hit — frequencies seen by two or more receivers.
  • iq_analysis — one record per IQ capture. The constraint_evaluations field lists, for every service operating in the band, which of that service's constraints the observed metrics satisfy and which they do not, with the source of each constraint.
  • detection — a raw detection row from the telemetry database, full metadata preserved.
  • evidence_error — a capture that could not be analysed and the reason.
  • session_summary / analysis_complete / detection_summary / iq_processing_summary — single-row summaries of the day's run.

Details. Click any row to expand a structured view of that record inline, directly under the row. Nested fields (constraint_evaluations, harmonics_hz, comb_hz, devices, metadata) are expanded in place. A "show raw JSON" toggle at the bottom of the panel reveals the exact record as written to the report.

Where it comes from. /opt/havana-shield/reports/analysis_<day>.jsonl.gz on the VMI, written by daily_analyse.py on the ASUS. The DB is not involved; the reports are read directly.

What this shows. For each frequency bucket, the change in average power between File A (baseline) and File B. The x-axis is frequency. The y-axis is the delta: red bars grow up from the centre line when B is stronger than A, blue bars grow down when B is weaker.

How to read it. A tall red column at a frequency means that frequency got hotter between the two captures. A tall blue column means it got quieter. A clean flat line near zero means the spectrum is unchanged between the two files.

Bucket size. Defaults to 100 kHz. Widen it (1 MHz, 10 MHz) to see broad trends; narrow it (10 kHz, 1 kHz) to isolate a single carrier. The bucket must be at least as wide as the sweep resolution or the comparison will be noisy.

What it does not show. Absolute power — only the difference.

Live View RTL.SDR. Watch for yourself.

Target Neuropa MHz Nearest scan MHz Δ MHz dB Match Nearest source

What this shows. Every distinct target that parse_neuropa_overlaps.py has ever flagged (read from /opt/havana-shield/neuropa_overlaps.json) matched against your current filtered detections. A target is verified when at least one of your rows sits within Tolerance MHz of the claimed frequency and passes the Min power gate.

Claimed dB is the power the neuropa pass reported for that target the first time it was seen. Best dB is the strongest row in your data that falls inside the tolerance window. Δ MHz is the distance from the claim to your closest hit.

What it does not show. It does not compare times — a target is verified if your data ever contains a matching row, not if the two captures were taken on the same day. For a same‑day comparison, set the main filters to a single file first, then run the cross‑analysis.

PRF verification (from IQ analysis)

PRF target Neuropa Hz Nearest detected Hz Δ Hz Score Match IQ capture path

What this shows. Every pulse repetition frequency that analyze_iq_prf.py searches for, and whether any of your captured IQ files contains it. The data is read directly from iq_prf_analysis.json — the IQ script itself is not re-run here.

Score is the best normalised autocorrelation coefficient found across all matching captures. IQ captures counts how many of your files contained the target PRF. Verified is yes when that count is at least one.

What it does not show. It does not tell you which capture had the strongest score — hover a row to see the best filename. For a per-capture breakdown, inspect iq_prf_analysis.json directly.