Nortek Aquadopp Coordinate Transformation
Nortek Aquadopp current profilers measure velocity along three acoustic beams.
The raw BEAM-frame data must be transformed to geographic East–North–Up (ENU)
coordinates before any oceanographic analysis. This page documents the full
two-step transformation pipeline implemented in oceanarray, the sign
conventions used, and why the specific choices were made.
The Nortek reference implementation used here is the Nortek Support article
on manual coordinate system transformation,
and the companion Python script at docs/source/_static/code/3_beam_transformation.py.
Overview
The full transformation from BEAM to ENU proceeds in two steps:
where:
\(\mathbf{T}\) is the instrument-specific transformation matrix (BEAM→XYZ), stored in the instrument’s
.hdrfile.\(\mathbf{R} = \mathbf{H} \cdot \mathbf{P}\) is the orientation matrix (XYZ→ENU), built from the compass heading, pitch, and roll recorded at each timestep, plus the local magnetic declination.
In oceanarray:
Stage 1 applies \(\mathbf{T}\) and writes
velocity_x,velocity_y,velocity_zalongside the retained beam velocitiesvelocity_beam1/2/3.Stage 3 computes the magnetic declination via IGRF (
ppigrf), builds \(\mathbf{R}\) at every timestep, and writeseast_velocity,north_velocity,up_velocity.
Step 1 — BEAM → XYZ (\(\mathbf{T}\))
The standard Nortek Aquadopp head has three beams arranged at 25° from vertical (65° from the horizontal plane). The transformation matrix \(\mathbf{T}\) maps beam velocities \((V_1, V_2, V_3)\) to the instrument’s Cartesian XYZ frame:
For a standard Aquadopp head (integer-scaled form, divide by 4096):
This matrix is instrument-specific. The values stored in the .hdr file
should always be preferred over the generic formula above.
Pointing-down orientation
When the instrument is mounted pointing downward (status bit 0 = 1), rows 2 and 3 (0-indexed: rows 1 and 2) of \(\mathbf{T}\) change sign before application:
This is controlled via the pointing_down: true key in the mooring YAML.
By default pointing_down is false (upward-looking).
Reading the T matrix from instrument files
Stage 1 parses \(\mathbf{T}\) from the instrument header:
Old format (
.hdrtext block labelled"Transformation matrix") — handled by_parse_nortek_T_matrix_hdr().New format (
.hdrorString Data.csvwithGETXFAVG,ROWS=3,COLS=3,M11=...,M33=...) — handled by_parse_nortek_T_matrix_csv().
The nine elements are stored in the dataset’s global attributes as
nortek_T_M11 … nortek_T_M33, and XYZ velocities are written as
velocity_x, velocity_y, velocity_z. The original beam velocities
(velocity_beam1/2/3) are retained for post-hoc verification.
If the header cannot be parsed, Stage 1 leaves nortek_coordinate_system
as "BEAM". Stage 3 will then skip the transformation entirely and log a
warning asking you to re-run Stage 1 with the correct header file.
There is no analytical fallback — an instrument-specific T matrix is required.
Step 2 — XYZ → ENU (\(\mathbf{R} = \mathbf{H} \cdot \mathbf{P}\))
The orientation matrix \(\mathbf{R}\) converts instrument-frame XYZ velocities to geographic ENU coordinates. It is the product of a heading matrix \(\mathbf{H}\) and a tilt matrix \(\mathbf{P}\).
This step is performed in Stage 3 because it requires the local magnetic declination, which depends on the deployment position and time.
Heading matrix \(\mathbf{H}\)
The Nortek convention defines heading as the compass bearing (clockwise from geographic North) of the instrument’s X-axis. The heading matrix is:
where \(\delta\) is the magnetic declination (positive East). The
-90° offset is an instrument-frame convention: at heading = 90° (X-axis
pointing East) with no tilt, \(h = 0°\) and \(\mathbf{H} = \mathbf{I}\),
giving X → East, Y → North, Z → Up — the standard ENU alignment.
Magnetic declination is computed at the deployment midpoint using the IGRF
model (ppigrf package):
Be, Bn, _ = ppigrf.igrf(lon, lat, 0.0, t_mid)
declination = degrees(arctan2(Be, Bn)) # positive East
Tilt matrix \(\mathbf{P}\)
Pitch (\(p\)) and roll (\(r\)) are combined into a single tilt matrix:
Combined rotation \(\mathbf{R}\)
Expanding \(\mathbf{R} = \mathbf{H} \cdot \mathbf{P}\) with \(c_h = \cos h,\; s_h = \sin h,\; c_p = \cos p,\; s_p = \sin p,\; c_r = \cos r,\; s_r = \sin r\):
where:
Sanity check (heading = 90°, no tilt): \(h = 0°\), so \(c_h = 1,\; s_h = 0\), and \(\mathbf{P} = \mathbf{I}\). Then \(E = V_x\), \(N = V_y\), \(U = V_z\) — X → East, Y → North. ✓
Sanity check (heading = 0°, no tilt): \(h = -90°\), so \(c_h = 0,\; s_h = -1\). Then \(E = -V_y\), \(N = V_x\), \(U = V_z\) — X → North. ✓
Tilt QC
Excessive instrument tilt degrades the velocity measurement. The combined tilt angle is computed from pitch \(p\) and roll \(r\):
QARTOD flags are applied by Stage 3:
\(\theta_{\text{tilt}} > 20°\) → flag 3 (suspect)
\(\theta_{\text{tilt}} > 30°\) → flag 4 (bad)
The tilt variable is also written to the per-instrument report so the flagging threshold can be visually verified.
Current speed and direction
After the ENU transform, current speed and direction are derived from the horizontal components:
Direction follows oceanographic convention (the direction toward which the current flows, measured clockwise from North).
Implementation reference
The reference Python script from Nortek Support is reproduced at
docs/source/_static/code/3_beam_transformation.py. Key excerpts:
# Heading adjustment: -90° because heading=90° aligns X with East
hdg = np.radians(heading - 90)
H = np.array([
[ np.cos(hdg), np.sin(hdg), 0],
[-np.sin(hdg), np.cos(hdg), 0],
[ 0, 0, 1]
])
P = np.array([
[ np.cos(pch), -np.sin(pch)*np.sin(rll), -np.cos(rll)*np.sin(pch)],
[ 0, np.cos(rll), -np.sin(rll)],
[ np.sin(pch), np.sin(rll)*np.cos(pch), np.cos(pch)*np.cos(rll)]
])
R = H @ P
The oceanarray implementation in stage3._xyz_to_enu() expands this
product analytically (vectorised over the time dimension) and adds the magnetic
declination offset to the heading before computing \(h\).
Configuration reference
Relevant YAML keys under each Nortek instrument entry:
Key |
Default |
Description |
|---|---|---|
|
|
Set to |
|
— |
Path (relative to the instrument folder) of the |
The magnetic declination is computed automatically from the mooring latitude, longitude, and deployment midpoint using the IGRF model; no manual entry is required.
See also
Nortek Support: How do I transform a coordinate system manually?
3. Automatic QC flagging — QARTOD flags applied to velocity after tilt QC
oceanarray.stage3._xyz_to_enu()— vectorised ENU rotationoceanarray.stage3._apply_beam_to_enu()— full BEAM/XYZ → ENU pipelineoceanarray.stage1.Stage1Processor._parse_nortek_T_matrix_hdr()— header parsing