author  A.M. Thurnherr <athurnherr@yahoo.com> 
Tue, 29 Jun 2021 12:21:32 0400  
changeset 59  4f4530fa35da 
parent 58  78607e2e8add 
permissions  rwrr 
0  1 
#====================================================================== 
2 
# R D I _ C O O R D S . P L 

3 
# doc: Sun Jan 19 17:57:53 2003 

58  4 
# dlm: Wed Mar 17 23:20:13 2021 
0  5 
# (c) 2003 A.M. Thurnherr 
58  6 
# uEInfo: 66 9 NIL 0 0 72 10 2 4 NIL ofnI 
0  7 
#====================================================================== 
8 

9 
# RDI Workhorse Coordinate Transformations 

10 

11 
# HISTORY: 

12 
# Jan 19, 2003:  written 

13 
# Jan 21, 2003:  made it obey HEADING_BIAS (magnetic declination) 

14 
# Jan 22, 3003:  corrected magnetic declination 

15 
# Feb 16, 2003:  use pitch correction from RDI manual 

16 
# Oct 11, 2003:  BUG: return value of atan() had been interpreted 

17 
# as degrees instead of radians 

18 
# Feb 27, 2004:  added velApplyHdgBias() 

19 
#  changed nonzero HEADING_ALIGNMENT from error to warning 

20 
# Sep 16, 2005:  added deg() for [mkprofile] 

21 
# Aug 26, 2006:  BUG: incorrect transformation for uplookers 

22 
# Nov 30, 2007:  optimized &velInstrumentToEarth(), velBeamToInstrument() 

23 
#  added support for 3beam solutions 

24 
# Feb 12, 2008:  added threeBeamFlag 

25 
# Mar 18, 2009:  added &gimbal_pitch(), &angle_from_vertical() 

26 
# May 19, 2009:  added &velBeamToVertical() 

27 
# May 23, 2009:  debugged & renamed to &velBeamToBPEarth 

28 
# May 23, 2010:  changed prototypes of rad() & deg() to conform to ANTS 

5  29 
# Dec 20, 2010:  cosmetics 
6  30 
# Dec 23, 2010:  added &velBeamToBPInstrument 
31 
# Jan 22, 2011:  made velApplyHdgBias calculate sin/cos every time to allow 

32 
# perensemble corrections 

8  33 
# Jan 15, 2012:  replaced defined(@...) by (@...) to get rid of warning 
13
b176da8559b3
before implementing WBWens (PD0 writing)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
8
diff
changeset

34 
# Aug 7, 2013:  BUG: &velBeamToBPInstrument did not return any val unless 
b176da8559b3
before implementing WBWens (PD0 writing)
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
8
diff
changeset

35 
# all beam velocities are defined 
14  36 
# Nov 27, 2013:  added &RDI_pitch(), &tilt_azimuth() 
19
e23a5fd2923a
after adapting RDI_Coords to calc w even without valid heading
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
18
diff
changeset

37 
# Mar 4, 2014:  added support for ensembles with missing PITCH/ROLL/HEADING 
e23a5fd2923a
after adapting RDI_Coords to calc w even without valid heading
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
18
diff
changeset

38 
# May 29, 2014:  BUG: vertical velocity can be calculated even without 
e23a5fd2923a
after adapting RDI_Coords to calc w even without valid heading
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
18
diff
changeset

39 
# heading 
e23a5fd2923a
after adapting RDI_Coords to calc w even without valid heading
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
18
diff
changeset

40 
#  removed some old debug statements 
e23a5fd2923a
after adapting RDI_Coords to calc w even without valid heading
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
18
diff
changeset

41 
#  removed unused code from &velBeamToBPInstrument 
28  42 
# Jan 5, 2016:  added &velEarthToInstrument(@), &velInstrumentToBeam(@) 
31  43 
# Jan 9, 2016:  added &velEarthToBeam(), &velBeamToEarth() 
32  44 
# Feb 29, 2016:  debugged & verified velEarthToInstrument(), velInstrumentToBeam() 
45 
#  added velBeamToEarth() 

34  46 
# May 19, 2016:  begin implemeting bin interpolation 
35
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

47 
# May 25, 2016:  continued 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

48 
# May 26, 2016:  made it work 
36
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

49 
# May 30, 2016:  begin implementing 2nd order attitude transformations 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

50 
# Jun 6, 2016:  toEarth transformation in beamToBPEarth was but crude approximation; 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

51 
# updated with transformation taken from Lohrman et al. (JAOT 1990) 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

52 
#  BUG: v34 sign was inconsistent with RDI coord manual 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

53 
# Jun 8, 2016:  added $ens as arg to velInstrumentToBeam() for consistency 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

54 
# Jul 7, 2016:  added velEarthToBPw() with algorithm debugged and verified 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

55 
# by Paul Wanis from TRDI 
39  56 
# Oct 12, 2017:  documentation 
41  57 
# Nov 26, 2017:  BUG: velBeamtoBPEarth() did not respect missing values 
58 
# Nov 27, 2017:  BUG: numbersp() from [antslib.pl] was used 

43
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
41
diff
changeset

59 
# Mar 28, 2018:  added &loadInstrumentTransformation() 
54  60 
# Jun 5, 2020:  added sscorr_w & sscorr_w_mooring 
61 
# Jun 29, 2020:  added comments for sscorr_w, which conflicts with LADCP_w_ocean 

58  62 
# Mar 17, 2021:  adapted velBeamToInstrument() to Nortek (checked w only) 
63 
#  adapted velInstrumentToEarth() to Nortek, assuming Nortek pitch is gimbal pitch 

64 
# HISTORY END 

65 

66 
# NORTEK TODO: 

67 
#  check u, v sign convention for Nortek 

68 
#  verify that gimbal pitch for Nortek gives better results 

69 
# for A20 test profile 900, the differences in w have a stddev of 1.3e5 m/s 

70 
#  update gimbal pitch for Nortek in other routines 

0  71 

72 
use strict; 

73 
use POSIX; 

74 

75 
my($PI) = 3.14159265358979; 

76 

77 
sub rad(@) { return $_[0]/180 * $PI; } 

78 
sub deg(@) { return $_[0]/$PI * 180; } 

79 

35
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

80 
# 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

81 
# Tweakables 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

82 
# 
0  83 

36
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

84 
$RDI_Coords::minValidVels = 3; # 3beam solutions ok (velBeamToInstrument) 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

85 
$RDI_Coords::binMapping = 'linterp'; # 'linterp' or 'none' (earthVels, BPearthVels) 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

86 
$RDI_Coords::beamTransformation = 'LHR90'; # set to 'RDI' to use 1st order transformations from RDI manual 
35
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

87 

7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

88 
# 
43
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
41
diff
changeset

89 
# beam to earth transformation 
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
41
diff
changeset

90 
#  loadInstrumentTransformation(filename) loads a file that contains the 
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
41
diff
changeset

91 
# output from the PS3 command, which includes the instrument transformation 
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
41
diff
changeset

92 
# matrix as follows: 
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
41
diff
changeset

93 
# Instrument Transformation Matrix (Down): Q14: 
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
41
diff
changeset

94 
# 1.4689 1.4682 0.0030 0.0035 24067 24055 49 58 
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
41
diff
changeset

95 
# 0.0036 0.0029 1.4664 1.4673 59 48 24025 24041 
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
41
diff
changeset

96 
# 0.2658 0.2661 0.2661 0.2657 4355 4359 4359 4354 
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
41
diff
changeset

97 
# 1.0373 1.0382 1.0385 1.0373 16995 17010 17015 16995 
35
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

98 
# 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

99 

7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

100 
$RDI_Coords::threeBeam_1 = 0; # stats from velBeamToInstrument 
0  101 
$RDI_Coords::threeBeam_2 = 0; 
102 
$RDI_Coords::threeBeam_3 = 0; 

103 
$RDI_Coords::threeBeam_4 = 0; 

104 
$RDI_Coords::fourBeam = 0; 

105 

106 
$RDI_Coords::threeBeamFlag = 0; # flag last transformation 

107 

108 
{ # STATIC SCOPE 

109 
my(@B2I); 

110 

43
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
41
diff
changeset

111 
sub loadInstrumentTransformation($) 
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
41
diff
changeset

112 
{ 
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
41
diff
changeset

113 
die("loadInstrumentTransformation(): B2I matrix already defined\n") 
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
41
diff
changeset

114 
if (@B2I); 
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
41
diff
changeset

115 
open(ITF,$_[0])  die("$_[0]: $!\n"); 
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
41
diff
changeset

116 
my($row) = 0; 
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
41
diff
changeset

117 
while (<ITF>) { 
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
41
diff
changeset

118 
if ($row == 0) { 
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
41
diff
changeset

119 
next unless m{^Instrument Transformation Matrix \(Down\):}; 
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
41
diff
changeset

120 
$row = 1; 
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
41
diff
changeset

121 
} elsif ($row <= 4) { 
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
41
diff
changeset

122 
my(@vals) = split; 
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
41
diff
changeset

123 
die("$_[0]: cannot decode row #$row of Instrument Transformation Matrix\n") 
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
41
diff
changeset

124 
unless (@vals == 8); 
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
41
diff
changeset

125 
for (my($i)=0; $i<4; $i++) { 
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
41
diff
changeset

126 
die("$_[0]: cannot decode row #$row of Instrument Transformation Matrix\n") 
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
41
diff
changeset

127 
unless numberp($vals[$i]); 
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
41
diff
changeset

128 
$B2I[$row1][$i] = $vals[$i]; 
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
41
diff
changeset

129 
} 
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
41
diff
changeset

130 
$row++; 
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
41
diff
changeset

131 
} else { 
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
41
diff
changeset

132 
last; 
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
41
diff
changeset

133 
} 
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
41
diff
changeset

134 
} 
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
41
diff
changeset

135 
die("$_[0]: cannot decode Instrument Transformation Matrix (row = $row)\n") 
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
41
diff
changeset

136 
unless ($row == 5); 
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
41
diff
changeset

137 
close(ITF); 
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
41
diff
changeset

138 
} 
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
41
diff
changeset

139 

0  140 
sub velBeamToInstrument(@) 
141 
{ 

35
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

142 
my($ADCP,$ens,$v1,$v2,$v3,$v4) = @_; 
0  143 
return undef unless (defined($v1) + defined($v2) + 
144 
defined($v3) + defined($v4) 

145 
>= $RDI_Coords::minValidVels); 

146 

58  147 
unless (@B2I) { # nominal transformation matrix 
35
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

148 
my($a) = 1 / (2 * sin(rad($ADCP>{BEAM_ANGLE}))); 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

149 
my($b) = 1 / (4 * cos(rad($ADCP>{BEAM_ANGLE}))); 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

150 
my($c) = $ADCP>{CONVEX_BEAM_PATTERN} ? 1 : 1; 
0  151 
my($d) = $a / sqrt(2); 
152 
@B2I = ([$c*$a, $c*$a, 0, 0 ], 

153 
[0, 0, $c*$a, $c*$a], 

154 
[$b, $b, $b, $b ], 

155 
[$d, $d, $d, $d ]); 

156 
} 

157 

58  158 
if ($ADCP>{PRODUCER} =~ '^Nortek') { # Nortek ADCPs use different coord system 
159 
$v1 *= 1 if defined($v1); 

160 
$v2 *= 1 if defined($v2); 

161 
$v3 *= 1 if defined($v3); 

162 
$v4 *= 1 if defined($v4); 

163 
} 

164 

165 
if (!defined($v1)) { # 3beam solutions 

0  166 
$RDI_Coords::threeBeamFlag = 1; 
167 
$RDI_Coords::threeBeam_1++; 

168 
$v1 = ($v2*$B2I[3][1]+$v3*$B2I[3][2]+$v4*$B2I[3][3])/$B2I[3][0]; 

169 
} elsif (!defined($v2)) { 

170 
$RDI_Coords::threeBeamFlag = 1; 

171 
$RDI_Coords::threeBeam_2++; 

172 
$v2 = ($v1*$B2I[3][0]+$v3*$B2I[3][2]+$v4*$B2I[3][3])/$B2I[3][1]; 

173 
} elsif (!defined($v3)) { 

174 
$RDI_Coords::threeBeamFlag = 1; 

175 
$RDI_Coords::threeBeam_3++; 

176 
$v3 = ($v1*$B2I[3][0]+$v2*$B2I[3][1]+$v4*$B2I[3][3])/$B2I[3][2]; 

177 
} elsif (!defined($v4)) { 

178 
$RDI_Coords::threeBeamFlag = 1; 

179 
$RDI_Coords::threeBeam_4++; 

180 
$v4 = ($v1*$B2I[3][0]+$v2*$B2I[3][1]+$v3*$B2I[3][2])/$B2I[3][3]; 

181 
} else { 

182 
$RDI_Coords::threeBeamFlag = 0; 

183 
$RDI_Coords::fourBeam++; 

184 
} 

185 

186 
return ($v1*$B2I[0][0]+$v2*$B2I[0][1], 

187 
$v3*$B2I[1][2]+$v4*$B2I[1][3], 

188 
$v1*$B2I[2][0]+$v2*$B2I[2][1]+$v3*$B2I[2][2]+$v4*$B2I[2][3], 

189 
$v1*$B2I[3][0]+$v2*$B2I[3][1]+$v3*$B2I[3][2]+$v4*$B2I[3][3]); 

190 
} 

191 
} # STATIC SCOPE 

192 

43
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
41
diff
changeset

193 
# 
36
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

194 
# velInstrumentToEarth(\%ADCP,ens,v1,v2,v3,v4) => (u,v,w,e) 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

195 
#  $RDI_Coords::beamTransformation = 'LHR90' 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

196 
#  from Lohrmann, Hackett & Roet (J. Tech., 1990) 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

197 
#  eq A1 maps to RDI matrix M (sec 5.6) with 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

198 
# alpha = roll 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

199 
# beta = gimball_pitch 
43
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
41
diff
changeset

200 
# psi (pitch used for calculation) = asin{sin(beta) cos(alpha) / sqrt[1 sin(alpha)^2 sin(beta)^2]} 
36
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

201 
#  (I only checked for 0 heading, but this is sufficient) 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

202 
#  $RDI_Coords::beamTransformation = 'RDI' 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

203 
#  default prior to LADCP_w V1.3 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

204 
#  from RDI manual 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

205 
#  99% accurate for p/r<8deg 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

206 
# => 1cm/s error for 1m/s winch speed! 
43
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
41
diff
changeset

207 
# 
36
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

208 

0  209 
{ # STATIC SCOPE 
210 
my($hdg,$pitch,$roll,@I2E); 

211 

212 
sub velInstrumentToEarth(@) 

213 
{ 

35
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

214 
my($ADCP,$ens,$v1,$v2,$v3,$v4) = @_; 
0  215 
return undef unless (defined($v1) && defined($v2) && 
18  216 
defined($v3) && defined($v4) && 
35
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

217 
defined($ADCP>{ENSEMBLE}[$ens]>{PITCH}) && 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

218 
defined($ADCP>{ENSEMBLE}[$ens]>{ROLL})); 
0  219 

220 
unless (@I2E && 

35
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

221 
$pitch == $ADCP>{ENSEMBLE}[$ens]>{PITCH} && 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

222 
$roll == $ADCP>{ENSEMBLE}[$ens]>{ROLL}) { 
0  223 
printf(STDERR "$0: warning HEADING_ALIGNMENT == %g ignored\n", 
35
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

224 
$ADCP>{HEADING_ALIGNMENT}) 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

225 
if ($ADCP>{HEADING_ALIGNMENT}); 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

226 
$hdg = $ADCP>{ENSEMBLE}[$ens]>{HEADING}  $ADCP>{HEADING_BIAS} 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

227 
if defined($ADCP>{ENSEMBLE}[$ens]>{HEADING}); 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

228 
$pitch = $ADCP>{ENSEMBLE}[$ens]>{PITCH}; 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

229 
$roll = $ADCP>{ENSEMBLE}[$ens]>{ROLL}; 
58  230 
my($rad_gimbal_pitch); 
231 
if ($ADCP>{PRODUCER} =~ '^Nortek') { 

232 
$rad_gimbal_pitch = rad($pitch); # I am assuming that this is correct 

233 
} else { 

234 
$rad_gimbal_pitch = atan(tan(rad($pitch)) * cos(rad($roll))); 

235 
} 

236 

36
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

237 
my($rad_calc_pitch) = ($RDI_Coords::beamTransformation eq 'RDI') ? $rad_gimbal_pitch : 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

238 
asin(sin($rad_gimbal_pitch)*cos(rad($roll)) / 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

239 
sqrt(1sin(rad($roll))**2*sin($rad_gimbal_pitch)**2)); 
19
e23a5fd2923a
after adapting RDI_Coords to calc w even without valid heading
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
18
diff
changeset

240 
my($sh,$ch) = (sin(rad($hdg)),cos(rad($hdg))) 
e23a5fd2923a
after adapting RDI_Coords to calc w even without valid heading
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
18
diff
changeset

241 
if defined($hdg); 
36
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

242 
my($sp,$cp) = (sin($rad_calc_pitch),cos($rad_calc_pitch)); 
0  243 
my($sr,$cr) = (sin(rad($roll)), cos(rad($roll))); 
35
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

244 
@I2E = $ADCP>{ENSEMBLE}[$ens]>{XDUCER_FACING_UP} 
0  245 
? ( 
246 
[$ch*$cr$sh*$sp*$sr, $sh*$cp,$ch*$sr+$sh*$sp*$cr], 

247 
[$ch*$sp*$sr+$sh*$cr, $ch*$cp, $sh*$sr+$ch*$sp*$cr], 

248 
[+$cp*$sr, $sp, $cp*$cr, ], 

249 
) : ( 

250 
[$ch*$cr+$sh*$sp*$sr, $sh*$cp, $ch*$sr$sh*$sp*$cr], 

251 
[$ch*$sp*$sr$sh*$cr, $ch*$cp,$sh*$sr$ch*$sp*$cr], 

252 
[$cp*$sr, $sp, $cp*$cr, ], 

253 
); 

254 
} 

35
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

255 
return defined($ADCP>{ENSEMBLE}[$ens]>{HEADING}) 
19
e23a5fd2923a
after adapting RDI_Coords to calc w even without valid heading
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
18
diff
changeset

256 
? ($v1*$I2E[0][0]+$v2*$I2E[0][1]+$v3*$I2E[0][2], 
e23a5fd2923a
after adapting RDI_Coords to calc w even without valid heading
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
18
diff
changeset

257 
$v1*$I2E[1][0]+$v2*$I2E[1][1]+$v3*$I2E[1][2], 
e23a5fd2923a
after adapting RDI_Coords to calc w even without valid heading
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
18
diff
changeset

258 
$v1*$I2E[2][0]+$v2*$I2E[2][1]+$v3*$I2E[2][2], 
e23a5fd2923a
after adapting RDI_Coords to calc w even without valid heading
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
18
diff
changeset

259 
$v4) 
e23a5fd2923a
after adapting RDI_Coords to calc w even without valid heading
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
18
diff
changeset

260 
: (undef,undef, 
e23a5fd2923a
after adapting RDI_Coords to calc w even without valid heading
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
18
diff
changeset

261 
$v1*$I2E[2][0]+$v2*$I2E[2][1]+$v3*$I2E[2][2], 
e23a5fd2923a
after adapting RDI_Coords to calc w even without valid heading
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
18
diff
changeset

262 
$v4); 
0  263 
} 
264 
} # STATIC SCOPE 

265 

32  266 

267 
sub velBeamToEarth(@) 

268 
{ 

35
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

269 
my($ADCP,$e,@v) = @_; 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

270 
return velInstrumentToEarth($ADCP,$e,velBeamToInstrument($ADCP,$e,@v)); 
32  271 
} 
272 

35
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

273 

28  274 
# 
275 
# velEarthToInstrument() transforms earth to instrument coordinates 

276 
#  based on manually inverted rotation matrix M (Sec 5.6 in coordtrans manual) 

36
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

277 
#  Paul Wanis from TRDI pointed out that M is orthonormal, which 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

278 
# implies that M^1 = M' (where M' is the transpose), confirming 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

279 
# the (unnecessary) derivation 
32  280 
#  code was verified for both down and uplookers 
28  281 
#  missing heading data (IMP) causes undef beam velocities 
282 
# 

283 

284 
{ # STATIC SCOPE 

285 
my($hdg,$pitch,$roll,@E2I); 

286 

287 
sub velEarthToInstrument(@) 

288 
{ 

35
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

289 
my($ADCP,$ens,$u,$v,$w,$ev) = @_; 
28  290 

32  291 
unless (@E2I && 
35
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

292 
$pitch == $ADCP>{ENSEMBLE}[$ens]>{PITCH} && 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

293 
$roll == $ADCP>{ENSEMBLE}[$ens]>{ROLL}) { 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

294 
$hdg = $ADCP>{ENSEMBLE}[$ens]>{HEADING}  $ADCP>{HEADING_BIAS} 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

295 
if defined($ADCP>{ENSEMBLE}[$ens]>{HEADING}); 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

296 
$pitch = $ADCP>{ENSEMBLE}[$ens]>{PITCH}; 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

297 
$roll = $ADCP>{ENSEMBLE}[$ens]>{ROLL}; 
28  298 
my($rad_gimbal_pitch) = atan(tan(rad($pitch)) * cos(rad($roll))); 
35
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

299 
my($useRoll) = ($ADCP>{ENSEMBLE}[$ens]>{XDUCER_FACING_UP}) ? $roll+180 : $roll; 
28  300 
my($sh,$ch) = (sin(rad($hdg)),cos(rad($hdg))) 
301 
if defined($hdg); 

302 
my($sp,$cp) = (sin($rad_gimbal_pitch),cos($rad_gimbal_pitch)); 

32  303 
my($sr,$cr) = (sin(rad($useRoll)), cos(rad($useRoll))); 
304 
@E2I = ([$ch*$cr+$sh*$sp*$sr, $ch*$sp*$sr$sh*$cr, $cp*$sr], # M^1 = R^1 * P^1 * R^1 

305 
[$sh*$cp, $ch*$cp, $sp ], 

306 
[$ch*$sr$sh*$sp*$cr, $sh*$sr$ch*$sp*$cr, $cp*$cr]); 

28  307 
} 
308 

35
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

309 
return defined($ADCP>{ENSEMBLE}[$ens]>{HEADING}) 
28  310 
? ($u*$E2I[0][0]+$v*$E2I[0][1]+$w*$E2I[0][2], 
311 
$u*$E2I[1][0]+$v*$E2I[1][1]+$w*$E2I[1][2], 

312 
$u*$E2I[2][0]+$v*$E2I[2][1]+$w*$E2I[2][2], 

313 
$ev) 

314 
: (undef,undef,undef,undef); 

315 

36
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

316 
} # velEarthToIntrument() 
28  317 
} # STATIC SCOPE 
318 

319 
# 

320 
# velInstrumentToBeam() transforms instrument to beam coordinates 

321 
#  based on manually solved eq system in sec 5.3 of coord manual 

322 
#  does not implement binremapping 

39  323 
#  returns undef for 3beam solutions, as it is not known which 
28  324 
# beam was bad 
325 
# 

326 

327 
{ # STATIC SCOPE 

328 
my($a,$b,$c,$d); 

329 

330 
sub velInstrumentToBeam(@) 

331 
{ 

36
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

332 
my($ADCP,$ens,$x,$y,$z,$ev) = @_; 
28  333 
return undef unless (defined($x) + defined($y) + 
334 
defined($z) + defined($ev) == 4); 

335 

336 
unless (defined($a)) { 

35
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

337 
$a = 1 / (2 * sin(rad($ADCP>{BEAM_ANGLE}))); 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

338 
$b = 1 / (4 * cos(rad($ADCP>{BEAM_ANGLE}))); 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

339 
$c = $ADCP>{CONVEX_BEAM_PATTERN} ? 1 : 1; 
28  340 
$d = $a / sqrt(2); 
341 
} 

342 

343 
return ( $x/(2*$a*$c) + $z/(4*$b) + $ev/(4*$d), 

344 
$x/(2*$a*$c) + $z/(4*$b) + $ev/(4*$d), 

345 
$y/(2*$a*$c) + $z/(4*$b)  $ev/(4*$d), 

346 
$y/(2*$a*$c) + $z/(4*$b)  $ev/(4*$d)); 

347 

348 
} 

349 
} # STATIC SCOPE 

350 

31  351 
# 
352 
# velEarthToBeam() combines velEarthToInstrument and velInstrumentToBeam 

353 
# 

354 

355 
sub velEarthToBeam(@) 

356 
{ 

35
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

357 
my($ADCP,$ens,$u,$v,$w,$ev) = @_; 
36
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

358 
return velInstrumentToBeam($ADCP,$ens, 
35
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

359 
velEarthToInstrument($ADCP,$ens,$u,$v,$w,$ev)); 
31  360 
} 
361 

36
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

362 
# 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

363 
# velEarthToBPw() returns w12 and w34 for beamcoordinate data 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

364 
#  I am grateful for Paul Wanis from TRDI who corrected a 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

365 
# bug in my transformation (fixed in V1.3). [The bug did not 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

366 
# affect the final w profiles significantly, because w12 and w34 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

367 
# are used only as diagnostics.] 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

368 
#  algorithm: 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

369 
# 1) rotate into instrument coordinates 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

370 
# 2) w12 = w + e*tan(beam_angle)/sqrt(2) 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

371 
# w34 = w  e*tan(beam_angle)/sqrt(2) 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

372 
# 3) rotate into horizontal coords (earth coords w/o 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

373 
# considering heading, i.e. same as earth coords 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

374 
# in case of w 
39  375 
#  the commentedout version above is a "bruteforce" 
376 
# implementation which should give the same result 

36
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

377 
# 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

378 

39  379 
#sub velEarthToBPw(@) 
380 
#{ 

381 
# my(@bpv) = velBeamToBPEarth(&velEarthToBeam(@_)); 

382 
# return ($bpv[1],$bpv[3]); 

383 
#} 

384 

36
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

385 
sub velEarthToBPw(@) 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

386 
{ 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

387 
my($ADCP,$ens,$u,$v,$w,$ev) = @_; 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

388 
my(@iv) = velEarthToInstrument(@_); 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

389 
my(@iv12) = my(@iv34) = @iv; 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

390 
$iv12[2] += $iv[3] * tan(rad($ADCP>{BEAM_ANGLE}))/sqrt(2); 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

391 
$iv34[2] = $iv[3] * tan(rad($ADCP>{BEAM_ANGLE}))/sqrt(2); 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

392 
my(@ev12) = velInstrumentToEarth($ADCP,$ens,@iv12); 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

393 
my(@ev34) = velInstrumentToEarth($ADCP,$ens,@iv34); 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

394 
return ($ev12[2],$ev34[2]); 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

395 
} 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

396 

0  397 
#====================================================================== 
5  398 
# velBeamToBPEarth(@) calculates the vertical and horizontal vels 
0  399 
# from the two beam pairs separately. Note that (w1+w2)/2 is 
36
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

400 
# identical to the w estimated according to RDI (ignoring 3beam 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

401 
# solutions). 
0  402 
#====================================================================== 
403 

404 
{ # STATIC SCOPE 

405 
my($TwoCosBAngle,$TwoSinBAngle); 

406 

407 
sub velBeamToBPEarth(@) 

408 
{ 

35
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

409 
my($ADCP,$ens,$b1,$b2,$b3,$b4) = @_; 
0  410 
my($v12,$w12,$v34,$w34); 
411 

18  412 
return (undef,undef,undef,undef) 
35
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

413 
unless (defined($ADCP>{ENSEMBLE}[$ens]>{PITCH}) && 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

414 
defined($ADCP>{ENSEMBLE}[$ens]>{ROLL})); 
18  415 

0  416 
unless (defined($TwoCosBAngle)) { 
35
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

417 
$TwoCosBAngle = 2 * cos(rad($ADCP>{BEAM_ANGLE})); 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

418 
$TwoSinBAngle = 2 * sin(rad($ADCP>{BEAM_ANGLE})); 
0  419 
} 
36
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

420 
my($rad_roll) = rad($ADCP>{ENSEMBLE}[$ens]>{ROLL}); 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

421 
my($sr) = sin($rad_roll); my($cr) = cos($rad_roll); 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

422 
my($rad_gimbal_pitch) = atan(tan(rad($ADCP>{ENSEMBLE}[$ens]>{PITCH})) * $cr); # gimbal pitch 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

423 
my($rad_calc_pitch) = ($RDI_Coords::beamTransformation eq 'RDI') ? $rad_gimbal_pitch : 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

424 
asin(sin($rad_gimbal_pitch)*cos($rad_roll) / 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

425 
sqrt(1sin($rad_roll)**2*sin($rad_gimbal_pitch)**2)); 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

426 
my($sp) = sin($rad_calc_pitch); my($cp) = cos($rad_calc_pitch); 
0  427 

428 
# Sign convention: 

429 
#  refer to Coord manual Fig. 3 

430 
#  v12 is horizontal velocity from beam1 to beam2, i.e. westward for upwardlooking ADCP 

431 
# with beam 3 pointing north (heading = 0) 

432 

41  433 
my($v12_ic,$w12_ic,$v34_ic,$w34_ic,$w_ic); 
434 

435 
if (numberp($b1) && numberp($b2)) { 

436 
$v12_ic = ($b1$b2)/$TwoSinBAngle; # instrument coords... 

437 
$w12_ic = ($b1+$b2)/$TwoCosBAngle; # consistent with RDI convention 

438 
} 

439 
if (numberp($b3) && numberp($b4)) { 

440 
$v34_ic = ($b4$b3)/$TwoSinBAngle; 

441 
$w34_ic = ($b3+$b4)/$TwoCosBAngle; 

442 
} 

0  443 

36
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

444 
if ($ADCP>{ENSEMBLE}[$ens]>{XDUCER_FACING_DOWN}) { # beampair Earth coords 
41  445 
if (numberp($w12_ic) && numberp($w34_ic)) { 
446 
$w_ic = ($w12_ic+$w34_ic) / 2; 

447 
$v12 = $v12_ic*$cr + $v34_ic*0 + $w_ic*$sr; # Lohrman et al. (1990) A1 

448 
$v34 = $v12_ic*$sp*$sr + $v34_ic*$cp  $w_ic*$sp*$cr; #  defined for z upward => DL 

449 
$w12 =$v12_ic*$cp*$sr + $v34_ic*$sp + $w12_ic*$cp*$cr; 

450 
$w34 =$v12_ic*$cp*$sr + $v34_ic*$sp + $w34_ic*$cp*$cr; 

451 
} elsif (numberp($w12_ic)) { 

452 
$v12 = $v12_ic*$cr + $w12_ic*$sr; 

453 
$w12 =$v12_ic*$cp*$sr + $w12_ic*$cp*$cr; 

454 
} elsif (numberp($w34_ic)) { 

455 
$v34 = $v34_ic*$cp  $w34_ic*$sp*$cr; 

456 
$w34 = $v34_ic*$sp + $w34_ic*$cp*$cr; 

457 
} 

458 
} else { 

459 
if (numberp($w12_ic) && numberp($w34_ic)) { 

460 
$w_ic = ($w12_ic+$w34_ic) / 2; 

461 
$v12 =$v12_ic*$cr + $v34_ic*0  $w_ic*$sr; #  as above with 1st & 3rd cols negated 

462 
$v34 =$v12_ic*$sp*$sr + $v34_ic*$cp + $w_ic*$sp*$cr; 

463 
$w12 = $v12_ic*$cp*$sr + $v34_ic*$sp  $w12_ic*$cp*$cr; 

464 
$w34 = $v12_ic*$cp*$sr + $v34_ic*$sp  $w34_ic*$cp*$cr; 

465 
} elsif (numberp($w12_ic)) { 

466 
$v12 =$v12_ic*$cr  $w12_ic*$sr; 

467 
$w12 = $v12_ic*$cp*$sr  $w12_ic*$cp*$cr; 

468 
} elsif (numberp($w34_ic)) { 

469 
$v34 = $v34_ic*$cp + $w34_ic*$sp*$cr; 

470 
$w34 = $v34_ic*$sp  $w34_ic*$cp*$cr; 

471 
} 

0  472 
} 
473 

474 
return ($v12,$w12,$v34,$w34); 

475 
} 

476 
} 

477 

5  478 
#=================================================================== 
479 
# velBeamToBPInstrument(@) calculates the instrumentcoordinate vels 

480 
# from the two beam pairs separately. 

36
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

481 
#  in spite of the function name, the output is in ship 
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

482 
# coordinates (instr coords with w up) 
5  483 
#=================================================================== 
484 

485 
{ # STATIC SCOPE 

486 
my($TwoCosBAngle,$TwoSinBAngle); 

487 

488 
sub velBeamToBPInstrument(@) 

489 
{ 

35
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

490 
my($ADCP,$ens,$b1,$b2,$b3,$b4) = @_; 
5  491 
my($v12,$w12,$v34,$w34); 
492 

18  493 
return (undef,undef,undef,undef) 
35
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

494 
unless (defined($ADCP>{ENSEMBLE}[$ens]>{PITCH}) && 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

495 
defined($ADCP>{ENSEMBLE}[$ens]>{ROLL})); 
18  496 

5  497 
unless (defined($TwoCosBAngle)) { 
35
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

498 
$TwoCosBAngle = 2 * cos(rad($ADCP>{BEAM_ANGLE})); 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

499 
$TwoSinBAngle = 2 * sin(rad($ADCP>{BEAM_ANGLE})); 
5  500 
} 
501 

502 
# Sign convention: 

503 
#  refer to Coord manual Fig. 3 

504 
#  v12 is horizontal velocity from beam1 to beam2 

505 
#  w is +ve upward, regardless of instrument orientation 

506 

507 
if (defined($b1) && defined($b2)) { 

508 
$v12 = ($b1$b2)/$TwoSinBAngle; 

509 
$w12 = ($b1+$b2)/$TwoCosBAngle; 

35
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

510 
$w12 *= 1 if ($ADCP>{ENSEMBLE}[$ens]>{XDUCER_FACING_UP}); 
5  511 
} 
512 
if (defined($b3) && defined($b4)) { 

36
515b06dae59c
version at end of ECOGIG EN586 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
35
diff
changeset

513 
$v34 = ($b4$b3)/$TwoSinBAngle; 
5  514 
$w34 = ($b3+$b4)/$TwoCosBAngle; 
35
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

515 
$w34 *= 1 if ($ADCP>{ENSEMBLE}[$ens]>{XDUCER_FACING_UP}); 
5  516 
} 
517 

518 
return ($v12,$w12,$v34,$w34); 

519 
} 

520 
} 

521 

0  522 
#====================================================================== 
523 
# velApplyHdgBias() applies the heading bias, which is used to correct 

524 
# for magnetic declination for data recorded in Earthcoordinates ONLY. 

525 
# Bias correction for beamcoordinate data is done in velInstrumentToEarth() 

526 
#====================================================================== 

527 

6  528 
sub velApplyHdgBias(@) 
529 
{ 

35
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

530 
my($ADCP,$ens,$v1,$v2,$v3,$v4) = @_; 
18  531 
return (undef,undef,undef,undef) 
532 
unless (defined($v1) && defined($v2) && 

35
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

533 
defined($ADCP>{ENSEMBLE}[$ens]>{HEADING})); 
0  534 

35
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

535 
my($sh) = sin(rad($ADCP>{HEADING_BIAS})); 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

536 
my($ch) = cos(rad($ADCP>{HEADING_BIAS})); 
0  537 

6  538 
return ( $v1*$ch + $v2*$sh, 
539 
$v1*$sh + $v2*$ch, 

540 
$v3 , 

541 
$v4 ); 

542 
} 

0  543 

544 
# 

545 
# Pitch/Roll Functions 

546 
# 

547 

548 
sub gimbal_pitch($$) # RDI coord trans manual 

549 
{ 

5  550 
my($RDI_pitch,$RDI_roll) = @_; 
18  551 
return 'nan' unless defined($RDI_pitch) && defined($RDI_roll); 
5  552 
return deg(atan(tan(rad($RDI_pitch)) * cos(rad($RDI_roll)))); 
0  553 
} 
554 

14  555 
sub RDI_pitch($$) 
556 
{ 

557 
my($gimbal_pitch,$roll) = @_; 

18  558 
return 'nan' unless defined($gimbal_pitch) && defined($roll); 
14  559 
return deg(atan(tan(rad($gimbal_pitch))/cos(rad($roll)))); 
560 
} 

561 

562 
sub tilt_azimuth($$) 

563 
{ 

564 
my($gimbal_pitch,$roll) = @_; 

18  565 
return 'nan' unless defined($gimbal_pitch) && defined($roll); 
14  566 
return angle(deg(atan2(sin(rad($gimbal_pitch)),sin(rad($roll))))); 
567 
} 

568 

18  569 
#  angle from vertical is home grown 
0  570 
#  angle between two unit vectors given by acos(v1 dot v2) 
571 
#  vertical unit vector v1 = (0 0 1) => dot product = zcomponent of v2 

572 
#  when vertical unit vector is pitched in x direction, followed by 

573 
# roll in y direction: 

574 
# x = sin(pitch) 

575 
# y = cos(pitch) * sin(roll) 

576 
# z = cos(pitch) * cos(roll) 

577 
# has been checked with sqrt(x^2+y^2+z^2) == 1 

578 
#  for small angles, this is very similar to sqrt(pitch^2+roll^2) 

579 

580 
sub angle_from_vertical($$) 

581 
{ 

5  582 
my($RDI_pitch,$RDI_roll) = @_; 
18  583 
return 'nan' unless defined($RDI_pitch) && defined($RDI_roll); 
5  584 
my($rad_pitch) = atan(tan(rad($RDI_pitch)) * cos(rad($RDI_roll))); 
585 
return deg(acos(cos($rad_pitch) * cos(rad($RDI_roll)))); 

0  586 
} 
587 

35
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

588 
# 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

589 
# alongBeamDZ(ADCP_dta,ens,beam) => (dz_to_bin1_center,bin_dz) 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

590 
#  calculate vertical distances: 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

591 
#  between transducer and bin1 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

592 
#  between adjacent bins 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

593 
#  no soundspeed correction 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

594 
#  for UL (Fig. 3 Coord Manual): 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

595 
# b1 = phi + roll b2 = phi  roll 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

596 
# b3 = phi  pitch b4 = phi + pitch 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

597 
#  for DL: 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

598 
# b1 = phi + roll b2 = phi  roll 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

599 
# b3 = phi + pitch b4 = phi  pitch 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

600 
# 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

601 

7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

602 
sub alongBeamDZ($$$) 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

603 
{ 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

604 
my($ADCP,$ens,$beam) = @_; 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

605 

7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

606 
my($tilt); # determine tilt of given beam 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

607 
my($pitch) = $ADCP>{ENSEMBLE}[$ens]>{PITCH}; 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

608 
my($roll) = $ADCP>{ENSEMBLE}[$ens]>{ROLL}; 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

609 
if ($beam == 0) { # beam 1 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

610 
$tilt = &angle_from_vertical($pitch,$ADCP>{BEAM_ANGLE}+$roll); 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

611 
} elsif ($beam == 1) { # beam 2 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

612 
$tilt = &angle_from_vertical($pitch,$ADCP>{BEAM_ANGLE}$roll); 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

613 
} elsif ($beam == 2) { # beam 3 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

614 
$tilt = $ADCP>{ENSEMBLE}[$ens]>{XDUCER_FACING_UP} 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

615 
? &angle_from_vertical($ADCP>{BEAM_ANGLE}$pitch,$roll) 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

616 
: &angle_from_vertical($ADCP>{BEAM_ANGLE}+$pitch,$roll); 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

617 
} else { # beam 4 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

618 
$tilt = $ADCP>{ENSEMBLE}[$ens]>{XDUCER_FACING_UP} 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

619 
? &angle_from_vertical($ADCP>{BEAM_ANGLE}+$pitch,$roll) 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

620 
: &angle_from_vertical($ADCP>{BEAM_ANGLE}$pitch,$roll); 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

621 
} 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

622 
return ($ADCP>{DISTANCE_TO_BIN1_CENTER}*cos(rad($tilt)), 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

623 
$ADCP>{BIN_LENGTH}*cos(rad($tilt))); 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

624 
} 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

625 

7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

626 
# 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

627 
# binterp(ADCP_dta,ens,bin,ADCP_field) => @interpolated_vals 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

628 
#  interpolate beam velocities to nominal bin center 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

629 
#  field can be VELOCITY, ECHO_AMPLITUDE, ... 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

630 
# 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

631 
# earthVels(ADCP_dta,ens,bin) => (u,v,w,err_vel) 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

632 
# BPEarthVels(ADCP_dta,ens,bin) => (v12,w12,v34,w34) 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

633 
#  new interface (V1.7) 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

634 
# 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

635 

7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

636 
sub binterp1($$$$$) # interpolate along a single beam 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

637 
{ 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

638 
my($ADCP,$ens,$target_dz,$ADCP_field,$beam) = @_; 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

639 

7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

640 
my($dz2bin1,$bin_dz) = &alongBeamDZ($ADCP,$ens,$beam); 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

641 
my($floor_bin) = int(($target_dz$dz2bin1) / $bin_dz); 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

642 
$floor_bin if ($floor_bin == $ADCP>{N_BINS}1); 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

643 

7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

644 
my($y1) = $ADCP>{ENSEMBLE}[$ens]>{$ADCP_field}[$floor_bin][$beam]; 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

645 
my($y2) = $ADCP>{ENSEMBLE}[$ens]>{$ADCP_field}[$floor_bin+1][$beam]; 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

646 
$y2 = $y1 unless defined($y2); 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

647 
$y1 = $y2 unless defined($y1); 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

648 
return undef unless defined($y1); 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

649 

7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

650 
my($dz1) = $dz2bin1 + $floor_bin * $bin_dz; 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

651 
my($dz2) = $dz1 + $bin_dz; 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

652 
my($ifac) = ($target_dz  $dz1) / ($dz2  $dz1); 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

653 
die("assertion failed\nifac = $ifac (target_dz = $target_dz, dz1 = $dz1, dz2 = $dz2)") 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

654 
unless ($ifac>= 0.5 && $ifac<=2); 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

655 
return $y1 + $ifac*($y2$y1); 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

656 
} 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

657 

7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

658 
sub binterp($$$$) 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

659 
{ 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

660 
my($ADCP,$ens,$target_bin,$ADCP_field) = @_; 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

661 

7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

662 
my($crt) = cos(rad($ADCP>{ENSEMBLE}[$ens]>{TILT})); # calc center depth of target bin 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

663 
my($target_dz) = ($ADCP>{DISTANCE_TO_BIN1_CENTER} + $target_bin*$ADCP>{BIN_LENGTH}) * $crt; 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

664 

7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

665 
return (&binterp1($ADCP,$ens,$target_dz,$ADCP_field,0), # interpolate all four beams 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

666 
&binterp1($ADCP,$ens,$target_dz,$ADCP_field,1), 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

667 
&binterp1($ADCP,$ens,$target_dz,$ADCP_field,2), 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

668 
&binterp1($ADCP,$ens,$target_dz,$ADCP_field,3)); 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

669 
} 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

670 

7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

671 
sub earthVels($$$) 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

672 
{ 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

673 
my($ADCP,$ens,$bin) = @_; 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

674 
if ($RDI_Coords::binMapping eq 'linterp') { 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

675 
return velInstrumentToEarth($ADCP,$ens, 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

676 
velBeamToInstrument($ADCP,$ens, 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

677 
binterp($ADCP,$ens,$bin,'VELOCITY'))); 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

678 
} elsif ($RDI_Coords::binMapping eq 'none') { 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

679 
return velInstrumentToEarth($ADCP,$ens, 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

680 
velBeamToInstrument($ADCP,$ens, 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

681 
@{$ADCP>{ENSEMBLE}[$ens]>{VELOCITY}[$bin]})); 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

682 
} else { 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

683 
die("earthVels(): unknown bin mapping '$RDI_Coords::binMapping '\n"); 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

684 
} 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

685 
} 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

686 

7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

687 
sub BPEarthVels($$$) 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

688 
{ 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

689 
my($ADCP,$ens,$bin) = @_; 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

690 
if ($RDI_Coords::binMapping eq 'linterp') { 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

691 
return velBeamToBPEarth($ADCP,$ens,binterp($ADCP,$ens,$bin,'VELOCITY')); 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

692 
} elsif ($RDI_Coords::binMapping eq 'none') { 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

693 
return velBeamToBPEarth($ADCP,$ens,@{$ADCP>{ENSEMBLE}[$ens]>{VELOCITY}[$bin]}); 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

694 
} else { 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

695 
die("BPEarthVels(): unknown bin mapping '$RDI_Coords::binMapping '\n"); 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

696 
} 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

697 
} 
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

698 

7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

699 
# 
54  700 
# Sound Speed Correction for Vertical Velocity 
701 
#  Usage: sscorr_w(<observed w>,<beam_angle>,<ADCP sVel setup>,salin,temp,press,<vertical temp. gradient> 

702 
# 

703 

704 
sub sscorr_w($$$$$$$$) 

705 
{ 

706 
my($w,$beamAngle,$ssADCP,$salin,$temp,$press,$dz,$dtdz) = @_; 

707 

708 
return 'nan' unless numberp($w); 

709 
my($tanSqBeamAngle) = tan(rad($beamAngle))**2; 

710 

711 
my($ssXD) = sVel($salin,$temp,$press); 

712 
my($ssBin) = sVel($salin,$temp+$dz*$dtdz,$press$dz); 

713 
my($Kn) = sqrt(1 + (1  $ssBin/$ssXD)**2 * $tanSqBeamAngle); 

714 
return $w * $ssBin/$ssADCP / $Kn; 

715 
} 

716 

717 
# 

718 
# Sound Speed Correction for Vertical Velocity 

719 
#  Usage: sscorr_w_mooring(\$ADCP,<ensidx>,<binidx>,<press>,<salin>,<vertical temp. gradient>) 

720 
#  Notes: 

721 
#  RDI Coord. Trans. manual sec. 4.1 

722 
#  manual error: the ^2 applies to the [] 

723 
#  difference between pressure and depth over instrument range ignored 

724 
#  Assumptions: 

725 
#  libEOS83.pl loaded 

726 
#  $ADCP{ENSEMBLE}[$ensidx]>VELOCITY}[2] contains measured w 

727 
#  sound speed variation dominated by temperature 

728 
#  vertical temperature gradient is constant in time (violated 

729 
# at least on superinertial time scales) 

730 
# 

731 

732 
sub sscorr_w_mooring($$$$$) 

733 
{ 

734 
my($ADCP,$ei,$bi,$press,$salin,$dtdz) = @_; 

735 

736 
my($w) = $ADCP>{ENSEMBLE}[$ei]>{VELOCITY}[2]; 

737 
return 'nan' unless numberp($w); 

738 

739 
my($tanSqBeamAngle) = tan(rad($ADCP>{BEAM_ANGLE}))**2; 

740 

741 
$Global::P{ITS} = 90; 

742 
my($ssXD) = sVel($salin,$ADCP>{ENSEMBLE}[$ei]>{TEMPERATURE},$press); 

743 
my($ssADCP) = $ADCP>{ENSEMBLE}[$ei]>{SPEED_OF_SOUND}; 

744 

745 
my($dz) = $ADCP>{ENSEMBLE}[$ei]>{BLANKING_DISTANCE} + $bi * $ADCP>{ENSEMBLE}[$ei]>{BIN_LENGTH}; 

746 
$dz *= 1 if ($ADCP>{ENSEMBLE}[$ei]>{XDUCER_FACING_DOWN}); # z increases upward 

747 

748 
my($ssBin) = sVel($salin, 

749 
$ADCP>{ENSEMBLE}[$ei]>{TEMPERATURE} + $dz*$dtdz, 

750 
$press$dz); # ignore press/depth difference across range 

751 

752 
my($Kn) = sqrt(1 + (1  $ssBin/$ssXD)**2 * $tanSqBeamAngle); # RDI manual 

753 
return $w * $ssBin/$ssADCP / $Kn; 

754 
} 

755 

35
7c394a2d1fc9
before implementing 2nd order coord trans
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
34
diff
changeset

756 

0  757 
1; 