Skip to content

Commit

Permalink
Update parsers for Signature Nortek ADCP to support SRS files:
Browse files Browse the repository at this point in the history
* Update readAD2CPBinary to Nortek Signature Integration manual 2017.
* Add support to new data records such as: Burst Altimiter Raw, DVL Bottom Track, Altimiter, Avg Altimiter Raw.
* Beam coordinate system information is being parsed.
* Similar data records (same type, same config) are being grouped together in the same dataset across programmed modes.
* Added following diagnostic parameters: AmbiguityVel, TransmitEnergy, NominalCorrelation, Error.
* Add support to velocity in BEAM coordinates.
* Add support to Altimeter LE and AST parameters.
* Update support of .mat files so that result is consistent with .ad2cp files. Support Alt_Average and Alt_Burst programmed modes.
* Generate as many datasets/NetCDF files as there is different programmed modes.
* Add burst metadata in global attributes.
  • Loading branch information
ggalibert committed Nov 6, 2017
1 parent 46ed41f commit 223a933
Show file tree
Hide file tree
Showing 11 changed files with 746 additions and 260 deletions.
1 change: 1 addition & 0 deletions Graph/TimeSeries/parameters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ NORTEK_QC, TimeDepth
VEL1, TimeDepth
VEL2, TimeDepth
VEL3, TimeDepth
VEL4, TimeDepth
VDEN, TimeFrequency
VDEV, TimeFrequency
VDEP, TimeFrequency
Expand Down
2 changes: 1 addition & 1 deletion Graph/TimeSeries/setTimeSerieColorbarContextMenu.m
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
end

switch upper(var.name(1:4))
case {'UCUR', 'VCUR', 'WCUR', 'ECUR', 'VEL1', 'VEL2', 'VEL3'} % 0 centred parameters
case {'UCUR', 'VCUR', 'WCUR', 'ECUR', 'VEL1', 'VEL2', 'VEL3', 'VEL4'} % 0 centred parameters
colormap(r_b);
cbCLimRange('', '', 'auto, 0 centred', var.data);

Expand Down
2 changes: 1 addition & 1 deletion Graph/diagramMooring1DVarAgainstOther.m
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ function diagramMooring1DVarAgainstOther(sample_data, varName, yAxisVarName, isQ
if iVar && iYAxisVar && ...
size(sample_data{iSort(i)}.variables{iVar}.data, 2) == 1 && ...
size(sample_data{iSort(i)}.variables{iYAxisVar}.data, 2) == 1 && ... % we're only plotting 1D variables with depth variable but no current
all(~strncmpi(sample_data{iSort(i)}.variables{iVar}.name, {'UCUR', 'VCUR', 'WCUR', 'CDIR', 'CSPD', 'VEL1', 'VEL2', 'VEL3'}, 4))
all(~strncmpi(sample_data{iSort(i)}.variables{iVar}.name, {'UCUR', 'VCUR', 'WCUR', 'CDIR', 'CSPD', 'VEL1', 'VEL2', 'VEL3', 'VEL4'}, 4))
iGood = true(size(sample_data{iSort(i)}.variables{iVar}.data));
if isQC
%get time, depth and var QC information
Expand Down
2 changes: 1 addition & 1 deletion Graph/diagramMooring2DVarAgainstOther.m
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ function diagramMooring2DVarAgainstOther(sample_data, varName, yAxisVarName, isQ
end

elseif iVar && iYAxisVar && ...
any(strncmpi(sample_data{iSort(i)}.variables{iVar}.name, {'UCUR', 'VCUR', 'WCUR', 'CDIR', 'CSPD', 'VEL1', 'VEL2', 'VEL3'}, 4)) && ...
any(strncmpi(sample_data{iSort(i)}.variables{iVar}.name, {'UCUR', 'VCUR', 'WCUR', 'CDIR', 'CSPD', 'VEL1', 'VEL2', 'VEL3', 'VEL4'}, 4)) && ...
size(sample_data{iSort(i)}.variables{iVar}.data, 2) == 1 % we're plotting current metre 1D variables with DEPTH variable.
iGood = true(size(sample_data{iSort(i)}.variables{iVar}.data));
if isQC
Expand Down
2 changes: 1 addition & 1 deletion Graph/lineMooring1DVar.m
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ function lineMooring1DVar(sample_data, varName, isQC, saveToFile, exportDir)
iVar = getVar(sample_data{iSort(i)}.(typeVar), varName);

if iVar > 0 && size(sample_data{iSort(i)}.(typeVar){iVar}.data, 2) == 1 && ... % we're only plotting 1D variables but no current
all(~strncmpi(sample_data{iSort(i)}.(typeVar){iVar}.name, {'UCUR', 'VCUR', 'WCUR', 'CDIR', 'CSPD', 'VEL1', 'VEL2', 'VEL3'}, 4))
all(~strncmpi(sample_data{iSort(i)}.(typeVar){iVar}.name, {'UCUR', 'VCUR', 'WCUR', 'CDIR', 'CSPD', 'VEL1', 'VEL2', 'VEL3', 'VEL4'}, 4))
if initiateFigure
fileName = genIMOSFileName(sample_data{iSort(i)}, 'png');
visible = 'on';
Expand Down
2 changes: 1 addition & 1 deletion Graph/pcolorMooring2DVar.m
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ function pcolorMooring2DVar(sample_data, varName, isQC, saveToFile, exportDir)
instrumentDesc{i} = [strrep(instrumentDesc{i}, '_', ' ') ' (' num2str(metaDepth(i)) 'm' instrumentSN ')'];

switch varName(1:4)
case {'UCUR', 'VCUR', 'WCUR', 'VEL1', 'VEL2', 'VEL3'} % 0 centred parameters
case {'UCUR', 'VCUR', 'WCUR', 'VEL1', 'VEL2', 'VEL3', 'VEL4'} % 0 centred parameters
cMap = 'r_b';
cType = 'centeredOnZero';
case {'CDIR', 'SSWD'} % directions [0; 360[
Expand Down
2 changes: 1 addition & 1 deletion Graph/scatterMooring1DVarAgainstDepth.m
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ function scatterMooring1DVarAgainstDepth(sample_data, varName, isQC, saveToFile,
iVar = getVar(sample_data{iSort(i)}.variables, varName);

if iVar > 0 && size(sample_data{iSort(i)}.variables{iVar}.data, 2) == 1 && ... % we're only plotting 1D variables with depth variable but no current
all(~strncmpi(sample_data{iSort(i)}.variables{iVar}.name, {'UCUR', 'VCUR', 'WCUR', 'CDIR', 'CSPD', 'VEL1', 'VEL2', 'VEL3'}, 4))
all(~strncmpi(sample_data{iSort(i)}.variables{iVar}.name, {'UCUR', 'VCUR', 'WCUR', 'CDIR', 'CSPD', 'VEL1', 'VEL2', 'VEL3', 'VEL4'}, 4))
iGood = true(size(sample_data{iSort(i)}.variables{iVar}.data));
if isQC
%get time, depth and var QC information
Expand Down
4 changes: 2 additions & 2 deletions Graph/scatterMooring2DVarAgainstDepth.m
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ function scatterMooring2DVarAgainstDepth(sample_data, varName, isQC, saveToFile,
end

elseif iVar > 0 && ...
any(strncmpi(sample_data{iSort(i)}.variables{iVar}.name, {'UCUR', 'VCUR', 'WCUR', 'CDIR', 'CSPD', 'VEL1', 'VEL2', 'VEL3'}, 4)) && ...
any(strncmpi(sample_data{iSort(i)}.variables{iVar}.name, {'UCUR', 'VCUR', 'WCUR', 'CDIR', 'CSPD', 'VEL1', 'VEL2', 'VEL3', 'VEL4'}, 4)) && ...
size(sample_data{iSort(i)}.variables{iVar}.data, 2) == 1 % we're plotting current metre 1D variables with DEPTH variable.
iGood = true(size(sample_data{iSort(i)}.variables{iVar}.data));
if isQC
Expand Down Expand Up @@ -182,7 +182,7 @@ function scatterMooring2DVarAgainstDepth(sample_data, varName, isQC, saveToFile,

% define cMap, cLim and cType per parameter
switch varName(1:4)
case {'UCUR', 'VCUR', 'WCUR', 'ECUR', 'VEL1', 'VEL2', 'VEL3'} % 0 centred parameters
case {'UCUR', 'VCUR', 'WCUR', 'ECUR', 'VEL1', 'VEL2', 'VEL3', 'VEL4'} % 0 centred parameters
cMap = 'r_b';
cType = 'centeredOnZero';
CLim = [-max(abs(yLimMin), abs(yLimMax)) max(abs(yLimMax), abs(yLimMin))];
Expand Down
1 change: 1 addition & 0 deletions IMOS/imosParameters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ VDIRT, 1, sea_surface_wave_to_direction,
VEL1, 0, sea_water_velocity_from_acoustic_beam_1, m s-1, , , V, 999999.0, -10.0, 10.0, float
VEL2, 0, sea_water_velocity_from_acoustic_beam_2, m s-1, , , V, 999999.0, -10.0, 10.0, float
VEL3, 0, sea_water_velocity_from_acoustic_beam_3, m s-1, , , V, 999999.0, -10.0, 10.0, float
VEL4, 0, sea_water_velocity_from_acoustic_beam_4, m s-1, , , V, 999999.0, -10.0, 10.0, float
VOLT, 0, voltage, V, , , E, 999999.0, -100.0, 100.0, float
VSF412, 0, volume_scattering_function_of_radiative_flux_in_sea_water_for_wavelength_412nm, m-1 sr-1, , , E, 999999.0, , , float
VSF440, 0, volume_scattering_function_of_radiative_flux_in_sea_water_for_wavelength_440nm, m-1 sr-1, , , E, 999999.0, , , float
Expand Down
56 changes: 45 additions & 11 deletions Parser/readAD2CPBinary.m
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,12 @@
[sect, len] = readSection(filename, data, dIdx, cpuEndianness);

if ~isempty(sect)
% grouping by Id, Version and Size is our only option, there is no
% information on whether record type is XXX or Alt_XXX like in .mat files.
if isfield(sect.Data, 'Version')
curField = ['Id' sprintf('%s', sect.Header.Id) 'Version' sprintf('%d', sect.Data.Version)];
curField = ['Id' sprintf('%s', sect.Header.Id) '_Version' sprintf('%d', sect.Data.Version) '_Size' sprintf('%u', sect.Header.DataSize)];
else
curField = ['Id' sprintf('%s', sect.Header.Id)];
curField = ['Id' sprintf('%s', sect.Header.Id) '_Size' sprintf('%u', sect.Header.DataSize)];
end
theFieldNames = fieldnames(sect);
nField = length(theFieldNames);
Expand Down Expand Up @@ -150,20 +152,46 @@
% read the section in
id = dec2hex(data(idx+2));
switch id
case '15'
case '15' % Burst Data Record
[sect, ~, off] = readBurstAverage (data, idx, cpuEndianness); % 0x15
case '16'

case '16' % Average Data Record
[sect, ~, off] = readBurstAverage (data, idx, cpuEndianness); % 0x16
case '17'

case '17' % Bottom Track Data Record
[sect, ~, off] = readBottomTrack (data, idx, cpuEndianness); % 0x17
case '18'

case '18' % Interleaved Burst Data Record (beam 5)
[sect, ~, off] = readBurstAverage (data, idx, cpuEndianness); % 0x18
case 'A0'

case '1A' % Burst Altimeter Raw Record
[sect, ~, off] = readBurstAverage (data, idx, cpuEndianness); % 0x1A

case '1B' % DVL Bottom Track Record
[sect, ~, off] = readBottomTrack (data, idx, cpuEndianness); % 0x1B

case '1C' % Echo Sounder Record
disp('Echo Sounder Record not supported');
off = len;

case '1D' % DVL Water Track Record
disp('DVL Water Track Record not supported');
off = len;

case '1E' % Altimeter Record
[sect, ~, off] = readBurstAverage (data, idx, cpuEndianness); % 0x1E

case '1F' % Avg Altimeter Raw Record
[sect, ~, off] = readBurstAverage (data, idx, cpuEndianness); % 0x1F

case 'A0' % String Data Record, eg. GPS NMEA data, comment from the FWRITE command
[sect, ~, off] = readString (data, idx, cpuEndianness); % 0xA0

otherwise
disp('Unknown section type');
disp(['ID : hex ' id ' at offset ' num2str(idx+2)]);
off = len;

end

if isempty(sect), return; end
Expand Down Expand Up @@ -285,8 +313,11 @@
iEndCell = 10;
iStartBeam = 13;
iEndBeam = 16;
iStartCoord = 11;
iEndCoord = 12;
sect.nCells = bin2dec(sect.Beams_CoordSys_Cells(end-iEndCell+1:end-iStartCell+1));
sect.nBeams = bin2dec(sect.Beams_CoordSys_Cells(end-iEndBeam+1:end-iStartBeam+1));
sect.coordSys = bin2dec(sect.Beams_CoordSys_Cells(end-iEndCoord+1:end-iStartCoord+1));

sect.CellSize = bytecast(data(idx+30:idx+31), 'L', 'uint16', cpuEndianness); % 1 mm
sect.Blanking = bytecast(data(idx+32:idx+33), 'L', 'uint16', cpuEndianness); % 1 mm
Expand Down Expand Up @@ -343,8 +374,11 @@
iEndCell = 10;
iStartBeam = 13;
iEndBeam = 16;
iStartCoord = 11;
iEndCoord = 12;
sect.nCells = bin2dec(sect.Beams_CoordSys_Cells(end-iEndCell+1:end-iStartCell+1));
sect.nBeams = bin2dec(sect.Beams_CoordSys_Cells(end-iEndBeam+1:end-iStartBeam+1));
sect.coordSys = bin2dec(sect.Beams_CoordSys_Cells(end-iEndCoord+1:end-iStartCoord+1));

sect.CellSize = bytecast(data(idx+36:idx+37), 'L', 'uint16', cpuEndianness); % 1 mm
sect.Blanking = bytecast(data(idx+38:idx+39), 'L', 'uint16', cpuEndianness); % 1 mm
Expand All @@ -356,7 +390,7 @@
sect.AccRawX = bytecast(data(idx+50:idx+51), 'L', 'int16', cpuEndianness); % accelerometer Raw, X axis value in last measurement interval (16384 = 1.0)
sect.AccRawY = bytecast(data(idx+52:idx+53), 'L', 'int16', cpuEndianness);
sect.AccRawZ = bytecast(data(idx+54:idx+55), 'L', 'int16', cpuEndianness);
sect.AmbiguityVelocity = bytecast(data(idx+56:idx+57), 'L', 'uint16', cpuEndianness); % 0.1mm/s ; corrected for sound velocity
sect.AmbiguityVel = bytecast(data(idx+56:idx+57), 'L', 'uint16', cpuEndianness); % 0.1mm/s ; corrected for sound velocity
sect.DatasetDesc = dec2bin(bytecast(data(idx+58:idx+59), 'L', 'uint16', cpuEndianness), 16);
sect.TransmitEnergy = bytecast(data(idx+60:idx+61), 'L', 'uint16', cpuEndianness);
sect.VelocityScaling = bytecast(data(idx+62), 'L', 'int8', cpuEndianness);
Expand Down Expand Up @@ -416,7 +450,7 @@
iEndCoord = 12;
sect.nCells = bin2dec(sect.Beams_CoordSys_Cells(end-iEndCell+1:end-iStartCell+1));
sect.nBeams = bin2dec(sect.Beams_CoordSys_Cells(end-iEndBeam+1:end-iStartBeam+1));
sect.coordSys = sect.Beams_CoordSys_Cells(end-iEndCoord+1:end-iStartCoord+1);
sect.coordSys = bin2dec(sect.Beams_CoordSys_Cells(end-iEndCoord+1:end-iStartCoord+1));

sect.CellSize = bytecast(data(idx+32:idx+33), 'L', 'uint16', cpuEndianness); % 1 mm
sect.Blanking = bytecast(data(idx+34:idx+35), 'L', 'uint16', cpuEndianness); % 1 mm
Expand All @@ -429,7 +463,7 @@
sect.AccRawX = bytecast(data(idx+46:idx+47), 'L', 'int16', cpuEndianness); % accelerometer Raw, X axis value in last measurement interval (16384 = 1.0)
sect.AccRawY = bytecast(data(idx+48:idx+49), 'L', 'int16', cpuEndianness);
sect.AccRawZ = bytecast(data(idx+50:idx+51), 'L', 'int16', cpuEndianness);
sect.AmbiguityVelocity = bytecast(data(idx+52:idx+53), 'L', 'uint16', cpuEndianness); % 10^(Velocity scaling) m/s ; corrected for sound velocity
sect.AmbiguityVel = bytecast(data(idx+52:idx+53), 'L', 'uint16', cpuEndianness); % 10^(Velocity scaling) m/s ; corrected for sound velocity
sect.DatasetDesc = dec2bin(bytecast(data(idx+54:idx+55), 'L', 'uint16', cpuEndianness), 16);
sect.TransmitEnergy = bytecast(data(idx+56:idx+57), 'L', 'uint16', cpuEndianness);
sect.VelocityScaling = bytecast(data(idx+58), 'L', 'int8', cpuEndianness);
Expand Down Expand Up @@ -521,7 +555,7 @@
sect.Data.AccRawX = bytecast(data(idx+46:idx+47), 'L', 'int16', cpuEndianness); % accelerometer Raw, X axis value in last measurement interval (16384 = 1.0)
sect.Data.AccRawY = bytecast(data(idx+48:idx+49), 'L', 'int16', cpuEndianness);
sect.Data.AccRawZ = bytecast(data(idx+50:idx+51), 'L', 'int16', cpuEndianness);
sect.Data.AmbiguityVelocity = bytecast(data(idx+52:idx+53), 'L', 'uint16', cpuEndianness); % 10^(Velocity scaling) m/s ; corrected for sound velocity
sect.Data.AmbiguityVel = bytecast(data(idx+52:idx+53), 'L', 'uint16', cpuEndianness); % 10^(Velocity scaling) m/s ; corrected for sound velocity
sect.Data.DatasetDesc = dec2bin(bytecast(data(idx+54:idx+55), 'L', 'uint16', cpuEndianness), 16);
sect.Data.TransmitEnergy = bytecast(data(idx+56:idx+57), 'L', 'uint16', cpuEndianness);
sect.Data.VelocityScaling = bytecast(data(idx+58), 'L', 'int8', cpuEndianness);
Expand Down
Loading

0 comments on commit 223a933

Please sign in to comment.