author | A.M. Thurnherr <athurnherr@yahoo.com> |
Sun, 21 Oct 2018 19:52:56 -0400 | |
changeset 43 | b63fa355644c |
parent 33 | 307630665c6c |
permissions | -rwxr-xr-x |
0 | 1 |
#!/usr/bin/perl |
2 |
#====================================================================== |
|
3 |
# L I S T W |
|
4 |
# doc: Wed Mar 24 06:45:09 2004 |
|
43
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
33
diff
changeset
|
5 |
# dlm: Mon Apr 2 18:32:03 2018 |
0 | 6 |
# (c) 2004 A.M. Thurnherr |
43
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
33
diff
changeset
|
7 |
# uE-Info: 25 61 NIL 0 0 72 0 2 4 NIL ofnI |
0 | 8 |
#====================================================================== |
9 |
||
10 |
# dump vertical velocities |
|
11 |
||
12 |
# NB: currently broken |
|
13 |
||
14 |
# HISTORY: |
|
15 |
# Mar 24, 2004: - created from [listens] and [mkprofile] |
|
16 |
# Mar 27, 2004: - added elapsed field |
|
17 |
# - floatized time |
|
18 |
# Apr 3, 2004: - cosmetics |
|
19 |
# Nov 8, 2005: - UNIXTIME => UNIX_TIME |
|
20 |
# Sep 19, 2007: - adapted to new [RDI_BB_Read.pl] (not tested) |
|
21 |
# Jul 30, 2009: - NaN => nan |
|
14 | 22 |
# Nov 25, 2013: - checkEnsemble() expunged |
33 | 23 |
# Mar 17, 2016: - removed warning |
24 |
# - updated ancient library names |
|
43
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
33
diff
changeset
|
25 |
# Apr 2, 2018: - BUG: velBeamToInstrument() used old usage |
0 | 26 |
|
27 |
$0 =~ m{(.*)/[^/]+}; |
|
33 | 28 |
require "$1/RDI_PD0_IO.pl"; |
29 |
require "$1/RDI_Coords.pl"; |
|
30 |
require "$1/RDI_Utils.pl"; |
|
0 | 31 |
|
32 |
use Getopt::Std; |
|
33 |
||
34 |
$USAGE = "$0 @ARGV"; |
|
35 |
die("Usage: $0 " . |
|
36 |
"[-A)nts] " . |
|
37 |
"[-F)ilter <script>] " . |
|
38 |
"[bin -r)ange <bin|0,bin|*>] " . |
|
39 |
"[-e)rr-vel <max|0.1>] [-c)orrelation <min|70>] " . |
|
40 |
"[-S)alin <val|35>] [-t)emp <bias>] " . |
|
41 |
"[output -f)ields <field[,...]> " . |
|
42 |
"<RDI file>\n") |
|
43 |
unless (&getopts("Ac:e:F:f:r:S:t:") && @ARGV == 1); |
|
44 |
||
45 |
$opt_e = 0.1 unless defined($opt_e); # defaults |
|
46 |
$opt_c = 70 unless defined($opt_c); |
|
47 |
$opt_S = 35 unless defined($opt_S); |
|
48 |
print(STDERR "WARNING: Using uncalibrated ADCP temperature!\n"),$opt_t = 0 |
|
49 |
unless defined($opt_t); |
|
50 |
||
51 |
require $opt_F if defined($opt_F); # load filter |
|
52 |
||
53 |
if ($opt_f) { # additional fields |
|
54 |
@f = split(',',$opt_f); |
|
55 |
foreach $f (@f) { |
|
56 |
my($f) = $f; # copy it |
|
57 |
$f =~ s{\[.*$}{}; # remove indices |
|
58 |
$addFields .= " {$f}"; |
|
59 |
} |
|
60 |
} |
|
61 |
||
62 |
#---------------------------------------------------------------------- |
|
63 |
||
64 |
print(STDERR "Reading $ARGV[0]..."); # read data |
|
65 |
readData($ARGV[0],\%dta); |
|
66 |
print(STDERR "done\n"); |
|
67 |
||
68 |
if (defined($opt_r)) { # bin range |
|
69 |
($minb,$maxb) = split(',',$opt_r); |
|
70 |
die("$0: can't decode -r $opt_r\n") unless defined($maxb); |
|
71 |
} else { |
|
72 |
$minb = 0; |
|
73 |
$maxb = $dta{N_BINS} - 1; |
|
74 |
} |
|
75 |
||
76 |
die("$ARGV[0]: not enough bins for choice of -r\n") # enough bins? |
|
77 |
unless ($dta{N_BINS} >= $maxb); |
|
78 |
||
79 |
if ($dta{BEAM_COORDINATES}) { # coords used |
|
80 |
$beamCoords = 1; |
|
81 |
} elsif (!$dta{EARTH_COORDINATES}) { |
|
82 |
die("$ARGV[0]: only beam and earth coordinates implemented so far\n"); |
|
83 |
} |
|
84 |
||
85 |
#---------------------------------------------------------------------- |
|
86 |
# Reference-Layer w (from [mkprofile]) |
|
87 |
# - also sets W field when valid |
|
88 |
#---------------------------------------------------------------------- |
|
89 |
||
90 |
sub ref_lr_w($) |
|
91 |
{ |
|
92 |
my($ens) = @_; |
|
93 |
my($i,$n,$w); |
|
94 |
||
95 |
for ($i=$minb; $i<=$maxb; $i++) { |
|
96 |
next if ($dta{ENSEMBLE}[$ens]->{CORRELATION}[$i][0] < $opt_c || |
|
97 |
$dta{ENSEMBLE}[$ens]->{CORRELATION}[$i][1] < $opt_c || |
|
98 |
$dta{ENSEMBLE}[$ens]->{CORRELATION}[$i][2] < $opt_c || |
|
99 |
$dta{ENSEMBLE}[$ens]->{CORRELATION}[$i][3] < $opt_c); |
|
100 |
if ($beamCoords) { |
|
101 |
next if ($dta{ENSEMBLE}[$ens]->{PERCENT_GOOD}[$i][0] < 100 || |
|
102 |
$dta{ENSEMBLE}[$ens]->{PERCENT_GOOD}[$i][1] < 100 || |
|
103 |
$dta{ENSEMBLE}[$ens]->{PERCENT_GOOD}[$i][2] < 100 || |
|
104 |
$dta{ENSEMBLE}[$ens]->{PERCENT_GOOD}[$i][3] < 100); |
|
105 |
@v = velInstrumentToEarth(\%dta,$ens, |
|
43
b63fa355644c
commit to merge with changes from EN620
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
33
diff
changeset
|
106 |
velBeamToInstrument(\%dta,$ens, |
0 | 107 |
@{$dta{ENSEMBLE}[$ens]->{VELOCITY}[$i]})); |
108 |
} else { |
|
109 |
next if ($dta{ENSEMBLE}[$ens]->{PERCENT_GOOD}[$i][0] > 0 || |
|
110 |
$dta{ENSEMBLE}[$ens]->{PERCENT_GOOD}[$i][1] > 0 || |
|
111 |
$dta{ENSEMBLE}[$ens]->{PERCENT_GOOD}[$i][2] > 0 || |
|
112 |
$dta{ENSEMBLE}[$ens]->{PERCENT_GOOD}[$i][3] < 100); |
|
113 |
@v = @{$dta{ENSEMBLE}[$ens]->{VELOCITY}[$i]}; |
|
114 |
} |
|
115 |
next if (!defined($v[3]) || abs($v[3]) > $opt_e); |
|
116 |
||
117 |
if (defined($v[2])) { # valid w |
|
118 |
$dta{ENSEMBLE}[$ens]->{W}[$i] = $v[2]; |
|
119 |
$w += $v[2]; $n++; |
|
120 |
} |
|
121 |
} |
|
122 |
return $n ? $w/$n : undef; |
|
123 |
} |
|
124 |
||
125 |
#---------------------------------------------------------------------- |
|
126 |
||
127 |
print(STDERR "Generating profile by integrating w..."); |
|
128 |
||
129 |
for ($e=0; $e<=$#{$dta{ENSEMBLE}}; $e++) { |
|
130 |
filterEnsemble(\%dta,$e) # filter ensemble |
|
131 |
if (defined($opt_F) && |
|
132 |
$dta{ENSEMBLE}[$e]->{PERCENT_GOOD}[0][0] > 0); |
|
133 |
||
134 |
$dta{ENSEMBLE}[$e]->{REFW} = ref_lr_w($e); |
|
135 |
next unless defined($dta{ENSEMBLE}[$e]->{REFW}); |
|
136 |
||
137 |
unless (defined($firstgood)) { # init profile |
|
138 |
$firstgood = $lastgood = $e; |
|
139 |
$depth = 0; |
|
140 |
} |
|
141 |
||
142 |
my($dt) = $dta{ENSEMBLE}[$e]->{UNIX_TIME} - # time step since |
|
143 |
$dta{ENSEMBLE}[$lastgood]->{UNIX_TIME}; # ... last good ens |
|
144 |
if ($dt > 120) { |
|
145 |
printf(STDERR "\nWARNING: %d-s gap too long, profile restarted at ensemble $e...",$dt); |
|
146 |
$firstgood = $lastgood = $e; |
|
147 |
$dt = $depth = 0; |
|
148 |
} |
|
149 |
||
150 |
$depth += $dta{ENSEMBLE}[$lastgood]->{REFW} * $dt # integrate depth |
|
151 |
if ($dt > 0); |
|
152 |
$dta{ENSEMBLE}[$e]->{DEPTH} = $depth; |
|
153 |
$atbottom = $e, $maxdepth = $depth if ($depth > $maxdepth); |
|
154 |
||
155 |
my($ss) = soundSpeed($opt_S, # sound-speed corr |
|
156 |
$dta{ENSEMBLE}[$e]->{TEMPERATURE}-$opt_t, |
|
157 |
$depth); |
|
158 |
$dta{ENSEMBLE}[$e]->{SPEED_OF_SOUND_CORRECTION} = |
|
159 |
$ss / $dta{ENSEMBLE}[$e]->{SPEED_OF_SOUND}; |
|
160 |
$dta{ENSEMBLE}[$e]->{SPEED_OF_SOUND} = $ss; |
|
161 |
$dta{ENSEMBLE}[$e]->{REFW} *= |
|
162 |
$dta{ENSEMBLE}[$e]->{SPEED_OF_SOUND_CORRECTION}; |
|
163 |
||
164 |
$lastgood = $e; |
|
165 |
} |
|
166 |
||
167 |
printf(STDERR "done (max depth = %.1fm, depth at end of cast = %.1fm)\n", |
|
168 |
$maxdepth,$depth); |
|
169 |
||
170 |
filterEnsembleStats() if defined($opt_F); |
|
171 |
||
172 |
#---------------------------------------------------------------------- |
|
173 |
||
174 |
print(STDERR "Writing output..."); |
|
175 |
||
176 |
if ($opt_A) { |
|
177 |
print("#ANTS# [] $USAGE\n"); |
|
178 |
print("#ANTS#FIELDS# {ens} {unix_time} {time} {bin} {depth} {dz} {w} {ref_w} {dw} $addFields\n"); |
|
179 |
printf("#ANTS#PARAMS# maxdepth{$max_depth} bottom_time{%d}\n", |
|
180 |
$dta{ENSEMBLE}[$atbottom]->{UNIX_TIME} - |
|
181 |
$dta{ENSEMBLE}[$firstgood]->{UNIX_TIME}); |
|
182 |
} else { |
|
183 |
print("# ens-no time elapsed bin-no depth dz w ref-w dw $addFields\n"); |
|
184 |
print("#----------------------------------------------------------------------\n"); |
|
185 |
} |
|
186 |
||
187 |
for ($e=$firstgood; $e<=$lastgood; $e++) { |
|
188 |
||
189 |
for ($i=$minb; $i<=$maxb; $i++) { # dump valid |
|
190 |
next unless defined($dta{ENSEMBLE}[$e]->{W}[$i]); |
|
191 |
||
192 |
printf("%d %f %f %d %.1f %.1f %g %g %g ", |
|
193 |
$e,$dta{ENSEMBLE}[$e]->{UNIX_TIME}, |
|
194 |
$dta{ENSEMBLE}[$e]->{UNIX_TIME} - |
|
195 |
$dta{ENSEMBLE}[$firstgood]->{UNIX_TIME},$i, |
|
196 |
$dta{ENSEMBLE}[$e]->{DEPTH} + |
|
197 |
$dta{ENSEMBLE}[$e]->{SPEED_OF_SOUND_CORRECTION} * |
|
198 |
($dta{DISTANCE_TO_BIN1_CENTER} + $i*$dta{BIN_LENGTH}), |
|
199 |
$dta{ENSEMBLE}[$e]->{SPEED_OF_SOUND_CORRECTION} * |
|
200 |
($dta{DISTANCE_TO_BIN1_CENTER} + $i*$dta{BIN_LENGTH}), |
|
201 |
$dta{ENSEMBLE}[$e]->{SPEED_OF_SOUND_CORRECTION} * |
|
202 |
$dta{ENSEMBLE}[$e]->{W}[$i], |
|
203 |
$dta{ENSEMBLE}[$e]->{REFW}, |
|
204 |
$dta{ENSEMBLE}[$e]->{SPEED_OF_SOUND_CORRECTION} * |
|
205 |
$dta{ENSEMBLE}[$e]->{W}[$i] - $dta{ENSEMBLE}[$e]->{REFW}, |
|
206 |
); |
|
207 |
||
208 |
sub p($) { print(defined($_[0])?"$_[0] ":"nan "); } |
|
209 |
||
33 | 210 |
if (@f) { |
0 | 211 |
foreach $f (@f) { |
212 |
my($fn,$fi) = ($f =~ m{([^[]*)(\[.*)}); |
|
213 |
$fn = $f unless defined($fn); |
|
214 |
p(eval("\$dta{ENSEMBLE}[$e]->{$fn}$fi")); |
|
215 |
} |
|
216 |
} |
|
217 |
print("\n"); |
|
218 |
} |
|
219 |
} |
|
220 |
||
221 |
print(STDERR "done\n"); |
|
222 |
||
223 |
exit(0); |
|
224 |