Live status · Read the latest
monad-knowledge Wi-Fi sensing lab · FIIT STU

12 lessons · 48 visual steps · 2D & 3D labs

CSI, one picture at a time.

Move a number. Watch the picture. Build the formula. Start with one wave and finish by reading every value in a Wi-Fi channel record.

Companion labs in CSI from Zero

In plain words Build the idea from waves and two-number arrows to antenna links, Intel AX210 and ESP32-C5 records, and the pictures in csiscope.

Start with basic arithmetic; no prior radio theory needed. All labs use labelled synthetic data unless you paste your own values. Geometry is illustrative. No live radio is controlled and no pasted data leaves your browser. Reviewed 24 September 2026.

The complete reading edition is below. Build or enable the frontend for interactive 2D/3D labs.

Step 1 of 12

A wave is a repeating number

An antenna carries a changing electrical current. It produces an electromagnetic field; a receiving antenna converts part of that field back into a voltage. A sine wave is the simplest description of one repeating component.

A graph needs a horizontal variable and a vertical quantity. Here the horizontal axis is time and the vertical axis is a normalized voltage. The height is amplitude A. Frequency f counts cycles per second (hertz). Phase φ tells us where in the cycle we start. One turn is 360° or 2π radians; π radians is half a turn.

A real radio oscillates billions of times per second. This figure is deliberately slowed to a few cycles so you can see it. A time plot is not a picture of a wiggly trajectory through the room. In space the wavelength is λ = c/f; c = 299,792,458 m/s in vacuum. Indoor propagation also involves materials, reflections and antenna patterns.

v(t) = A cos(2π f t + φ)     T = 1/f     λ = c/f

Try it in the lab. Change amplitude, then phase, then frequency. Which control changes the number of cycles, and which only moves the peaks?

Worked example
A = 1, f = 1 Hz, φ = 0°: v(0) = 1, v(0.25 s) = 0, v(0.5 s) = −1. A 5.2 GHz wave has λ ≈ 5.77 cm.
Amplitude changes height; phase moves peaks; frequency changes how many cycles fit. The vertical scale is normalized, not volts measured from hardware. Sources: survey
Is a negative voltage a negative amount of received power?

No. Voltage changes sign each half-cycle. Power depends on squared magnitude and impedance, not the voltage's sign.

Step 2 of 12

Two coordinates describe one wave

A complex number is a pair of real numbers with useful arithmetic. Draw I horizontally and Q vertically. The arrow from zero to (I,Q) has a length and an angle.

Write H = I + jQ, with j² = −1. The word imaginary names the vertical coordinate; it does not mean the measurement is imaginary. Pythagoras gives the length √(I²+Q²). atan2(Q,I) finds the angle while keeping the correct quadrant. At (0,0), the angle is undefined.

Euler's identity, e^(jφ) = cos φ + j sin φ, gives the same number in polar form A e^(jφ). Its real rotating projection is I cos(2πft) − Q sin(2πft). I and Q are two coefficients for one waveform, not two antennas, packets or people. The 3D helix adds time as a third mathematical axis; it is not the spatial path of the radio wave.

H = I + jQ = |H| e^(jφ)     |H| = √(I²+Q²)     φ = atan2(Q,I)

Try it in the lab. Set I = 3 and Q = 4. Read the 5-unit arrow. Switch to 3D, rotate it, and follow the same complex number through time.

Worked example
3 + j4 = 5 exp(j·0.9273). Phase = 53.130°. −3 + j4 has the same magnitude and phase 126.870°.
The point and polar coordinates are two representations of the same value. The dashed circle has the arrow's radius. Sources: survey
Why can amplitude alone not recover the original pair?

Every point on a circle has the same amplitude. You also need the angle to distinguish them.

Step 3 of 12

A channel scales and rotates

Send a known complex symbol X through a channel H. In a simple, narrowband, noiseless model, the received symbol is Y = HX. Complex multiplication multiplies lengths and adds angles.

H is the channel's effect, X is what was sent, and Y is what arrived. They are different quantities even though all three can be complex numbers. A CSI coefficient is an estimate of H, not a payload bit, an instantaneous antenna voltage, or a location.

One coefficient works for a frequency narrow enough that the channel is approximately constant over it. Wi-Fi uses many such frequencies. Real reception also has noise and interference: Y = HX + N. If H is nearly zero, dividing by it strongly amplifies the noise. A deep fade is therefore difficult to equalize.

Y = H X + N     |HX| = |H| |X|     arg(HX) = arg(H) + arg(X)

Try it in the lab. Rotate H by 90° and reduce its amplitude. Watch X stay fixed while Y moves. Then make the gain approach zero.

Worked example
X = 1 + j0; H = 0.6 + j0.8; Y = 0.6 + j0.8. The channel has unit gain and rotates by 53.130°.
The blue arrow is the sent symbol and the orange arrow is the received symbol, in a noiseless teaching model. Sources: survey
If Y changes, must the room have changed?

No. X may have changed, and noise, gain control, interference or oscillator errors can change Y too. Estimating H requires a known reference.

Step 4 of 12

Known training symbols reveal H

The receiver cannot infer both an unknown message and an unknown channel from one received value. Wi-Fi packets carry known training fields. The receiver compares what should have arrived with what did arrive.

For a nonzero known training symbol Xₖ, the simplest least-squares estimate is Ĥₖ = Yₖ/Xₖ. Repeated training can be combined to reduce noise. In MIMO, training across streams allows a matrix estimate; it is not independent division of an arbitrary mixture.

The packet path is: antenna → RF filtering and amplification → downconversion into I/Q → sampling → timing/frequency synchronization → FFT → training-field channel estimate → equalization and decoding. CSI extraction exposes an internal estimate. The training field, packet PHY, firmware and capture configuration determine what is exported. Later pilots can track residual phase errors; they are not extra antennas.

Ĥ = (Σ X*Y)/(Σ |X|²)     for one X: Ĥ = Y/X

Try it in the lab. Increase the deterministic noise amplitude and then the number of known training symbols. Compare the estimate with the planted channel.

Worked example
X = j, H = 0.6 + j0.8 gives Y = −0.8 + j0.6. Dividing Y by j returns 0.6 + j0.8.
Blue marks the planted H; orange marks the least-squares estimate from the displayed synthetic training observations. This one seeded example is not a statistical accuracy claim. Sources: survey esp
Is CSI something a receiver can produce when nobody sends a usable packet?

No packet-derived channel estimate exists for an interval with no usable received training. Missing CSI is not a measured zero channel.

Step 5 of 12

A vector samples the channel across frequency

A Wi-Fi channel contains many closely spaced subcarriers. They add into one transmitted waveform. After an FFT, the receiver estimates a complex gain at each reported frequency.

An index i is a position in an array. A subcarrier number k is a signed FFT-bin coordinate relative to the RF center f꜀. The physical frequency is fₖ = f꜀ + kΔf. Negative k means below the center, not negative radio frequency. The center (DC) and guard tones are not ordinary transmitted data tones. Pilots are known symbols on active tones.

With useful OFDM symbol duration Tᵤ, Δf = 1/Tᵤ. Legacy/HT/VHT use 312.5 kHz; HE uses 78.125 kHz. HE has denser sampling at the same bandwidth. That does not by itself improve delay resolution: bandwidth, not the number of stored coefficients alone, sets that scale. Arrays may omit nulls, include them, group tones, or contain several training fields. Always read metadata.

H = [H[k₀], H[k₁], …]     fₖ = f꜀ + kΔf     Δf = 1/Tᵤ

Try it in the lab. Switch between 52 used legacy tones, 242 used HE20 tones, and the C5's 53-entry L-LTF. Select an array position and locate its real frequency.

Worked example
Legacy 20 MHz: k = −26…−1, +1…+26. There are 52 used tones and a DC gap. k = −26 is −8.125 MHz from center.
These are declared 20 MHz profile grids. The C5 plot is sorted by frequency for reading; its raw SDK array begins at DC. The inspector preserves raw storage order. Sources: esp format
Does entry 26 always mean the center frequency?

No. It depends on the grid and ordering. In a sorted 52-tone array entry 26 is k = +1; in the raw C5 L-LTF array entry 0 is DC.

Step 6 of 12

Every coefficient adds many physical paths

The receiver hears a direct path plus reflected, scattered and diffracted copies. A longer path arrives later. At a given frequency, those copies add as complex arrows.

A path with delay τ contributes a phase −2πfτ and a complex amplitude a. Sum all paths to get H(f). A tiny movement can alter their relative phases; two strong paths may cancel. A lower amplitude therefore does not uniquely mean a person blocked the direct line. A person can change both amplitudes and delays, and can affect links without standing on their straight line.

The lab uses one direct ray and one floor-reflected ray in an authored room, with a chosen echo gain. Heights and lengths are in metres. The mirror construction gives the specular reflection point. It omits diffraction, wall materials, antenna patterns and multiple bounces. The direct path's common delay is removed, leaving relative phase. Drag the 3D view or switch to plan view; moving the receiver changes the same model in both.

H(f) = Σ aₗ exp(−j2πfτₗ)     τₗ = path lengthₗ/c

Try it in the lab. Move the receiver height by a few centimetres. Watch the path difference and the selected tone change. Then set echo gain to zero.

Worked example
Two unit arrows separated by 0° sum to amplitude 2; at 180° they sum to zero. Neither individual path disappeared.
The room geometry changes path length, which changes interference. Synthetic geometry and arbitrary normalized path gains, not a prediction for the library. Sources: survey
Can one complex coefficient tell us where all the reflectors are?

No. Many collections of paths give the same sum. Localization needs more independent information, assumptions and calibration.

Step 7 of 12

Antennas add a spatial dimension

Each receive antenna samples the field at a different position and polarization. Each distinguishable transmit stream can have a different effective channel to it. At one frequency, collect these links into a matrix.

In an ideal physical-antenna basis, Yᵣ = Σₛ HᵣₛXₛ + Nᵣ. A 2×2 channel has four complex coefficients per tone. Stack K tones and P packets to obtain H[packet, receive, transmit, tone]. Software can transpose or flatten this tensor without changing the physics. The project's analysis view is [record, tone, chain], where chain = rx·ntx + tx.

A transmitter may map spatial streams through precoding or cyclic shifts. Exported CSI can then be an effective stream channel rather than a separately calibrated physical antenna channel. The AX210 has two receive/transmit chains, but a one-stream packet does not automatically yield a measured 2×2 matrix. Use nrx, ntx and validity from the record. Switched antennas on a single RF chain are not simultaneous MIMO.

Mount antennas rigidly; document cable/connector, spacing, orientation, polarization, height and band. Half-wavelength spacing is an array-design scale, not a guarantee of angle estimation. Phase differences also contain cable and hardware offsets and multipath. Moving an antenna or touching its cable changes the instrument. Two disconnected receivers do not automatically share a phase reference.

Y[k] = H[k] X[k] + N[k]     chain = rx·Ntx + tx

Try it in the lab. Select a receive antenna, a transmit stream and a tone. Follow the highlighted matrix cell and the flattened chain index.

Worked example
2 RX × 1 TX × 52 tones = 104 complex numbers = 208 signed scalar words. At two bytes per word, the AX210 CSI payload occupies 416 bytes, before framing.
A synthetic 2×2 channel illustrates indexing. Colors encode gain, not a measured radiation pattern or an angle estimate. Sources: survey intel format
Are I and Q the two channels of a 2×2 radio?

No. Every complex channel coefficient has both I and Q. A 2×2 channel can have four coefficients per tone, each with its own pair.

Step 8 of 12

Read every number in a vendor vector

The physics is shared; storage conventions are not. Choose an explicit profile, then inspect one coefficient from a synthetic payload or paste your own signed scalar words. Everything stays in this browser.

The AX210/iax CSIQ profile stores contiguous chain blocks. Each coefficient is a little-endian signed 16-bit imaginary word followed by a real word. Its payload byte offset is 4·(chain·K + i). File headers and TLV headers are outside this offset. The C5 L-LTF SDK profile has 53 signed 8-bit pairs ordered k = 0…26, −26…−1. The DC entry is not a channel measurement. Plotting can reorder it, but storage position and k must remain distinguishable.

Select the profile that actually matches the recording. C5 HT/VHT20 and HE20 SU grids can contain 57 and 245 entries including nulls; STBC, MU, bandwidth and LTF acquisition settings need their own interpretation. This lab intentionally accepts only one legacy C5 L-LTF block, or the stated AX210 used-tone blocks. It does not guess an unknown packet format from vector length.

Before using an AX210 chain, check the record's measured-chain mask: parsed RSSI −127 dBm marks a stale unmeasured block. C5 ESP-IDF v6.0 documents rx_channel_estimate_info_vld; consult the exact SDK, rather than borrowing first_word_invalid rules from another ESP32. This inspector has no packet header and cannot validate those flags. It explains numbers, not capture integrity. Raw amplitudes from different vendors have no common calibrated power scale.

H = real + j·imag     word offset = 2(chain·K+i)     byte offset = word offset·word size

Try it in the lab. Inspect the pair [4,3]. Then enable the deliberate I/Q mistake: its magnitude stays 5 but its phase changes. Paste a matching complete payload to inspect your own values.

Worked example
Imaginary-first words [4,3] mean H = 3+j4, magnitude 5, phase 53.130°. Misreading them as real-first gives 4+j3 and 36.870°.
The table connects storage position, subcarrier, chain, I/Q, magnitude and phase. A null or zero has no valid channel phase. No payload is uploaded. Sources: esp format
Why did an I/Q bug survive an amplitude-only plot?

Swapping I and Q maps H to j·conj(H). The magnitude is identical, but the phase becomes π/2 minus the original phase.

Step 9 of 12

Measured phase includes the receiver

A radio's clock is not perfectly synchronized to the other radio. The reported phase includes propagation, a common phase rotation and a slope across frequency, as well as noise and hardware effects.

Phase wraps at ±π: a jump from +179° to −179° is a 2° change. Unwrapping chooses a continuous sequence by adding whole turns; it cannot recover arbitrary delays or fix missing data. A simplified impairment model adds α per packet and βk across subcarriers. CFO contributes evolving common phase; sufficiently large CFO also creates intercarrier interference, beyond this simple model. Timing and sampling offsets contribute slope.

Sanitizing by subtracting a fitted line removes the common offset and slope, but also removes genuinely linear channel phase. A clean residual is not absolute propagation delay. A same-packet ratio Hₐ/Hᵦ or conjugate product HₐHᵦ* can cancel shared phase errors. Chain-specific errors remain; a ratio becomes unstable when its denominator is near zero. Separate ESP receivers do not share those errors just because they hear the same AP.

φmeasured(k,p) ≈ φchannel(k,p) + α(p) + β(p)k     arg(HₐHᵦ*) = φₐ − φᵦ

Try it in the lab. Add common rotation and timing slope. Compare wrapped, unwrapped and detrended views. Notice that removing slope also erases the planted physical delay.

Worked example
A physical delay of 20 ns gives a slope −2π·312,500·20×10⁻⁹ = −0.03927 rad per legacy subcarrier, indistinguishable from a timing slope in this model.
Known synthetic channel phase is shown beside impaired phase. Detrending deliberately loses a physical linear component; it is not calibration. Sources: survey scope
Can sanitized phase alone tell us the transmitter is six metres away?

No. Fitting out the line removes delay information, and packet timing, multipath and hardware phase make uncalibrated absolute ranging ambiguous.

Step 10 of 12

A waterfall is a stack of packet spectra

One packet supplies one frequency response. Repeat the measurement and stack the rows. A waterfall turns amplitude into color so you can see which frequencies change at which times.

The horizontal axis is subcarrier frequency offset in MHz; the vertical axis is elapsed time in seconds. Each colored cell represents one time and one frequency. The color is 20 log₁₀|H| relative to a stated amplitude reference, not dBm. A 3D surface shows the same values with height as an additional encoding. It is not a 3D scan of the room.

Here one echo rotates slowly while a static path remains. This makes time-varying interference even though the transmitter's data symbols are not plotted. Set motion frequency to zero for a static channel. Real rows arrive at packet times, not at a guaranteed rate. Scope by record class and transmitter before interpreting a stripe; changing packet types, transmitters, gain settings or missing records can create apparent motion.

A[p,k] = 20 log₁₀(|H[p,k]| / reference amplitude)

Try it in the lab. Switch 2D to 3D and select a packet. The orange spectrum below must match that exact row. Freeze motion at 0 Hz.

Worked example
|H| = 2 relative to reference 1 gives +6.0206 dB. |H| = 0.5 gives −6.0206 dB. Neither value is an absolute received power.
The heatmap, 3D surface and selected spectrum all use the same synthetic coefficients and fixed color scale. A blank DC column means no measurement. Sources: scope format
Is a wide spectrum bundle a confidence interval for the number of people?

No. A p05–p95 bundle summarizes the distribution of channel amplitudes over its window. It is neither a headcount nor a confidence interval for one.

Step 11 of 12

Frequency structure becomes a delay profile

The inverse Fourier transform combines frequencies into a delay-domain description. A delayed path produces a phase slope across frequency; combining those slopes creates a peak near its delay.

The ideal channel impulse response h(τ) is a sum of delayed path contributions. The finite measured band blurs each path into a lobe. The lab uses an ideal contiguous frequency grid to isolate this idea. It applies a Hann window and computes a zero-padded inverse transform. Increasing zero padding makes the curve smoother without resolving closer physical paths.

The delay resolution scale is about 1/B for observed bandwidth B; windowing widens the main lobe. At 20 MHz, 1/B = 50 ns, about 15 m of path length cτ, not 15 m of guaranteed location accuracy. Active-tone bandwidth is smaller than nominal bandwidth. csiscope uses a Hann-windowed IFFT, and its legacy contiguous-tone approximation and packet timing offsets preclude interpreting an absolute peak as calibrated range. An uncalibrated peak shift can be receiver timing.

h[n] = IFFT{W[k]H[k]}     PDP[n] = |h[n]|²     delay scale ≈ 1/B

Try it in the lab. Try echoes 20 ns apart, then 150 ns apart. Increase bandwidth, then padding. Only bandwidth changes the underlying ability to separate delays.

Worked example
At B = 20 MHz, 1/B = 50 ns. At B = 80 MHz, 1/B = 12.5 ns. Fourfold padding only adds display samples between existing delay bins.
An ideal full-grid two-path example, with direct-path timing anchored by construction. The console's sparse tone handling and timing errors are not simulated here. Sources: survey scope
Does a 1 ns interpolated delay-bin spacing mean 30 cm ranging resolution?

No. Bin spacing can be made small by padding. Physical bandwidth, windowing, SNR, synchronization and the estimation method govern distinguishability and ranging accuracy.

Step 12 of 12

Doppler is change across packets

Subcarrier frequency describes where we listen within the radio channel. Doppler frequency describes how a channel coefficient evolves over time. These are two different Fourier axes.

For one path with changing length L(t), phase is −2πL/λ. The signed Doppler shift is fᴅ = −(1/λ)dL/dt under this convention. Bistatic motion changes transmitter-to-object plus object-to-receiver length. The sign and magnitude depend on geometry; speed is not universally λfᴅ/2. Tangential movement can have little instantaneous Doppler.

Sample at fₛ packets per second and an ideal uniformly sampled complex signal is ambiguous outside ±fₛ/2. The lab plots the true slow-time sinusoid and the indistinguishable aliased reconstruction through its samples. csiscope's spectrogram uses an STFT of a two-chain conjugate product. Its hertz axis also depends on real arrival times, missing slots and resampling. Check the metronome and arrivals before calling a ridge motion; a packet cadence can create a ridge too.

fᴅ = −(1/λ)dL/dt     unaliased interval: −fₛ/2 ≤ fᴅ < fₛ/2

Try it in the lab. Use 12 Hz channel change at 20 packets/s: it aliases to −8 Hz. Raise the delivered sampling rate. Changing the RF carrier is a different operation.

Worked example
12 Hz sampled at 20 Hz is indistinguishable from −8 Hz. At 50 Hz, 12 Hz lies within the ±25 Hz Nyquist interval.
Uniform complex samples alias modulo the packet rate. Real dropouts, clock errors and irregular arrivals make the inference harder than this ideal demonstration. Sources: scope survey
A Doppler ridge appears at the beacon repetition rate. Is it a walking speed?

Not without checking arrivals and the analysis path. Periodic sampling or traffic can create structure unrelated to a moving reflector.

From the model to the instrument

Read csiscope in this order

First verify capture delivery and measured-chain validity. Then choose one record class, transmitter and time window. Read spectrum and RSSI before interpreting phase, delay or Doppler. A changing channel is evidence of change in the complete radio link; attributing it to a person requires controls and ground truth.

Axes, meaning, and the first interpretation to check
PanelWhat you seeWhat to check
Capture / yieldRecords divided by observed frames; useful yield excludes empty records.A low yield is not silence. Check packet PHY and extractor eligibility.
Class + transmitter scopeOne tone geometry and one source within a chosen window.A mixture can change its spectrum even if every individual link is static.
Spectrum & bundleFrequency → relative amplitude; current trace and p05–p95 envelope.Width describes channel variability, not a calibrated headcount or confidence interval.
WaterfallFrequency × packet time → relative amplitude color.Check the color scale, null mask, dropped-row counters and actual clock.
Complex planeReal versus imaginary part, indexed by tone.A loop is frequency structure, not a floor plan. A rotation can be hardware phase.
PhaseFrequency → wrapped, unwrapped or line-detrended phase.A smooth residual does not preserve absolute delay or establish synchronization.
CSI ratio / chainsCompare simultaneous measured chain responses.Reject stale chains; ratios near a denominator null are unstable; matching chains can indicate a parser fault.
Impulse responseApparent delay → windowed power.Window, occupied bandwidth, missing tones and packet timing affect the peaks. Do not read them as room coordinates.
DopplerSlow time × temporal frequency → spectral energy.Check metronome: on-grid, deferred or irregular. Delivered rate matters; commanded rate is not evidence of delivery.
RSSIPer-chain strength field, with the convention printed by that view.Parsed CSIQ uses negative dBm; raw iax fields use a positive magnitude. Verify the label and parser before applying a sign. |H| is AGC-relative.
Extraction / tone statisticsNull fraction, identical-chain checks, edge behavior and temporal spread.A suspicious tone is first an extraction or interference question, not an occupancy event.
Arrivals / clocksInter-packet gaps and clock disagreement.AX210 FTM ticks at 320 MHz wrap and must be unwrapped; wallclock anchors dates. C5 timestamps are a different clock.

Before trusting a deployment

  1. Document transmitter, receiver and antenna positions, heights, orientation, cables, band, channel and bandwidth. Record which spatial streams and training fields are actually exported.
  2. Fix one transmitter and record class. Keep real packet timestamps and validity flags. Separate absent records, null tones, all-zero payloads and stale chains.
  3. Record a stable baseline after radio warm-up, then a controlled change with timing and ground truth. Keep a quiet comparison link or period. A changed antenna mount is a changed instrument.
  4. Check delivery and timing before choosing a Doppler window; retain gaps. For slow baseline comparisons, the project's drift workflow excludes the initial 30-minute settling window. That is a workflow convention, not a universal hardware constant.
  5. Compare relative CSI shape within a stable configuration. Use the correctly interpreted RSSI field for absolute strength. Calibrated ranging, angle estimation and headcounts require additional models and validation.

Your final explanation

Try explaining a single vector entry aloud: “In packet p, for receive chain r and transmit stream s, this array position maps to subcarrier k at f꜀ + kΔf. The stored pair decodes to I + jQ. Its magnitude describes relative gain and its angle describes phase, both affected by the measurement chain. It adds all propagation paths at that frequency.” Then explain why one entry cannot reveal a person's position or a number of people.

Sources and companion labs

The corpus supports the channel model and phase limitations. Vendor byte layouts come from the explicit SDK and capture specifications below; a generic ESP32 paper does not establish the C5 layout. The labs are mathematical demonstrations, not a performance comparison between devices.

  1. Ma et al., WiFi Sensing with Channel State Information (2020)

    Corpus: [[WiFi Sensing with Channel State Information|ma2020_4782]]. Channel matrices, multipath and phase offsets; not a C5 format specification.

  2. Espressif: ESP32-C5 CSI, ESP-IDF v6.0

    C5-specific acquisition, signed I/Q, LTF order, nulls and validity. Match the SDK and configuration that produced your record.

  3. Intel AX210 product specification

    2×2 hardware and supported bands. CSI export details come from the capture stack, not this product sheet.

  4. The project's CSIQ format workbench

    Local authority: csid/docs/CSIQ-format-v1.md, CSI_MATRIX and clocks sections. Inspect committed real captures here after the synthetic exercises.

  5. A real channel record, in the Toolbox

    Console grounding: csid/docs/dashboard.md and crates/csiscope. The course reproduces the meaning of views, not the live console or its complete DSP.

Continue with real channel records and the capture byte workbench. Use Signals, up close for QAM and OFDM waveform exercises, Wi-Fi standards for generation capabilities, and Three bands, one room for carrier and bandwidth comparisons.