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