Patrick Lidstone
Self-hosted

HRPT & AHRPT — full-resolution polar weather imagery

Two routes to the same instrument: NOAA HRPT is the raw one — Manchester chips at 1330.8 kchip/s, 10-bit words in fixed 11090-word minor frames, no FEC at all — while MetOp/FengYun AHRPT wraps the identical AVHRR data in the full CCSDS machinery (Viterbi + RS CADUs + Space Packets) this repo already runs for LRPT.

Rafe project · app/radio/sat/hrpt.py, app/radio/sat/ahrpt.py · test_sat_hrpt.py, test_sat_hrpt_iq.py, test_sat_ahrpt.py · RX (+ reference encoders for self-test) · HRPT minor-frame sync word is a self-consistent placeholder — transcribe the exact NOAA KLM value before an on-air capture (§2.2)


Abstract

The AVHRR imager on the NOAA POES and MetOp satellites produces 5 spectral channels × 2048 samples per scan line. NOAA's HRPT downlink (1698 MHz band, BPSK) is gloriously archaic: no error correction whatsoever, just bi-phase-L (Manchester) chips carrying 10-bit words in a rigid frame — if your S-band dish gives you clean bits you get a clean image, and every bit error is a speckle. AHRPT (MetOp, FengYun) is the modern re-plumbing: the same instrument words ride CCSDS Space Packets inside RS-protected, convolutionally-coded CADUs — so Rafe's implementation is deliberately thin, reusing the CCSDS core (ccsds.py) wholesale and adding only the AVHRR payload layer. This document pins both framings, the shared word/ de-interleave machinery, and the IQ front ends.

1. Shared machinery: 10-bit words and channel de-interleave

AVHRR words are 10-bit, MSB first (pack_words/unpack_words). The earth view of one scan line is 10 240 words = 5 channels × 2048 samples, interleaved word-by-word: word \(k\) belongs to channel \(k \bmod 5\), sample \(\lfloor k/5 \rfloor\) (deinterleave → a (5, 2048) array per line; channel_images stacks lines into 5 per-channel images, one row per frame).

2. NOAA HRPT

2.1 Physical layer

Parameter Value Code
Bit rate 665 400 bit/s BIT_RATE
Line code Manchester / bi-phase-L: 1 → 10, 0 → 01 manchester_encode
Chip rate 2 × 665 400 = 1 330 800 chip/s CHIP_RATE
Carrier BPSK (≈1698/1702/1707 MHz) decode_iq via qpsk_rx.demod_bpsk

manchester_decode takes the first chip of each pair. decode_iq runs the shared BPSK receiver (AGC → RRC → Gardner → Costas) at chip rate, hard-slices, then tries the 2 BPSK polarities × 2 Manchester chip phases and keeps the combination in which the frame sync appears — the ambiguity-resolution-by- sync-word pattern used throughout the satellite stack.

2.2 Minor-frame structure

Parameter Value Code
Words per minor frame 11 090 WORDS_PER_FRAME
Frame sync 6 ten-bit words (60 bits) HRPT_SYNC
Sync tolerance ≤ 6 bit errors in 60 find_sync(max_err=6)
Earth-view offset word 750 EARTH_START
Earth view words 750 … 750+10239 EARTH_WORDS

One minor frame = one scan line (3 lines/second). The words before the earth view carry telemetry, calibration and space view — skipped (zero-filled by the reference encoder), listed in §4. The stream decoder (decode) hunts the sync from any bit offset (the test prepends 37 junk bits), extracts each frame's earth words, de-interleaves, and steps exactly one frame forward — frame after frame until the bits run out, no inter-frame state needed because there is no FEC to synchronise.

Interop caveat (deliberate): HRPT_SYNC1000010111 0011111010 0011000001 1110110001 0101101010 1001000000 — is flagged in the source as a self-consistent constant. Transcribe the exact NOAA KLM minor-frame sync before trusting an on-air capture; everything else (word size, frame length, interleave, offsets) is standard HRPT geometry.

3. MetOp / FengYun AHRPT

AHRPT carries AVHRR as CCSDS Space Packets (APID 103) inside the same CADU pipeline as LRPT — so ahrpt.py is ~90 lines of glue:

Encode (reference/test): scan lines → 10-bit interleaved words (reusing hrpt.pack_words) → a payload prefixed by a 5-byte dimension header [nch, nsamp_lo, nsamp_hi, nlines_lo, nlines_hi] → 800-byte segments, each a Space Packet (sequence-numbered) → one packet per VCDU (892-byte frame, 6-byte header zone + 2-byte M-PDU pointer) → 4 × 223-byte RS chunks → ccsds.encode_cadu(…, interleave=4) (RS(255,223) ×4, PN randomiser, ASM, r=1/2 K=7 convolution).

Decode: ccsds.decode_stream (Viterbi → ASM hunt → derandomise → RS) → lrpt.extract_packets → filter APID 103 → reassemble segments by packet sequence number → parse the dimension header → unpack_avhrr back to per-line (nch, nsamp) arrays.

IQ front end: AHRPT is OQPSK; decode_ahrpt_iq demodulates with the shared receiver and tries the 4 phase rotations × I/Q swap, letting the CCSDS ASM arbitrate — identical strategy to LRPT.

Scope note: the 5-byte dimension header is Rafe's own serialisation for the payload layer (the real MetOp AVHRR packet layout carries its dimensions implicitly); APID, packet, CADU and FEC layers are the standard CCSDS ones, shared with and validated by the LRPT chain.

4. Validation

Test Asserts
test_manchester_roundtrip chip encode/decode identity
test_word_pack_roundtrip 10-bit word pack/unpack identity
test_frame_decode_and_deinterleave 3 frames + 37 junk lead-in bits → all 5 channels of each recovered exactly
test_sync_tolerates_bit_errors sync found with 4 errors in its 60 bits
test_channel_images_shape 5 stacked images, one row per frame
test_hrpt_full_decode_iq raw BPSK IQ (120 Hz offset, timing/phase offsets, noise) → exact channels
test_avhrr_pack_roundtrip AHRPT 10-bit payload pack/unpack identity
test_ahrpt_over_ccsds_multicadu 6 lines spanning many CADUs → exact recovery through the full CCSDS chain
test_ahrpt_iq_impaired OQPSK IQ, 170 Hz offset + noise → exact lines

5. Limitations

  • HRPT telemetry ignored. Words 0–749 (TIP telemetry, calibration, space view) are skipped; only the earth view is extracted. Calibrated temperatures/albedo would start there.
  • HRPT sync constant needs the KLM transcription (§2.2).
  • AHRPT dimension header is Rafe-internal (§3); real-capture interop needs the MetOp AVHRR packet field layout.
  • Real-time streaming decode wires through sat/decode_file.py and the collector roles described in sat.md.

Related: LRPT (the CCSDS core both reuse; Meteor's JPEG alternative to raw AVHRR), APT (the analog ancestor), xRIT (the geostationary file layer), and the maths guide on concatenated FEC.