Asking the fleet what it is doing…
monad-knowledge Wi-Fi sensing lab · FIIT STU

Preprocessing — why raw CSI lies: the sanitisation ladder from oscillator offsets and AGC to a signal you can trust

A 100-minute lecture. Timings are indicative; the concept checks between acts are meant to be asked out loud and answered before moving on. Every number in this text is labelled either measured (first-party hardware, dated) or in-silico (printed by workbook.ipynb at seed 7). Numbers derived on the board from first principles are called out as such.

Part 0 · The Number That Should Not Exist (0:00–0:08)

Week 3 got the CSI table onto disk honestly and deliberately left it dirty. Week 4 showed that even the 802.11bf standard does not clean it: the standard negotiates acquisition and reporting, and every hardware artefact — the per-packet gain, the coloured band edges, the oscillator phase terms — survives on standardised and raw CSI alike. This week is the cleanup that both weeks promised.

Since Week 4, the promise has a measured face. On 2026-07-27 the lab brought up its first illuminated link — monad01 transmitting to monad02, two AX210 cards in an ordinary office — and the raw numbers are worth staring at before any theory. The per-packet phase intercept of the raw CSI had a standard deviation of 3.5 radians. Pause on that. The phase lives on a circle of circumference 2\pi \approx 6.28 radians; a dispersion of 3.5 radians, wrapped onto that circle, is statistically indistinguishable from a uniform draw. The phase of the channel — the quantity every geometric method in Weeks 8–9 wants, the quantity that encodes path lengths at millimetre sensitivity — was, in the raw record, a random number.

Then one preprocessing step: divide the CSI of one RX chain by the CSI of the other, packet by packet. The circular standard deviation of the phase fell to 0.26 radians. A usable signal. The per-tone amplitude coefficient of variation fell from 0.32 to 0.20 under the same operation. (All measured, 2026-07-27.)

No filter was designed. No model was trained. No calibration table was consulted. A division — one line of NumPy — recovered a phase that three decades of engineering effort in the NIC had apparently destroyed. That asymmetry is the puzzle of the week: why is raw CSI that bad, and why is the repair that cheap? The answer to the first half is that the NIC was never trying to give you the channel — it was trying to decode bits, and everything it does to the measurement is in service of that goal. The answer to the second half is a structural fact about where the corruption enters, and it will fall out of a derivation you can do in four lines.

Raw CSI is not a noisy version of the channel; on the axes that matter, it is not the channel at all. That is what this week means by "raw CSI lies", and the sanitisation ladder — the ordered set of repairs this lecture builds — is what makes it stop lying.

One scoping note before we start. The Week 4 log seeded this week with the 996-tone synthetic channel of the standards lecture. We teach instead on the 56-tone HT grid, because that is the record class our own illuminated link actually captures — the course rule is that the first-party measured anchor wins over a synthetic convenience. The mechanisms are tone-count-independent; the in-silico numbers below come from a synthetic two-chain channel whose corruption scales are matched to the measured link, and every in-silico number is labelled as such next to its measured counterpart. The anchor external source, continuing from Weeks 3 and 4, is the Tsinghua WST tutorial — this week specifically its Sanitization page, which organises the same ladder we build here.

Part 1 · The Problem Nobody Ordered: What a Receiver Does to a Channel (0:08–0:25)

1.1 Two historical facts about radios

Everything in this act follows from two engineering constraints that predate Wi-Fi sensing by decades, and it is worth telling them as history, because both were solutions — celebrated ones — before sensing arrived and turned them into problems.

Fact one: a receiver must survive sixty decibels of dynamic range. A Wi-Fi device a metre from its access point and the same device fifty metres away, through two walls, see received powers that differ by 60–80 dB — a factor of a million or more. This is the near–far problem, and it is as old as radio itself: AM broadcast receivers in the 1920s already needed "automatic volume control" so that a nearby station did not blast and a distant one did not whisper. A modern ADC with b effective bits spans roughly 6b dB — a 10-bit converter covers about 60 dB, and only if the signal is placed exactly inside that window. So every radio front-end since has carried an automatic gain control (AGC): a feedback loop that measures incoming power and applies whatever gain places the signal in the ADC's sweet spot, packet by packet. For communication this is pure win — the constellation that the demodulator sees is gain-invariant after equalisation, so nobody ever needed to report the gain, and commodity NICs do not. For sensing it means the amplitude scale of every CSI record has been multiplied by an unknown, per-packet number. Communication's gain is sensing's loss — literally.

Fact two: no two radios share a clock. Every radio synthesises its carrier from a local crystal oscillator, and crystals are cut to a tolerance. The 802.11 OFDM specification requires centre-frequency accuracy within about ±20 parts per million. At a 5.32 GHz carrier — the course's running band example from Week 3 — 20 ppm is 5.32\times10^9 \times 20\times10^{-6} \approx 106\ \text{kHz} — and since transmitter and receiver can each be off in opposite directions, the raw carrier-frequency offset (CFO) between two in-spec radios can exceed 200 kHz. (Board arithmetic; keep the orders of magnitude, not the digits.) The receiver estimates and corrects most of this from the packet preamble, but the correction is never exact; residuals of tens to hundreds of hertz remain. A residual of even 100 Hz accumulates 2\pi \times 100 \times 0.01 \approx 6.3 radians of phase in the 10 ms between two packets — a full wrap. This is why the phase error is not a fixed offset you could calibrate once: it is a fresh draw every packet.

Hold both facts, because the entire week is their consequence: the receiver applies an unobserved gain (fact one) and an unobserved, per-packet phase (fact two), and the sensing literature's "sanitisation" is the art of undoing both from the outside.

1.2 The measurement model, term by term

Week 2 wrote the reported CSI as \hat H_{r,k} = a\,e^{j\theta} per RX chain r and tone k, and flagged that the angles carry offsets. Now we name them. Per packet t, what a commodity NIC reports is well modelled as

\hat H_r(k, t) \;=\; g(t)\, e^{j\left(\phi(t) + \beta(t)\,k\right)}\; H_r(k, t) \;+\; n_r(k,t),

where every symbol earns its place:

  • H_r(k,t) — the physical channel on chain r, tone k, packet t: the multipath sum of Weeks 1–2. This is what we want.
  • g(t) — the AGC gain: fact one made algebraic. A positive scalar, per packet, common to all tones (the gain is applied in the analogue front-end, before the FFT that separates tones), and never reported.
  • \phi(t) — a random per-packet phase intercept: fact two made algebraic, plus a second contributor. The residual CFO accumulates phase between packets, as computed above; and the packet-boundary detector — the correlator that decides "the packet starts at this sample" — lands on a slightly different sample each time, which also shifts all phases together. Both effects are constant across tones within one packet and random across packets, so they merge into one intercept. On the lab's link its dispersion is the measured 3.5 rad.
  • \beta(t)\,k — a linear phase slope across tones. Here is the derivation, because it is two lines and it explains the shape. A timing error of \tau seconds means the receiver Fourier-transforms x(t-\tau) instead of x(t); the shift theorem says the transform acquires a factor e^{-j2\pi f \tau}. Tone k sits at frequency f_k = k\,\Delta f relative to the carrier (with \Delta f = 312.5 kHz), so its phase shifts by -2\pi k\,\Delta f\,\taulinear in k, with slope \beta = -2\pi\,\Delta f\,\tau. Feel the sensitivity: a single-sample error at 20 MHz is \tau = 50 ns, giving \beta = 2\pi \times 312.5\times10^3 \times 50\times10^{-9} \approx 0.098 rad/tone — about 5.5 radians of tilt across a 56-tone grid from one sample of mis-timing (board arithmetic). Sampling-frequency offset (SFO — the ADC clocks also disagree by ppm) adds a slowly drifting contribution of the same linear-in-k form. The workbook injects a slope std of 0.02 rad/tone, which corresponds to a residual timing jitter of about 10 ns — a fifth of a sample, i.e. a good packet detector, and still enough to matter.
  • n_r(k,t) — thermal noise. The only term in the model that behaves the way textbooks assume.

Two properties of this model drive the whole week. First, \phi, \beta and g are time-varying and unobserved: no one-off calibration can remove them, because they are different on every packet (ma2020_4782 ). Second — the exploitable structure — they are common across the RX chains of one NIC, because both chains share one oscillator, one sampling clock, and (to first order) one gain step (zeng2021_1e4f ). Notice what is not indexed by r in the model: g, \phi, \beta. That absence of a subscript is the whole trick. What is common to two measurements can be cancelled by comparing them, and that observation is the top rung of the ladder.

The sanitisation ladder, as this course and the WST tutorial's Sanitization page organise it, has an amplitude side and a phase side. Amplitude: remove or normalise the AGC gain, handle the band-edge roll-off, denoise what remains. Phase: detrend the linear slope, then cancel the residual offsets by a cross-chain operation — the CSI ratio (divide chain 1 by chain 2) or conjugate multiplication (multiply chain 1 by the conjugate of chain 2), which cancel the same common terms through division of phases or subtraction of phases respectively (xie2015_0389 ; diaz2023_7d09 ). Parts 2 and 3 walk the two sides; Parts 4–6 add the rungs most pipelines forget exist.

1.3 Interlude: the labs that never had this problem

To sharpen what is special about commodity-NIC sensing, look at the research lineage that sidestepped it — the MIT CSAIL through-wall systems of 2013–2015, which are also the systems that put RF sensing on the map.

WiVi (Adib and Katabi, SIGCOMM 2013) demonstrated through-wall motion detection at Wi-Fi frequencies — but not on Wi-Fi cards. It was built on USRP software-defined radios, and its core move was interference nulling: use MIMO to cancel the static reflection of the wall itself, so that the residual signal is dominated by the moving person behind it. WiTrack (Adib, Kabelac, Katabi and Miller, NSDI 2014) went further — 3D localisation of a person through a wall, at decimetre-scale accuracy — using a purpose-built FMCW front-end sweeping more than a gigahertz of bandwidth. RF-Capture (Adib et al., 2015) then reconstructed a coarse human figure through the wall from the same FMCW machinery. The lineage is summarised, with the systems that followed it, in the surveys we keep on the shelf (alqaness2019_397d ; wang2021_d8e3 ).

Here is the point for this lecture. In every one of those systems, transmitter and receiver were either the same device or shared a clock by construction. A monostatic FMCW radar mixes the received chirp with the transmitted chirp — the same oscillator, self-referenced — so the beat frequency it measures contains no CFO at all; there is no second crystal to disagree with the first. The measurement model of Section 1.2 simply does not apply: \phi(t) and \beta(t) never enter. These systems bought clean phase with custom hardware, wide bandwidth, and full control of the waveform.

Commodity-NIC CSI sensing is the opposite bargain: hardware that is already deployed in every room on earth, in exchange for a bistatic measurement between two clocks that have never met. The 3.5 radians on our first link is the price of that bargain, printed in data. The rest of this lecture is about not paying it twice.

Part 2 · The Phase Rung: One Shared Oscillator, So Divide (0:25–0:48)

2.1 How bad is 3.5 radians? A two-minute detour into circular statistics

Phases live on a circle, and dispersion on a circle needs its own estimator — you cannot subtract a mean from angles that wrap. The standard construction: map every phase to a unit phasor e^{j\theta_i}, average the phasors, and call the length of the average the resultant length

\bar R \;=\; \Bigl|\tfrac{1}{N}\textstyle\sum_{i=1}^N e^{j\theta_i}\Bigr|, \qquad 0 \le \bar R \le 1 .

If all phases agree, the phasors add coherently and \bar R \to 1. If the phases are uniform on the circle, the phasors cancel and \bar R \to 0. The circular standard deviation is defined as \sigma_c = \sqrt{-2\ln \bar R} — for small dispersion it agrees with the ordinary standard deviation (Taylor-expand and check this at home), and for \bar R \to 0 it diverges, as it should: a uniform phase has no meaningful spread parameter.

But a finite sample of uniform phases never gives exactly \bar R = 0: the N phasors execute a random walk whose resultant has expected length of order 1/\sqrt{N}. With the workbook's N = 600 packets, \bar R \approx 1/\sqrt{600} \approx 0.04, so the estimator saturates near \sigma_c \approx \sqrt{-2\ln 0.04} \approx 2.5 rad (board arithmetic). Now you can read the workbook's numbers correctly: the injected intercept std is 3.5 rad, but the estimated circular std comes out at 2.37 rad (intercept) and 2.39 rad (raw phase at tone k=+10) — both in-silico. Those are not measurements of 3.5; they are the saturation ceiling for N=600, which is the estimator's honest way of saying "this phase is indistinguishable from uniform — there is nothing here to measure." When you see a circular std pinned near 2.4–2.5 rad on 600 samples, stop interpreting the digits: the phase is gone.

2.2 The classical fix, and what it costs

The literature's first-generation answer is the linear-fit transform: for each packet, fit \phi + \beta k across tones by least squares and subtract it (ma2020_4782 ; diaz2023_7d09 ). This works, in the sense that the residual phase is stable — and it is still the right tool when only one RX chain exists. But look at what the subtraction removes: any component of the true channel phase that happens to be linear in k. Week 2 told you exactly what a linear phase across tones means physically: a pure delay. The line you subtract contains the line the geometry wrote. Linear-fit sanitisation therefore destroys absolute time-of-flight — after it, you can see phase curvature (multipath structure) and phase change (motion), but never absolute range. It also does nothing about corruption that is not linear in k. It is a lossy repair: acceptable for activity recognition, disqualifying for ranging.

2.3 The ratio: cancellation by construction

The sharper tool uses the structure we noticed in Part 1: the corruption carries no chain index. Write both chains of one NIC under the measurement model, drop the small noise term for clarity, and divide:

\frac{\hat H_1(k,t)}{\hat H_2(k,t)} \;=\; \frac{g(t)\,e^{j(\phi(t)+\beta(t)k)}\; H_1(k,t)}{g(t)\,e^{j(\phi(t)+\beta(t)k)}\; H_2(k,t)} \;=\; \frac{H_1(k,t)}{H_2(k,t)}.

Watch what happened, step by step: the scalar g(t) appears once in the numerator and once in the denominator — gone. The complex exponential is the same factor on both chains at the same (k,t) — gone, exactly, whatever value \phi and \beta took this packet. Nothing was estimated, so nothing carries estimation error; nothing was fitted, so no true structure was fitted away. The corruption was cancelled by construction, because division is exact and the corruption was common (zeng2021_1e4f ).

What survives is the ratio of two physical channels: the same room seen from two antennas a few centimetres apart. Is that still useful? Three answers, in increasing depth. Practically: yes — the ratio is a deterministic function of the channel, so any change in the room changes it. Structurally: when one path moves (a walking person) while the rest are static, the numerator traces a circle in the complex plane as the moving path's phase rotates (Week 1's phasor picture), and the ratio is a Möbius transformation of that circle — and Möbius transformations map circles to circles, so the motion signature survives the division intact, a point made carefully in the CSI-ratio paper (zeng2021_1e4f ). Theoretically: the Fresnel-zone analysis of wu2022_75d3 develops the ratio into a full sensing model — a reflector crossing Fresnel-zone boundaries traces the same peaks and valleys in the ratio as in the ideal channel. The ratio is not a trick that happens to work; it is an observable with a model.

The close cousin is conjugate multiplication: form \hat H_1(k,t)\,\overline{\hat H_2(k,t)}. The common phase subtracts (a conjugate negates it) instead of dividing out, so the oscillator terms cancel identically; the gains multiply instead of cancelling, so it repairs phase but squares the amplitude problem. The Widar lineage of gesture systems ran on cross-antenna conjugate operations of exactly this form; ratio versus conjugate is a choice you make based on whether amplitude or numerical robustness matters more downstream (division misbehaves when the denominator chain fades toward zero; multiplication never does). Both need the same thing: a second chain.

2.4 The numbers, in-silico and measured

The workbook (§5.1) rebuilds the cancellation from scratch: two chains with different static three-tap geometries, one moving-person path at 0.9 Hz, and a common per-packet corruption whose intercept std is set to the measured 3.5 rad. The raw phase at tone k=+10 is a cloud filling [-\pi,\pi], circular std 2.39 rad — the saturation ceiling of Section 2.1. The ratio phase at the same tone: circular std 0.07 rad, a 34-fold dispersion reduction, with the 0.9 Hz motion directly visible in the time series (all in-silico). The measured link tells the same story with real hardware: 3.5 rad → 0.26 rad. The in-silico residual is smaller than the measured one because a real link has per-chain noise the simulation only sketches — the direction and the mechanism, not the last digit, are the point.

Raw per-packet phase at one tone (left) is a uniform cloud over the circle — circular std saturated at 2.39 rad with a 3.5 rad common intercept injected, matched to the measured 2026-07-27 link. The two-chain CSI-ratio phase at the same tone (right) collapses to circular std 0.07 rad and shows the moving-person oscillation directly. Reproduce in Workbook §5.1.

The operational consequence deserves its own paragraph, because it is a capture requirement, not a processing preference: the CSI ratio needs two RX chains active in every record. A capture configured with one chain — or one that silently drops to one chain — cannot be phase-sanitised this way, ever, retroactively. There is no algorithm waiting in a future paper that will recover what a one-chain capture never recorded, because the information needed for the cancellation (the simultaneous second view under the same oscillator) does not exist in the file. On the lab's AX210 fleet, two active RX chains is therefore a hard requirement checked at capture time, on the same footing as Week 3's packet-rate floor. Conjugate multiplication inherits the same requirement for the same reason.

2.5 Case study: the systems that needed clean phase before it existed

CARM (Wang, Liu, Shahzad, Ling and Lu, MobiCom 2015) is the system that made Wi-Fi sensing quantitative. Its CSI-speed model links the frequency content of CSI variation to the speed of body movement — the scattering-model thread you met in Week 1 §8 — and its activity model maps speed profiles to activities (wang2015_48cf ). But a speed model reads spectra, and spectra are only as clean as the time series behind them. On an Intel 5300, with the phase of Section 2.1 — effectively uniform noise — CARM could not use phase directly at all; it worked on amplitude and spent real machinery on denoising it, running PCA across subcarriers to isolate the correlated channel variation from uncorrelated noise before any spectral analysis. Read CARM as a message from 2015: the features people wanted were already spectral and temporal; the observable they deserved — a clean phase — did not exist yet on commodity cards. The ratio, published six years later, is what closes that gap.

Respiration monitoring is the cleanest illustration of why the phase rung matters — the killer app for phase sanitisation. Quiet human breathing moves the chest wall by a few millimetres. At 5 GHz the wavelength is about 6 cm, so a millimetre-scale displacement changes a reflected path length by a small fraction of a wavelength — a phase modulation of a fraction of a radian, periodic at 0.2–0.4 Hz. Against a raw per-packet phase intercept with std 3.5 rad, that signal is buried by more than an order of magnitude; against a ratio phase with dispersion 0.07–0.26 rad, it is right at the surface, and the Fresnel-zone line of work that culminates in the CSI-ratio model (wu2022_75d3 ) grew directly out of respiration studies — including their famous position-dependence: a breather at a Fresnel-zone boundary is nearly invisible, a fact you can only even observe once the phase is clean. Whole product categories — contactless baby monitors, sleep trackers — sit on this one rung of the ladder.

Part 3 · The Amplitude Rung: The AGC Diary (0:48–1:05)

3.1 What the gain does to a feature

The amplitude side of the ladder starts with the uncomfortable fact from Part 1: absolute amplitude is uncalibrated on a real NIC. The AGC gain g(t) rescales the whole tone vector per packet, the NIC does not report the gain it applied, and transmit-power control on the other end adds its own unobserved per-packet scaling on top (xie2015_0389 ). A time series of raw |\hat H| at one tone is, to first order, a diary of the AGC's decisions with the channel superimposed.

Make the damage precise, because it is a two-line proof. The reported amplitude is |\hat H_r(k,t)| = g(t)\,|H_r(k,t)| (noise aside). Take the most tempting feature there is, the per-packet mean amplitude across tones:

m(t) \;=\; \tfrac{1}{N}\textstyle\sum_k |\hat H_r(k,t)| \;=\; g(t)\cdot \tfrac{1}{N}\textstyle\sum_k |H_r(k,t)|.

If the room is quasi-static — and indoors, packet to packet, it mostly is — the second factor is nearly constant, and m(t) \propto g(t): the feature is the gain. Any classifier trained on it learns the AGC's behaviour, which is a function of distance, transmit power, and firmware mood — and none of those transfer to the next deployment. This is the precise sense in which mean-level features die on real hardware.

Now see what survives, by the same algebra. Divide the tone vector by its own mean: a_k(t) = |\hat H(k,t)| \,/\, m(t) — the g(t) cancels, so the shape across tones is gain-invariant. Likewise any statistic of that shape (variances, tone-to-tone correlations — second-order structure), and likewise temporal structure computed on normalised quantities (the dynamics from packet to packet). The rule of thumb the survey literature repeats has this algebra underneath it: a scalar per-packet gain moves the whole tone vector together, so it can forge absolute levels but cannot forge relative or dynamical patterns.

3.2 The numbers

The workbook (§5.2) makes the diary explicit. With a gain spread chosen so the raw statistics land in the measured link's regime, the per-tone amplitude CV comes out at 0.39 raw (in-silico; the measured link: 0.32). The correlation between the per-packet mean amplitude and the injected AGC gain is 0.98: the feature is reading the gain, not the room — the two-line proof above, printed as a number. And because the simulation knows the gain it injected (which no real capture ever does), the workbook can draw the overlay a real experiment cannot: the raw amplitude trace hugging the gain trace point for point.

The two-chain ratio is again the strongest rung: the common gain divides out, and the in-silico CV falls from 0.39 to 0.17 (measured link: 0.32 → 0.20). Note what the numbers admit — the ratio does not cancel amplitude perfectly, in simulation or in measurement, because the two chains' gains are only mostly common; each chain has its own analogue amplifier stages, and that per-chain mismatch survives the division (this is the answer to Concept check 1). After the ratio, the correlation between mean ratio amplitude and the AGC gain is −0.00: the gain has left the signal. A 25-packet moving average of the ratio amplitude now recovers the 0.9 Hz motion cleanly — the same average on the raw stream would only have smoothed the gain's diary.

Top: raw amplitude at one tone tracks the unobserved AGC gain (correlation 0.98 with the injected gain) — the mean level is the gain's diary, not the room, and its moving average is structureless. Bottom: the two-chain ratio cancels the common gain (correlation −0.00); the per-tone CV falls from 0.39 to 0.17 in-silico (measured: 0.32 to 0.20), and a plain 25-packet moving average now recovers the 0.9 Hz motion — averaging the raw stream would only have averaged the gain. Reproduce in Workbook §5.2.

The remaining amplitude rungs are then conventional, and they are ordered: normalise each record (so the residual scale cannot masquerade as signal), treat the band-edge roll-off from Week 2 as the static filter signature it is (either crop the shoulder tones or divide by a reference profile — never let a classifier discover the shoulders as a "feature"), and denoise the residual — discrete-wavelet thresholding and CSI-ratio-based denoising are the two families current practice converges on (yue2026_231d ).

3.3 Case study: the fingerprint era, and what broke it

History ran this experiment for us, at field scale, and it is worth telling with names and dates because Week 6 inherits the moral.

E-eyes (Wang et al., MobiCom 2014) was a pioneer of device-free activity recognition on commodity Wi-Fi: it took histograms of CSI amplitude as fingerprints of in-place activities — cooking here, washing there — and matched them with a nearest-neighbour rule. It worked, impressively, in the deployment where its fingerprints were collected. But look at the feature with Part 3 eyes: an amplitude histogram is a distribution of absolute levels — precisely the axis the AGC owns. Change the NIC, the antenna orientation, the transmit power, even refit the AGC's firmware, and the histogram moves for reasons that have nothing to do with the human. The fingerprint era's systems were, in effect, partially fingerprinting the receiver. The pattern repeated across that generation: excellent in-domain accuracy, sharp collapse under hardware or environment change — the cross-domain problem that Week 10's drift lecture returns to at full scale.

The escape, when it came, went upward in structure, exactly as §3.1 predicts. Widar3.0 (Zheng et al., MobiSys 2019) replaced fingerprints with a physically defined feature — the body-coordinate velocity profile (BVP), a distribution of signal power over body-frame velocity components derived from Doppler spectra across links — precisely so that the feature would be domain-independent by construction (zheng2019_5389 ). Note the ingredients: Doppler spectra are temporal structure computed from sanitised (conjugate-processed) phase — the survivors of this week's ladder, assembled into a feature the AGC and the oscillators cannot touch. The lab's own feature-type-not-modality line — kinematic features transfer where fingerprints break — is the same finding in our own campaigns' vocabulary.

Part 4 · The Delay-Domain Rung: Window, Then Threshold (1:05–1:17)

Several preprocessing pipelines move to the delay domain: IFFT the CFR into a channel impulse response and read multipath taps off it, as Week 2 previewed. The classic system here is Splicer (xie2015_0389 ), which built power-delay profiles precise enough to be useful on commodity cards — and could only do so after a sanitisation pipeline of exactly this week's shape: phase-error correction and amplitude power-uncertainty handling first, delay-domain reading second. Two habits separate a tap census from an artefact census.

Window before the IFFT. On a 256-tone, 80 MHz grid the delay resolution is 1/(N\,\Delta f) = 1/(256 \times 312.5\,\text{kHz}) = 12.5 ns per bin — and no physical path delay lands exactly on that grid; rooms do not consult our FFT sizes. Recall from signals-and-systems what the DFT does to an off-grid component: the finite observation window is implicitly rectangular, and a rectangular window's transform is the Dirichlet (periodic sinc) kernel, whose first sidelobe sits at −13.3 dB — a textbook constant. So an off-grid tap does not appear as one clean spike; it leaks, planting sinc sidelobes on both sides, and the workbook measures the worst one at −13.2 dB relative to the tap (in-silico; theory says −13.3 — the agreement is the point). A −13 dB ghost next to every real path looks exactly like multipath. The repair is the standard one: taper the CFR with a Hann window before the IFFT. The Hann trades main-lobe width (roughly doubled, so effective delay resolution ~25 ns) for sidelobes at −31.5 dB in theory — the workbook measures −31.6 dB — pushing the ghosts below any sane detection level.

Threshold taps at −20 dB below the peak. Below that level a census is counting the noise floor and whatever sidelobes survived, not paths. The two rules interlock, and the workbook (§5.3) demonstrates the interlock on a 3-tap channel with deliberately off-grid delays: with the rectangular window, a −20 dB threshold counts 7 "taps", because the −13.2 dB sidelobes of the strong taps clear a −20 dB bar comfortably; with the Hann window the same threshold counts exactly 3. Read the logic direction carefully: windowing is what makes the −20 dB threshold meaningful. Threshold without window and you systematically over-count multipath; window without threshold and you read the noise floor as a dense tail of "paths". Either habit alone fails; together they produce a census you can defend.

A 3-tap channel with deliberately off-grid delays. Left, no window: sinc sidelobes at −13.2 dB clear the −20 dB tap threshold and the census counts 7 taps. Right, Hann window before the IFFT: sidelobes fall to −31.6 dB and the census counts exactly the 3 true taps. Reproduce in Workbook §5.3.

The delay domain is also where this week's next rung lives — because the CIR sees things amplitude cannot.

Part 5 · The Rung Below the Ladder: Verify Your Own Parse (1:17–1:27)

Preprocessing starts one step earlier than most pipelines admit — with evidence that the bytes were parsed correctly. This lesson is first-party, and it is told here in full because the failure mode is general.

The lab's own capture stack stored the CSI tensor chain-major where the parser assumed tone-major, and the complex coefficients imaginary-first where the parser assumed real-first. Every amplitude plot looked perfect throughout — for days. Why? Because |a+bi| = |b+ai|: swapping real and imaginary parts changes a complex number but not its magnitude. Amplitude is blind to this entire class of bug by construction — not approximately blind, identically blind. The workbook confirms it to machine precision: maximum amplitude difference between the correct and swapped parse, 0.0.

What decided it was a physical invariant, and the derivation deserves the board. Reading (\mathrm{Im}, \mathrm{Re}) as (\mathrm{Re}, \mathrm{Im}) maps a + bi \mapsto b + ai = i\,(a - bi), i.e.

H \;\longmapsto\; j\,\overline{H}.

The factor j is a constant phase — it moves no energy anywhere. The conjugation is the payload: by the DFT symmetry you know from signals class, if h[n] \leftrightarrow H[k], then \overline{H[k]} \leftrightarrow \overline{h[-n]}conjugation in the frequency domain is time reversal in the delay domain. And a physical channel has an arrow of time: it is causal, its energy concentrated at small delays, because paths arrive early and decay. Time-reverse it and the energy piles up at the end of the CIR — an anti-causal channel, which nature does not build. One scalar settles the question: the ratio of early to late tap energy. On the lab's real capture the verdict read 21.3 for the correct parse against 0.48 for the swapped one (measured); the workbook reproduces the mechanism at 35.6 versus 0.74 (in-silico, §5.4). The numbers differ, the verdict cannot: an early/late ratio below 1 is not a strange room — it is a wrong parse.

The same bytes parsed two ways. Amplitude cannot tell them apart (max difference 0.0), but the CIR can: the correct parse (left) is causal with early/late tap-energy ratio 35.6, the imaginary-first swap (right) is anti-causal at 0.74. On the lab's real capture the same verdict read 21.3 vs 0.48. Reproduce in Workbook §5.4.

The general habit — and this is the oldest tradition in experimental physics, wearing DSP clothes — is instrument verification against an invariant the physics guarantees. Astronomers point new telescopes at stars they already know; you point a new parser at causality, conjugate symmetry, or a known geometry, before trusting anything downstream. The toolchain world has internalised this: PicoScenes ships in-platform calibration procedures precisely so that a multi-NIC deployment starts from verified baselines, and the Nexmon CSI line (gringoli2019_68e7 ) exposes enough of the firmware path that the community could cross-check extracted CSI against known channels. Week 3 catalogued the gotchas that corrupt a file; this rung catches the ones that corrupt your reading of a correct file. The cost is one scalar per capture-stack change. The alternative, as the lab can testify, is days of beautiful, wrong amplitude plots.

Part 6 · Scope Every Statistic: Ambient Channels Are a Mixture (1:27–1:35)

The last rung governs what you are allowed to average. A passive capture on a live channel does not deliver one homogeneous stream of records; it interleaves whatever the airspace produces. On the lab's channel-11 ambient capture, 74 % of records were legacy 52-tone and 26 % HT 56-tone (measured), from different transmitters at different power. These are different record classes: different tone counts, different tone-to-frequency maps, different modulation, different sources.

Pool them into one array — as any pipeline does that treats "the capture" as one matrix — and every statistic you compute is a mixture artefact. The workbook (§5.5) reproduces the failure with the measured class mix (drawing 72 %/28 % at this seed): zero-padding the 52-tone records to 56 fakes a band edge, and the per-tone CV at the padded tones explodes to 1.68, against 0.23 and 0.22 when each class is scoped separately (in-silico). The pooled RSSI distribution is bimodal — std 6.5 dB pooled versus 1.9 and 1.8 dB per source MAC — because it is two transmitters at two distances, not one channel plus noise. Any threshold, normalisation, or drift statistic computed on the pooled stream inherits this bimodality as a phantom effect. This is a mixture-distribution error, the same statistical sin as pooling two hospitals' patients and reporting one "average temperature" — obvious when said out loud, endemic in practice because the file format hides the class boundary.

The rule is mechanical: scope every statistic to one (n_tone, modulation) record class and one source MAC, then compute. It costs one groupby, and it is the difference between measuring the channel and measuring the traffic mix. This is also a Week 3 echo at the statistics level — there the interleaving broke the time axis, here it breaks every distribution.

An ambient capture is a mixture, not a stream. Left: the pooled RSSI histogram is bimodal (std 6.5 dB) because it contains two transmitters (1.9 / 1.8 dB each) — matching the measured ch11 mix of 74 % legacy-52 / 26 % HT-56. Right: the pooled per-tone mean invents a band edge at the zero-padded tones; scoped per class, both profiles are clean. Reproduce in Workbook §5.5.

Coda: preprocessing is moving into the protocol. Set this week against Week 4 and a direction becomes visible. In the Intel 5300 era — the CSI Tool of Halperin et al., 2011, thirty grouped subcarriers at 8 bits — everything in this lecture was the researcher's problem, solved differently in every paper, which is one reason results of that decade replicate so poorly across setups (the reproducibility theme Week 12 takes up, and the motivation behind current protocol-level proposals such as zhang2026_ccac ). The 802.11bf standard (ratified 2024, published 2025) moves part of the ladder into the protocol: scheduled sounding regularises the time axis, negotiated reporting fixes the record class — Part 6's problem, dissolved by standardisation; threshold-based reporting even standardises some change detection. But the standard stops exactly where this lecture began: it does not report the AGC gain, it does not sanitise phase, and it says nothing about calibration or drift. The oscillator physics and the dynamic-range physics do not negotiate. Whatever the protocol year, the measurement model of Part 1 — and the ladder that answers it — remains the sensing researcher's inheritance. That open gap between the standardised report and a calibrated measurement is, as Week 4 framed it, exactly where this lab's thesis work lives.

Part 7 · Recap: What You Can Now Do (1:35–1:40)

You walked in with a table of complex numbers and a promise that it lies. You leave able to say precisely how it lies, and what to do about it, in six moves:

  1. Write the measurement model \hat H_r = g\,e^{j(\phi+\beta k)}H_r + n and name every term's physical origin — two clocks that never met, a packet detector that lands where it lands, a gain loop protecting an ADC.
  2. Divide two chains and prove the common corruption cancels exactly — and insist, at capture time, on the two active RX chains that make the division possible.
  3. Refuse mean-level amplitude features, with the two-line proof of why they read the AGC, and build on the survivors: normalised shape, second-order, temporal.
  4. Window before the IFFT and threshold at −20 dB, because each habit is what makes the other meaningful.
  5. Verify a parse against physics — one causality scalar per capture-stack change buys you out of the bug class amplitude cannot see.
  6. Scope every statistic to one (n_tone, modulation) class and one source MAC before computing anything on ambient air.

Key results and where to reproduce them

In-silico values are printed by the workbook at seed 7; measured values are from the lab's first illuminated link (2026-07-27, monad01 → monad02, AX210, office) and the channel-11 ambient capture.

Result In-silico (workbook) Measured (lab) Workbook cell
Raw per-packet phase intercept circ std 2.37 rad (saturated, 3.5 rad injected) std 3.5 rad §5.1
Two-chain ratio phase circ std 0.07 rad (34x reduction) circ std 0.26 rad §5.1
Per-tone amplitude CV, raw → ratio 0.39 → 0.17 0.32 → 0.20 §5.2
corr(mean amplitude, AGC gain), raw → ratio 0.98 → −0.00 §5.2
Off-grid tap sidelobe, rect vs Hann −13.2 dB vs −31.6 dB §5.3
−20 dB tap census on 3 true taps 7 (rect) vs 3 (Hann) §5.3
Parse swap, amplitude difference 0.0 (blind) invisible in amplitude §5.4
Parse swap, early/late CIR energy ratio 35.6 vs 0.74 21.3 vs 0.48 §5.4
Ambient record-class mix (ch11) 72 %/28 % drawn 74 % legacy-52 / 26 % HT-56 §5.5
Pooled vs scoped statistics edge CV 1.68 vs 0.23/0.22; RSSI std 6.5 vs 1.9/1.8 dB RSSI bimodal by MAC §5.5

Bridge to Week 6

The ladder ends where feature engineering begins, and it has already pre-sorted the candidates. AGC killed mean-level amplitude features; the ratio and the surviving second-order and temporal structure are what Week 6 has to work with. That is not a loss — it is a filter with a direction, and the E-eyes-to-Widar3.0 arc of Part 3 is the historical proof: features built on relative, dynamical structure are precisely the ones with a chance of surviving a hardware change, while features tied to absolute levels die twice, once to the AGC and once to the next NIC. Week 6 takes the sanitised signal and asks the course's recurring question at the feature level: statistical, spectral, or learned — and which of them still work when the hardware under the model changes.

Exam-Style Questions

Q1 — The cancellation, from scratch. Starting from the measurement model \hat H_r(k,t) = g(t)\,e^{j(\phi(t)+\beta(t)k)}H_r(k,t), derive what the two-chain CSI ratio equals, stating the one physical assumption the cancellation rests on. Then explain why a capture recorded with a single RX chain cannot be repaired this way afterwards. Model answer sketch: division cancels g and the exponential exactly because neither carries a chain index — the assumption is that both chains share one oscillator, sampling clock and gain step. The result is H_1/H_2, a deterministic function of the physical channels only. A one-chain capture lacks the simultaneous second measurement under the same oscillator state; that state is never stored, so the information required for cancellation does not exist in the file — no post-hoc algorithm can recreate it.

Q2 — Reading a saturated estimator. A student computes the circular standard deviation of raw CSI phase over 600 packets and reports "2.4 rad, so the corruption is smaller than the 3.5 rad the lab measured." Correct them quantitatively. Model answer sketch: for near-uniform phase, the resultant length of N phasors random-walks to \bar R \sim 1/\sqrt{N} \approx 0.04 at N=600, so \sigma_c = \sqrt{-2\ln\bar R} \approx 2.5 rad is the estimator's ceiling, not a measurement. Any dispersion at or above wrap-around produces the same ~2.4–2.5 rad. The correct reading is "indistinguishable from uniform"; 2.4 and 3.5 are not comparable numbers.

Q3 — Feature autopsy. For each feature, state whether it survives real-NIC amplitude corruption, with a one-line reason: (a) per-packet mean |\hat H| across tones; (b) the per-packet tone vector divided by its own mean; (c) variance over time of (a); (d) the frequency of the dominant spectral peak of the ratio amplitude at one tone. Model answer sketch: (a) dies — proportional to g(t), the two-line proof of §3.1. (b) survives — g cancels in the self-normalisation. (c) dies — it is essentially the variance of the gain diary. (d) survives — the ratio cancelled the common gain, and a spectral location is invariant to residual scaling.

Q4 — The census that lied. A pipeline reports 7 multipath taps above −20 dB on a channel you know has 3. Diagnose the likely cause, explain the mechanism with the relevant window constants, and state why fixing the threshold alone cannot repair it. Model answer sketch: no window before the IFFT: off-grid taps leak Dirichlet sidelobes at −13.3 dB (workbook, in-silico: −13.2), which clear a −20 dB bar. A Hann window drops sidelobes to ≈ −31.5 dB (workbook: −31.6) and the census returns 3. Raising the threshold instead would start deleting genuine weak paths before it deletes −13 dB ghosts — the threshold is only meaningful after windowing.

Q5 — Design an instrument check. You inherit a new CSI capture stack of unknown correctness. Amplitude plots look plausible. Propose one cheap test that would catch a real/imaginary byte swap, derive why amplitude could not have caught it, and give the decision rule. Model answer sketch: amplitude is invariant because the swap maps H \mapsto j\overline H and |j\overline H| = |H|. Conjugation in frequency is time reversal in delay, so IFFT the CFR (Hann-windowed) and compute the early/late tap-energy ratio; causal physics demands ≫ 1 (lab: 21.3 correct vs 0.48 swapped). Decision rule: ratio < 1 ⇒ reject the parse, not the room.

Q6 — The pooled capture. An ambient capture yields RSSI std 6.5 dB and a per-tone CV of 1.68 at the last four tones. A colleague concludes "very dynamic channel, strong band-edge fading." Offer the alternative explanation and the one-line remedy. Model answer sketch: the capture is a mixture — two record classes (52/56-tone) from two MACs at different power; the RSSI is bimodal (per-MAC stds 1.9/1.8 dB) and the "band edge" is a zero-padding artefact (scoped CVs 0.23/0.22). Remedy: group by (n_tone, modulation) and source MAC before computing any statistic.

Further Reading

  • Yang, Zhang, Chi & Zhang 2022, Hands-on Wireless Sensing with Wi-Fi: A Tutorial (Tsinghua TNS; arXiv:2206.09532) — the anchor external source, continuing from Weeks 3–4; its Sanitization page organises the amplitude/phase ladder this lecture builds. https://tns.thss.tsinghua.edu.cn/wst/
  • Zeng et al. 2021, Boosting WiFi Sensing Performance via CSI Ratio — the CSI-ratio observable: division of two RX chains of one NIC cancels the common amplitude noise and oscillator phase offsets; includes the Möbius-transformation argument for why motion structure survives. zeng2021_1e4f
  • Wu et al. 2022, WiFi CSI-based device-free sensing: from Fresnel zone model to CSI-ratio model — why the ratio preserves motion structure: the Fresnel-zone analysis that makes the ratio a model, not just a trick; the respiration lineage lives here. wu2022_75d3
  • Ma et al. 2020, WiFi Sensing with Channel State Information — the survey treatment of phase-offset sources (CFO, STO, SFO, CSD) and linear-fit removal, including its cost to absolute delay. ma2020_4782
  • Xie et al. 2015, Precise Power Delay Profiling with Commodity WiFi (Splicer) — the sanitisation pipeline that made commodity delay profiles usable: phase-error correction, amplitude power-uncertainty handling, splicing; Part 4's habits in system form. xie2015_0389
  • Wang et al. 2015, Understanding and Modeling of WiFi Signal Based Human Activity Recognition (CARM) — the CSI-speed and CSI-activity models: the 2015 state of the art that needed clean spectral content before a clean phase observable existed, and denoised amplitude with PCA to get it. wang2015_48cf
  • Zheng et al. 2019, Zero-Effort Cross-Domain Gesture Recognition with Wi-Fi (Widar3.0) — the escape from the fingerprint era: the body-coordinate velocity profile as a domain-independent feature built entirely from this week's survivors (sanitised phase → Doppler → physical structure). zheng2019_5389
  • Diaz et al. 2023, Channel phase processing in wireless networks for human activity recognition — a systematic comparison of phase-sanitisation transforms, including the linear transformation and conjugate operations. diaz2023_7d09
  • Al-qaness et al. 2019, Channel State Information from Pure Communication to Sense and Track Human Motion: A Survey — situates the commodity-CSI line against the SDR/FMCW lineage (WiVi, WiTrack) of Part 1's interlude. alqaness2019_397d
  • Gringoli et al. 2019, Free Your CSI (Nexmon CSI) — the Broadcom firmware-patching extractor; the openness that made community cross-verification of CSI possible. gringoli2019_68e7
  • Yue et al. 2026, Deep Learning-Enhanced Human Sensing with Channel State Information: A Survey — the denoising rung in current practice: CSI-ratio-based denoising and discrete wavelet thresholding. yue2026_231d
  • Zhang et al. 2026, SDP: A Unified Protocol and Benchmarking Framework for Reproducible Wireless Sensing — the measurement model with STO/PDD, CFO and PLL terms made explicit, and why raw CSI is not comparable across devices without a normalisation protocol; Part 6's coda in proposal form. zhang2026_ccac