Skip to Content
GuidesAnalyzingMeasured MODCOD thresholds

Measured MODCOD thresholds

What you will accomplish

A link budget whose demodulation threshold is a measurement you made, with the measurement’s own confidence recorded alongside the result.

This guide extends Closing a link, which works with the default sensitivity model. Here the required Es/N0 comes from a simulated waveform instead.

Prerequisites

Steps

Measure the thresholds

orbitforge waveform thresholds \ --modcods qpsk-1/2,qpsk-3/4,8psk-3/4,16apsk-3/4 \ --frame-size normal \ --frames 20 \ --output th.json
qpsk-1/2 Normal: Es/N0 2.75 dB, eta 0.989 bit/sym, required Eb/N0 2.80 dB qpsk-3/4 Normal: Es/N0 4.00 dB, eta 1.487 bit/sym, required Eb/N0 2.28 dB 8psk-3/4 Normal: Es/N0 8.00 dB, eta 2.228 bit/sym, required Eb/N0 4.52 dB 16apsk-3/4 Normal: Es/N0 10.25 dB, eta 2.967 bit/sym, required Eb/N0 5.53 dB
orbitforge link \ --constellation ph1.json \ --station "Madrid,40.43,-3.7,0.6" \ --frequency-ghz 20 --availability 99.5 --climate-zone K \ --duration-hours 6 \ --modcod qpsk-1/2 \ --modcod-thresholds th.json \ --modcod-frame-size normal
Using simulated MODCOD threshold qpsk-1/2 (Normal): required Eb/N0 2.80 dB (Es/N0 2.75 dB, eta 0.989, 20 frames/point) Link analysis: 60 satellites, 1 stations, 6.0 h at 60 s (20.0 GHz). madrid: coverage 100.0%, 92 contacts, best margin 11.9 dB Madrid link availability: 96.717%

There is no built-in threshold table

Passing --modcod without an artifact is refused:

error: the following required arguments were not provided: --modcod-thresholds <MODCOD_THRESHOLDS>

This is the right behavior and worth pausing on. The tool ships no default MODCOD threshold table, so it cannot quietly substitute a standard figure for one you did not measure.

If you want a MODCOD-based budget, you produce the evidence for it. Compare with the drag and solar-radiation-pressure coefficients in High-fidelity runs, which are opt-in for the same reason.

Omitting --modcod entirely is still valid and uses the default sensitivity model. On the same scenario that gives a best margin of 8.7 dB and does not close at 95%, a different question with a different answer.

The default frame count is optimistic

--frames sets how many frames are simulated per Es/N0 grid point, and the help notes that confidence extends only to a packet error rate near 1/N. With the default of 20, the threshold is declared where PER falls below roughly 5 percent.

Re-measuring the same MODCOD at higher frame counts:

--framesThreshold Es/N0Required Eb/N0Wall clock
202.75 dB2.80 dB31 s
603.00 dB3.05 dB77 s
2003.25 dB3.30 dB341 s

The threshold rises monotonically and has not converged at 200 frames. Each roughly threefold increase in frames costs another 0.25 dB, which is one step of the grid_step_db search grid.

Every value is therefore a lower bound on the true threshold, and the cheap default is the most optimistic of them. A quasi-error-free threshold, at packet error rates many orders below 5 percent, sits higher still.

The direction matters more than the magnitude. An under-measured threshold makes the link look easier to close, which is the failure mode that survives review.

What half a decibel costs

Running the identical link scenario against the 20-frame and 200-frame artifacts:

Threshold artifactRequired Eb/N0Best marginAvailability
20 frames2.80 dB11.9 dB96.717%
200 frames3.30 dB11.4 dB95.216%

A 0.5 dB shift in the threshold moves availability by 1.5 percentage points. Neither meets the 99.5 percent target, so in this case the conclusion survives. It would not have to.

The margin moved by exactly the threshold shift, which is the useful sanity check: the geometry and atmosphere are unchanged, so the whole difference is the demodulation requirement.

The provenance line is the point

Using simulated MODCOD threshold qpsk-1/2 (Normal): required Eb/N0 2.80 dB (Es/N0 2.75 dB, eta 0.989, 20 frames/point)

That line names the MODCOD, the frame size, both thresholds, the spectral efficiency, and the frame count the measurement used. It is printed on every run and it is what makes the availability figure reproducible.

Copy it into whatever document quotes the availability. “We assumed QPSK 1/2” is not a reproducible statement; that line is.

The artifact itself records the same provenance:

{ "generated_by": "orbitforge waveform thresholds v0.1.0", "frames_per_point": 20, "grid_step_db": 0.25, "seed": 42 }

grid_step_db is worth noting: thresholds are quantized to a 0.25 dB search grid, so no result is meaningful to finer resolution than that regardless of how many frames you run.

Choosing a MODCOD

Higher-order schemes buy spectral efficiency for required Es/N0:

MODCODEs/N0eta, bit/symEb/N0
qpsk-1/22.75 dB0.9892.80 dB
qpsk-3/44.00 dB1.4872.28 dB
8psk-3/48.00 dB2.2284.52 dB
16apsk-3/410.25 dB2.9675.53 dB

Read the two right-hand columns together. Going from qpsk-1/2 to qpsk-3/4 costs 1.25 dB of Es/N0 and improves required Eb/N0 by 0.52 dB while carrying 50 percent more throughput, because the weaker code is more efficient per information bit at this operating point.

Going to 16apsk-3/4 triples spectral efficiency for 7.5 dB of Es/N0. Whether that trade is available is decided by the margin distribution across the pass, not by the best margin.

These thresholds are additive white Gaussian noise measurements of the demodulator alone. They exclude phase noise, non-linear amplifier distortion, adjacent-channel interference, and implementation loss.

Real receivers sit some way above them. Carry an implementation margin and state it separately, rather than folding it into the threshold where it stops being visible.

Checklist

  1. Did you measure the threshold rather than assume one?
  2. Is --frames high enough that the threshold has stopped moving?
  3. Did you record the provenance line with the result?
  4. Is the frame size in the link run the same one you measured?
  5. Is implementation margin carried separately and stated?
  6. Are you choosing the MODCOD on the margin distribution, not the best margin?

Next steps

Question? Give us feedbackDocuments Varaha Constellation Designer main (pre-release)
Last updated on