function [ Data, Config, T_beam2xyz ] = signatureAD2CP_beam2xyz_enu( Data, Config, mode, twoZs, declination, index ) if nargin == 3 twoZs = 0; end ad2cpstr = 'AD2CP_'; ad2cpstr = ''; switch mode case 'avg' dataModeWord = 'Average'; configModeWord = 'avg'; case 'avg1' dataModeWord = 'Alt_Average'; configModeWord = 'avg1'; case 'burst' dataModeWord = 'Alt_Burst'; configModeWord = 'burst1'; case 'burst1' dataModeWord = 'Burst'; configModeWord = 'burst'; case 'shallow' dataModeWord = 'Shallow'; configModeWord = 'autonomous'; case 'shallow1' dataModeWord = 'Shallow1'; configModeWord = 'autonomous'; end % make the assumption the beam mapping is the same for all measurements in a data file activeBeams = Data.( [dataModeWord '_Physicalbeam'] )( 1, : ); activeBeams = activeBeams(find(activeBeams > 0)); numberOfBeams = length( activeBeams ); if numberOfBeams <= 2 print( 'Transformations require at least 3 active beams.' ) T_beam2xyz = nan; return end beam2xyz_vec = Config.([ad2cpstr configModeWord '_beam2xyz'] ); if numberOfBeams == 4, T_beam2xyz = [beam2xyz_vec(1:4); beam2xyz_vec(5:8); beam2xyz_vec(9:12); beam2xyz_vec(13:16)]; else if numberOfBeams == 3, T_beam2xyz = [beam2xyz_vec(1:3); beam2xyz_vec(4:6); beam2xyz_vec(7:9)]; end end % Special case if strcmp(Config.instrumentName, 'Signature55kHz'), T_beam2xyz =[ 1.9492 -0.9746 -0.9746; ... 0 -1.6881 1.6881; ... 0.3547 0.3547 0.3547]; end if Config.fwVersionDoppler <= 2163 && numberOfBeams == 4, % Fix bug in transformation matrix in version 2163 T_beam2xyz(2,:) = -T_beam2xyz(2,:); end if nargin < 6 disp(T_beam2xyz) L=length( Data.( [ dataModeWord '_TimeStamp' ] )); index = 1:L; else L=length(index); end % verify we're not already in 'xyz' if strcmpi( Config.( [ ad2cpstr configModeWord '_coordSystem' ] ), 'xyz' ) disp( 'Velocity data is already in xyz coordinate system.' ) return end xAllCells = zeros( L, Config.( [ad2cpstr configModeWord '_nCells' ] ) ); yAllCells = zeros( L, Config.( [ad2cpstr configModeWord '_nCells' ] ) ); zAllCells = zeros( L, Config.( [ad2cpstr configModeWord '_nCells' ] ) ); if twoZs == 1 z2AllCells = zeros( L, Config.( [ad2cpstr configModeWord '_nCells' ] ) ); end xyz = zeros( size( T_beam2xyz, 2 ), L ); beam = zeros( size( T_beam2xyz, 2 ), L ); for nCell = 1:Config.( [ad2cpstr configModeWord '_nCells' ] ) for i = 1:numberOfBeams beam( i, : ) = Data.( [ dataModeWord '_VelBeam' num2str( Data.( [ dataModeWord '_Physicalbeam' ] )( 1, i ) ) ] )( index, nCell )'; end xyz = T_beam2xyz * beam; xAllCells( :, nCell ) = xyz( 1, : )'; yAllCells( :, nCell ) = xyz( 2, : )'; zAllCells( :, nCell ) = xyz( 3, : )'; if twoZs == 1 z2AllCells( :, nCell ) = xyz( 4, : )'; end end Config.( [ad2cpstr configModeWord '_coordSystemXYZ' ] )(index,:) = 'xyz'; Data.( [ dataModeWord '_VelX' ] )(index,1:nCell) = xAllCells; Data.( [ dataModeWord '_VelY' ] )(index,1:nCell) = yAllCells; if twoZs == 1 Data.( [ dataModeWord '_VelZ1' ] )(index,1:nCell) = zAllCells; Data.( [ dataModeWord '_VelZ2' ] )(index,1:nCell) = z2AllCells; else Data.( [ dataModeWord '_VelZ' ] )(index,1:nCell) = zAllCells; end % verify we're not already in 'enu' if strcmpi( Config.( [ad2cpstr configModeWord '_coordSystem' ] ), 'enu' ) disp( 'Velocity data is already in enu coordinate system.' ) return end K = 3; Ncells = Config.( [ad2cpstr configModeWord '_nCells' ] ); EAllCells = zeros( L , Ncells ); NAllCells = zeros( L , Ncells ); UAllCells = zeros( L , Ncells ); if twoZs == 1 U2AllCells = zeros( L, Config.( [ad2cpstr configModeWord '_nCells' ] ) ); K = 4; end Name = ['X','Y','Z']; ENU = zeros( K, Ncells); xyz = zeros( K, Ncells); for sampleIndex = index(1):index(end) orientation = bitand(bitshift(uint32(Data.( [dataModeWord '_Status' ])(sampleIndex)), -25),7); if (orientation == 5) signXYZ=[1 -1 -1 -1]; else signXYZ=[1 1 1 1]; end if (orientation == 7) % AHRS xyz2enuAHRS = transpose(reshape(Data.([dataModeWord '_AHRSRotationMatrix'])(sampleIndex,:),3,3)); % Apply declination % Make declination rotation matrix H = [cosd(declination) sind(declination) 0; -sind(declination) cosd(declination) 0; 0 0 1]; xyz2enuAHRSdecl = H*xyz2enuAHRS; % Update the transformation matrix Data.([dataModeWord '_AHRSRotationMatrix'])(sampleIndex,:)=reshape(transpose(xyz2enuAHRSdecl),1,9); % Update the heading value heading = 90-(atan2(xyz2enuAHRSdecl(2,1),xyz2enuAHRSdecl(1,1))*180/pi); if heading < 0, heading = heading + 360; end if heading >= 360, heading = heading - 360; end Data.([dataModeWord '_Heading'])(sampleIndex) = heading; xyz2enu = xyz2enuAHRSdecl; else % Apply declination heading = Data.([dataModeWord '_Heading'])(sampleIndex) + declination; if heading < 0, heading = heading + 360; end if heading >= 360, heading = heading - 360; end Data.([dataModeWord '_Heading'])(sampleIndex) = heading; % Regular compass hh = pi*(Data.([dataModeWord '_Heading'])(sampleIndex)-90)/180; pp = pi*Data.([dataModeWord '_Pitch'])(sampleIndex)/180; rr = pi*Data.([dataModeWord '_Roll'])(sampleIndex)/180; % Make heading matrix H = [cos(hh) sin(hh) 0; -sin(hh) cos(hh) 0; 0 0 1]; % Make tilt matrix P = [cos(pp) -sin(pp)*sin(rr) -cos(rr)*sin(pp);... 0 cos(rr) -sin(rr); ... sin(pp) sin(rr)*cos(pp) cos(pp)*cos(rr)]; % Make resulting transformation matrix xyz2enu = H*P; end if (twoZs == 1) xyz2enu(1,3) = xyz2enu(1,3)/2; xyz2enu(1,4) = xyz2enu(1,3); xyz2enu(2,3) = xyz2enu(2,3)/2; xyz2enu(2,4) = xyz2enu(2,3); xyz2enu(4,:) = xyz2enu(3,:); xyz2enu(3,4) = 0; xyz2enu(4,4) = xyz2enu(3,3); xyz2enu(4,3) = 0; end for i = 1:K if (twoZs == 1) && (i >= 3) axs = [ Name(3) num2str((i-2),1) ]; else axs = Name(i); end xyz( i, : ) = signXYZ(i) * Data.( [ dataModeWord '_Vel' axs] )( sampleIndex, 1:Ncells )'; end ENU = xyz2enu * xyz; Data.( [ dataModeWord '_VelEast' ] )( sampleIndex, 1:Ncells ) = ENU( 1, : )'; Data.( [ dataModeWord '_VelNorth' ] )( sampleIndex, 1:Ncells ) = ENU( 2, : )'; if twoZs == 0 Data.( [ dataModeWord '_VelUp' ] )( sampleIndex, 1:Ncells ) = ENU( 3, : )'; else Data.( [ dataModeWord '_VelUp1' ] )( sampleIndex, 1:Ncells ) = ENU( 3, : )'; Data.( [ dataModeWord '_VelUp2' ] )( sampleIndex, 1:Ncells ) = ENU( 4, : )'; end end Config.( [ad2cpstr configModeWord '_coordSystemENU' ] ) = 'enu';