DisclosureOS documentation · v2 Beta
Radar profiles
Validate radar source files, follow a return into a track estimate, and keep capture time separate from result availability.
A radar recording can contain sampled returns, detection decisions and track estimates. These are different products. A radar profile names their roles and checks how they connect to the capture, source files and processing steps.
This guide starts with one fictional rotating scan. You will reproduce its files, validate them, read one exact source cell and diagnose three failures. Then you can run the moving-platform, ground-processing, steered-beam and cooperative-reply examples.
Profile status
Published in npm 2.0.0-beta.4. The profile evaluators and readers are available through @disclosureos/schema/experimental/v2. The retained source revision below is only needed to regenerate this example.
Use Equipment and captures for the shared equipment model. Connect measurements links an individual observation measurement to a captured channel. The optional radar profiles instead describe complete scan products, including arrays and report tables. They compose the observation, acquisition and source-selection contracts; they do not require a claim history or the scalar measurement-binding document as inputs.
1. Open the published-package example
Requirements: Node.js 22, npm and a ZIP extractor. Create a local project and install the published API:
mkdir disclosureos-radar-beta4
cd disclosureos-radar-beta4
npm init -y
npm install --save-exact @disclosureos/schema@2.0.0-beta.4
curl --fail --location https://os.disclosure.org/examples/meridian.zip --output meridian.zip
unzip meridian.zip
curl --fail --location https://os.disclosure.org/examples/v2/radar/check-radar.mjs --output check-radar.mjs
node check-radar.mjs meridian/radar-scanning-v1The download contains the full fictional example case. This guide uses only meridian/radar-scanning-v1. Keep the terminal in this npm project for the checks below. The displayed profile and selected-value results are explained in the following sections.
2. Follow the four documents
Open the downloaded example folder. The four documents have distinct jobs:
| Document | What to inspect |
|---|---|
observation.json | Sources, products, coordinate frames and processing ancestry. A detection or track remains derived from its inputs. |
acquisition.json | Equipment, configuration, active channel, capture time and the retained raw product. |
source-selection.json | CSV columns, array axes, units, digests and exact selectors into the products. |
radar-profile.json | Which products serve as the schedule, returns, thresholds, detections, tracks, associations and optional fictional positions. |
The profile identifies the other three documents by ID. In this fixture, acquisition:radar-capture and the context's product:returns select the capture. Channel return-power belongs to its pinned configuration. The profile's products.returns selects product:returns in the observation and source layouts. Equal names do not remove the need to check those document-specific relationships.
Retained products
| File | Role in the example |
|---|---|
scan-schedule.csv | Start, end, direction and beam width for each dwell, the interval spent looking in one direction. |
returns.f32 | Relative-power samples in a [scan, azimuth, range] array: 16 × 72 × 64 cells. |
thresholds.f32 | The threshold applied to each return cell. |
detections.csv | Selected peaks, source-cell indices, measurement times and estimated positions. |
tracks.csv | Position and velocity estimates at scan end, filter state and position covariance. |
associations.csv | Which detection updated each track. |
scenario-truth.csv | Separate authored positions for comparison, excluded from detection and tracking inputs. |
track-state.csv retains the complete filter covariance for numerical reproduction. methods.json records the seed, equations and assumptions; model.mjs implements them. index.json is an example convenience index. It is not a substitute for the standard documents or their checks.
3. Validate files and read a source cell
The full reproduction above compares this specific example with its generator. The downloaded check-radar.mjs uses the installed Beta 4 package. Run it from the npm project created above.
From your npm project, run:
node check-radar.mjs \
meridian/radar-scanning-v1The script loads the four saved documents and the local files. Its core call is:
const result = await evaluateRadarProfile(
observation,
context,
selection,
profile,
{ assets },
);assets maps each source layout's productRef, such as product:returns, to the complete file bytes. It does not map filenames, URLs or cell indices. The example index locates the local files; the evaluator checks their declared byte lengths and digests. The runner reads local files only and does not fetch artifact URLs.
The first result is:
{
"success": true,
"checks": {
"structure": "passed",
"sources": "passed",
"semantics": "passed"
},
"scientific": "not_checked",
"physicalCalibration": "not_checked",
"trackingPerformance": "not_checked",
"issues": []
}| Check | Meaning |
|---|---|
structure | The four inputs satisfy their prerequisite contracts. |
sources | The source layouts have matching bytes and valid source selections. |
semantics | The radar roles, timing, geometry, detection links, associations, covariance and processing ancestry satisfy this profile. |
These are the radar evaluator's actual field names. They differ from the structural, semantic, profile and external stages in the scalar-binding guide. Do not flatten either report into a claim that the data is scientifically valid. The evaluator does not establish physical calibration or tracking performance.
After success, the script uses readProductSourceSelection to read indices [0, 9, 20]. Indices are zero-based: this is the first scan, at 45° clockwise from local north and a horizontal range-cell center of 1,025 metres.
{
"selectedReturn": {
"byteOffset": 2384,
"byteLength": 4,
"coordinates": {
"scan": 0,
"azimuth": { "value": 45, "unit": "deg" },
"range": { "value": 1025, "unit": "m" }
},
"quantity": "normalized_return_power",
"unit": "1",
"mediaDecoding": "not_applicable",
"value": 0.10780756920576096
}
}The value is dimensionless relative power. Despite the quantity name, this fixture's values can exceed 1. It is not watts, radar cross-section, probability or an identified object. The reader locates and decodes a cell; it does not authenticate a file. The script therefore validates the complete sources before reading one.
4. Diagnose a failed check
Each flag changes only in-memory inputs. Use one flag at a time. Each deliberate failure exits with status 1, leaves the generated files untouched and stops before the source-cell read. An unsupported flag or extra argument exits with usage status 2.
Withhold the return bytes
node check-radar.mjs \
meridian/radar-scanning-v1 \
--missing-returnsThe radar result has success: false, sources: failed and semantics: not_checked, with RADAR.SOURCE_CONTENT. It cannot complete the profile without the return bytes.
The additional source report leaves external: not_checked and has no source issue. Missing bytes are not contradictory bytes. Do not treat an empty issue list as a completed check; inspect the stage statuses too.
Change one byte
node check-radar.mjs \
meridian/radar-scanning-v1 \
--changed-returnsThe radar result again reports RADAR.SOURCE_CONTENT. This time, the source report has external: failed and the following issue:
{
"code": "EXTERNAL.DIGEST",
"stage": "external",
"pointer": "product:returns",
"message": "Artifact digest differs."
}The source pointer is a product reference. The bytes have the expected length but no longer match the retained digest.
Name a channel that was not captured
node check-radar.mjs \
meridian/radar-scanning-v1 \
--wrong-channelStructure passes, semantics fails and sources remain not_checked. The issue is:
{
"code": "RADAR.CHANNEL",
"pointer": "/channelId",
"message": "Return power must select an acquisition channel from its pinned manifest with matching quantity and unit."
}Here the pointer is a path in radar-profile.json. Restore the passing result by running the command without a flag. No file restoration is needed.
Processing and timing
Keep measurement time, result availability and estimate time distinct. In the rotating example, returns are sampled at dwell midpoint and available at dwell end. The detector compares neighboring directions after the complete rotation, so its detections become available at scan end. Tracks are also estimated at scan end.
A viewer can show new return cells while still displaying the previous completed scan's track estimate. Keep that older estimate's time visible. A coasting track is a prediction without an associated detection in that scan; it does not establish that an object disappeared. confirmed is a filter state after repeated updates, not verified identity.
The seeded generator, range-neighborhood threshold and constant-velocity Kalman tracker are declared in methods.json. Adjacent directions were sampled at different times. The centroid does not compensate for that scan skew, and its assumed measurement error does not prove the error has been corrected.
Choose another scenario
For these optional regeneration steps, return to the separate source checkout from step 1. All commands below run from that checkout root. Each builder writes its own generated/ directory. Each verifier compares the retained files with the generator, evaluates the appropriate profile and reads the declared source content. A successful report keeps scientific validation unchecked and calibration not performed.
The check-radar.mjs exercise above targets the fixed rotating fixture. For the other scenarios, use their verifiers below. A steered [dwell, range] array and a cooperative reply table must not be fed into the rotating array reader by relabeling them.
Moving platforms
node examples/radar-moving/build.mjs
node examples/radar-moving/verify.mjs
node --test examples/radar-moving/model.test.mjsThis produces generated/airborne/ and generated/shipborne/ beneath examples/radar-moving/. Both use RadarProfile and evaluateRadarProfile.
The optional platform declaration and products.platformPose retain position, height and heading at each dwell midpoint. A beam can be relative to local north or platform heading. Every cell in a detection neighborhood uses its own retained pose; applying one end-of-scan pose would distort the estimate. The detector's declared inputs include both pose and schedule, without ancestry from fictional positions.
- Airborne retains slant range. East/north positions depend on a declared horizontal ground plane, not a measured target height. A slant range too short to reach that plane has no plotted position.
- Shipborne uses horizontal range, a vessel changing course, other surface traffic and a fixed buoy.
The public radarCellPosition helper performs the declared coordinate conversion. The model assumes a level antenna and yaw-only rotation. It excludes pitch, roll, navigation error, terrain relief, Earth curvature and propagation. Changing from map view to platform view changes the display frame, not the retained values or times. It does not reconstruct historical relative trails.
Ground and airport surface surveillance
node examples/radar-site/build.mjs
node examples/radar-site/verify.mjs
node --test examples/radar-site/model.test.mjsThis produces generated/ground/ and generated/civilian/ beneath examples/radar-site/. Both extend the rotating profile with optional reference capture, background subtraction, detector eligibility and site-feature sources.
The ground example retains reference returns, their mean background, received returns and the background-subtracted detector input. Thresholds and peaks refer to that processed input. Subtraction produces nonnegative float32 values; it is not a Doppler filter or a calibrated clutter-rejection claim.
An eligibility mask says which cells the detector may use. A hatched cell still has a return. It is excluded from detection, not outside reception coverage or a negative observation. The profile checks declared arithmetic, selection rules and processing ancestry; it does not require this branch for every rotating recording.
The civilian example adds an authored airport-surface sketch. Runways, taxiways and aprons are context, not radar-inferred features. Track labels do not identify aircraft or vehicles. The example does not supply altitude, transponder fusion or operational clearance decisions.
Scheduled beam steering
node examples/radar-advanced/build.mjs
node examples/radar-advanced/verify.mjs
node --test examples/radar-advanced/model.test.mjsThese commands generate and verify both generated/military/ and generated/secondary/ beneath examples/radar-advanced/.
The military example uses SteeredRadarProfile with evaluateSteeredRadarProfile. It retains each beam's direction, width, purpose and start/end time. The authored sector search and revisits illustrate electronic steering, which also has civilian uses. They are not a universal military radar type or an adaptive target-priority policy.
Returns and thresholds have axes [dwell, range]. Adjacent dwell indices need not be adjacent directions. Each detection points to its actual beam and range cell; detection and track results become available at dwell end. A coasting track may mean the beam looked elsewhere. Expiry depends on elapsed time since the last detection, not dwell count. Gaps between dwells are not measurements.
Cooperative replies
The same advanced runner also verifies the secondary example, using SecondaryRadarProfile with evaluateSecondaryRadarProfile.
This packet begins with decoded replies, not raw radio-frequency pulses. It keeps interrogation windows, decoded replies and accepted reports separate. It has no reflected-power array or primary-radar detection threshold. Every accepted report refers to one valid reply; invalid replies remain inspectable and cannot become accepted reports.
Mode A codes are reported four-digit octal strings. Preserve leading zeros and do not treat the code as authenticated identity. Mode C supplies pressure altitude referenced to 1013.25 hPa, not geometric height. The display keeps slant range and bearing rather than using that altitude to invent a horizontal position.
Missing fields remain missing. A window without a reply does not establish that no object was present. Acquisition and availability times remain explicit. The example does not fuse replies into an aircraft track or implement an RF decoder, Mode S, ADS-B or IFF. Its separate fictional-position table is excluded from report selection.
Validation boundaries
Use the evaluator to check declared relationships and retained numerical consistency. Use the example's model tests for its particular detector and tracker. Neither establishes operational detection performance or physical calibration.
The plotted 95% contour comes from a declared Gaussian position model. It is conditional on the pose, projection and filter assumptions, without uncertainty in those inputs. It is not a calibrated accuracy guarantee, detection probability or confidence in identity.
The models do not implement the physical radar equation, atmospheric propagation, terrain masking or measured antenna calibration. They are not a constant-false-alarm-rate specification, an ASTERIX decoder or a representation of named operational hardware. A public byte digest identifies the retained bytes; it does not authenticate their origin.
For background on the distinction between reflected returns and cooperative replies, see FAA surveillance systems. MIT Lincoln Laboratory's tracking and parameter estimation notes explain the estimation concepts. The executable examples and limits above are defined by the pinned source, not by those operational references.
Build on the example
Use the pinned radar profile definitions and steered/secondary definitions for the exact fields. The shared equipment reference describes the capture declarations; it is not a reference for these newer radar-specific fields.
For your own integration, retain the provider's files first, declare their layouts and capture relationships, then choose the profile that fits the actual products. Compute digests from the supplied bytes. Keep reported values, derived estimates and any synthetic comparison separate. Do not copy the example's clock precision, calibration state, detector thresholds or covariance as defaults for real equipment.
A simpler radar observation can still use the shared record and instrument contracts without these optional profiles. Choose one when you need its scan-level checks, not solely because the instrument is called a radar.