29
|
1 |
#!/usr/bin/perl
|
|
2 |
#======================================================================
|
|
3 |
# L A D C P _ W _ R E G R I D
|
|
4 |
# doc: Fri Apr 24 17:15:59 2015
|
30
|
5 |
# dlm: Mon Jul 27 17:20:23 2015
|
29
|
6 |
# (c) 2015 A.M. Thurnherr
|
30
|
7 |
# uE-Info: 182 21 NIL 0 0 72 2 2 4 NIL ofnI
|
29
|
8 |
#======================================================================
|
|
9 |
|
|
10 |
$antsSummary = 'edit and re-grid LADCP vertical-velocity samples';
|
|
11 |
$antsMinLibVersion = 6.1;
|
|
12 |
|
|
13 |
# HISTORY:
|
|
14 |
# Apr 24, 2015: - created
|
|
15 |
# Apr 25, 2015: - maded gridding work
|
|
16 |
# Apr 26, 2015: - made editing work
|
|
17 |
# Apr 27, 2015: - added -p
|
|
18 |
# May 5, 2015: - modified Editfile syntax to use parens()
|
|
19 |
# May 7, 2015: - allow leading whitespace before Editfile labels
|
|
20 |
# May 17, 2015: - removed warning about missing ./Editfile
|
|
21 |
# May 18, 2015: - added important %PARAMs for dual-head data
|
|
22 |
# - updated to libV6.1
|
|
23 |
# May 19, 2015: - added hab to output
|
|
24 |
# - allow setting %PARAMS in Editfile
|
|
25 |
# May 20, 2015: - Editfile => EditParams
|
|
26 |
# Jun 18, 2015: - added -i
|
|
27 |
# - implemented default output on -t stdout
|
|
28 |
# - changed to libGMT.pl
|
|
29 |
# - removed dead -d option
|
30
|
30 |
# Jul 26, 2015: - adapted for %outgrid_*
|
|
31 |
# Jul 27, 2015: - B-t)rack <wprof>
|
29
|
32 |
|
|
33 |
($ANTS) = (`which ANTSlib` =~ m{^(.*)/[^/]*$});
|
|
34 |
|
|
35 |
die("$0: ANTSlib required but not found (bad \$PATH?)\n")
|
|
36 |
unless ($ANTS ne '');
|
|
37 |
|
|
38 |
require "$ANTS/ants.pl";
|
|
39 |
require "$ANTS/libstats.pl";
|
|
40 |
require "$ANTS/libGMT.pl";
|
|
41 |
|
30
|
42 |
&antsUsage('b:i:k:o:p:t:',1,
|
29
|
43 |
'[profile -i)d <id>]',
|
|
44 |
'[-o)utput bin <resolution[10m]>] [-k) require <min> samples]',
|
30
|
45 |
# '[valid LADCP -b)ins <bin[2],bin[*][,bin[2],bin[*]]>',
|
|
46 |
'[-p)lot <[%03d_wprof.eps]> [B-t)rack <wprof>]]',
|
29
|
47 |
'<.samp file> [.samp file]');
|
|
48 |
|
|
49 |
$dual_head = (@ARGV==1);
|
|
50 |
|
|
51 |
$opt_o_override = defined($opt_o);
|
30
|
52 |
$opt_o = $P{outgrid_dz};
|
29
|
53 |
&antsCardOpt(\$opt_o,10);
|
|
54 |
|
|
55 |
$opt_k_override = defined($opt_k);
|
|
56 |
$opt_k = 2 * $P{ouput_grid_minsamp}
|
|
57 |
if defined($P{ouput_grid_minsamp});
|
|
58 |
&antsCardOpt(\$opt_k,$dual_head?40:20);
|
|
59 |
|
30
|
60 |
if (defined($opt_b)) {
|
|
61 |
croak("$0: -b not implemented yet\n");
|
|
62 |
($LADCP_firstBin,$LADCP_lastBin) = split(',',$opt_b);
|
|
63 |
croak("$0: cannot decode -b $opt_b\n")
|
|
64 |
unless (numberp($LADCP_firstBin) &&
|
|
65 |
($LADCP_lastBin eq '*' || numberp($LADCP_lastBin)));
|
|
66 |
}
|
29
|
67 |
|
|
68 |
#----------------------------------------------------------------------
|
|
69 |
# Redirect STDOUT to %.wprof & create %_wprof.ps if STDOUT is a tty
|
|
70 |
#----------------------------------------------------------------------
|
|
71 |
|
|
72 |
$id = defined($opt_i) ? $opt_i : &antsParam('profile_id');
|
|
73 |
croak("$0: no profile_id in first file => -i required\n")
|
|
74 |
unless defined($id);
|
|
75 |
|
|
76 |
if (-t STDOUT) {
|
|
77 |
$opt_p = '%03d_wprof.ps' unless defined($opt_p);
|
|
78 |
$outfile = sprintf('%03d.wprof',$id);
|
|
79 |
open(STDOUT,">$outfile") || die("$outfile: $!\n");
|
|
80 |
}
|
|
81 |
|
30
|
82 |
croak("$0: -t only makes sense when a plot is produced\n")
|
|
83 |
if $opt_t && !defined($opt_p);
|
|
84 |
|
29
|
85 |
#----------------------------------------------------------------------
|
|
86 |
# Library
|
|
87 |
#----------------------------------------------------------------------
|
|
88 |
|
|
89 |
my(@dscMin,@dscMax,@dscDUc);
|
|
90 |
|
|
91 |
sub discard($$$) # define bad-data filter
|
|
92 |
{
|
|
93 |
my($fnm,$min,$max) = @_;
|
|
94 |
my($fnr) = fnr($fnm);
|
|
95 |
$dscMin[$fnr] = numberp($min) ? $min : -9e99;
|
|
96 |
$dscMax[$fnr] = numberp($max) ? $max : 9e99;
|
|
97 |
$dscDUc[$fnr] = 2;
|
|
98 |
}
|
|
99 |
|
|
100 |
sub discard_dc($$$) # define bad-data filter
|
|
101 |
{
|
|
102 |
my($fnm,$min,$max) = @_;
|
|
103 |
my($fnr) = fnr($fnm);
|
|
104 |
$dscMin[$fnr] = numberp($min) ? $min : -9e99;
|
|
105 |
$dscMax[$fnr] = numberp($max) ? $max : 9e99;
|
|
106 |
$dscDUc[$fnr] = 1;
|
|
107 |
}
|
|
108 |
|
|
109 |
sub discard_uc($$$) # define bad-data filter
|
|
110 |
{
|
|
111 |
my($fnm,$min,$max) = @_;
|
|
112 |
my($fnr) = fnr($fnm);
|
|
113 |
$dscMin[$fnr] = numberp($min) ? $min : -9e99;
|
|
114 |
$dscMax[$fnr] = numberp($max) ? $max : 9e99;
|
|
115 |
$dscDUc[$fnr] = 0;
|
|
116 |
}
|
|
117 |
|
|
118 |
sub isBad()
|
|
119 |
{
|
|
120 |
for (my($f)=0; $f<$antsBufNFields; $f++) {
|
|
121 |
next unless defined($dscDUc[$f]);
|
|
122 |
next unless ($dscDUc[$f]==2 || $dscDUc[$f]==$ants_[0][$dcF]);
|
|
123 |
return 1 unless ($ants_[0][$f] < $dscMin[$f]) ||
|
|
124 |
($ants_[0][$f] > $dscMax[$f]);
|
|
125 |
}
|
|
126 |
return 0;
|
|
127 |
}
|
|
128 |
|
|
129 |
#----------------------------------------------------------------------
|
|
130 |
# Edit Data
|
|
131 |
#----------------------------------------------------------------------
|
|
132 |
|
|
133 |
$wF = &fnr('w');
|
|
134 |
$eF = &fnr('elapsed');
|
|
135 |
$dF = &fnr('depth');
|
30
|
136 |
$bF = &fnr('bin');
|
29
|
137 |
$dcF = &fnr('downcast');
|
|
138 |
|
|
139 |
$first_label = &antsRequireParam('run_label');
|
|
140 |
$bin_length = &antsRequireParam('ADCP_bin_length');
|
|
141 |
$pulse_length = &antsRequireParam('ADCP_pulse_length');
|
|
142 |
$blanking_dist = &antsRequireParam('ADCP_blanking_distance');
|
|
143 |
($dayNoP,$dn) = &antsFindParam('dn\d\d');
|
|
144 |
croak("$0: cannot determine day number\n")
|
|
145 |
unless defined($dayNoP);
|
|
146 |
|
|
147 |
my($R,$R2);
|
|
148 |
if ($opt_p) { # begin plot
|
|
149 |
$xmin = -0.1; $x2min = -200;
|
|
150 |
$xmax = 0.35; $x2max = 200;
|
|
151 |
$ymin = 0;
|
|
152 |
$ymax = antsParam('water_depth');
|
|
153 |
$ymax = antsRequireParam('max_depth') unless defined($ymax);
|
|
154 |
$plotsize = 13;
|
|
155 |
$R = "-R$xmin/$xmax/$ymin/$ymax";
|
|
156 |
$R2 = "-R$x2min/$x2max/$ymin/$ymax";
|
|
157 |
GMT_begin(sprintf($opt_p,$id),"-JX$plotsize/-$plotsize",$R,'-X6 -Y4');
|
|
158 |
GMT_psxy('-W1');
|
|
159 |
print(GMT "0 $ymin\n0 $ymax");
|
|
160 |
GMT_psxy('-L -G200');
|
|
161 |
print(GMT "0.07 $ymin\n0.07 $ymax\n0.18 $ymax\n0.18 $ymin\n");
|
|
162 |
GMT_setR($R2);
|
|
163 |
GMT_psxy('-M -W1');
|
|
164 |
print(GMT ">\n50 $ymin\n50 $ymax\n");
|
|
165 |
print(GMT ">\n100 $ymin\n100 $ymax\n");
|
|
166 |
print(GMT ">\n150 $ymin\n150 $ymax\n");
|
|
167 |
GMT_setR($R);
|
30
|
168 |
|
|
169 |
if (defined($opt_t)) {
|
|
170 |
open(BT,$opt_t) || croak("$opt_t: $!\n");
|
|
171 |
@BTL = &antsFileLayout(BT);
|
|
172 |
my($BTwf,$BTdf,$BTmf,$BTnf);
|
|
173 |
for (my($f)=0; $f<=$#BTL; $f++) {
|
|
174 |
$BTdf = $f if ($BTL[$f] eq 'depth');
|
|
175 |
$BTwf = $f if ($BTL[$f] eq 'BT_w');
|
|
176 |
$BTmf = $f if ($BTL[$f] eq 'BT_w.mad');
|
|
177 |
$BTnf = $f if ($BTL[$f] eq 'BT_w.nsamp');
|
|
178 |
}
|
|
179 |
croak("$opt_t: file-layout error\n")
|
|
180 |
unless defined($BTdf) && defined($BTwf) &&
|
|
181 |
defined($BTmf) && defined($BTnf);
|
|
182 |
GMT_psxy('-W6');
|
|
183 |
while (@BT = &antsFileIn(BT)) {
|
|
184 |
next unless numberp($BT[$BTwf]);
|
|
185 |
printf(GMT "%f %f\n",$BT[$BTwf],$BT[$BTdf]);
|
|
186 |
}
|
|
187 |
}
|
29
|
188 |
}
|
|
189 |
|
|
190 |
$min_depth = 9e99; # sentinels
|
|
191 |
$max_depth = -9e99;
|
|
192 |
|
|
193 |
$curF = ''; # current input file (sentinel)
|
|
194 |
$filt = 0;
|
|
195 |
for (my($curF),$r=0; &antsIn(); $r++) {
|
|
196 |
if ($P{PATHNAME} ne $curF) { # new file
|
|
197 |
$curF = $P{PATHNAME};
|
|
198 |
|
30
|
199 |
&antsInfo("WARNING: inconsistent %outgrid_dz in input files")
|
|
200 |
if (defined($P{outgrid_dz}) && $P{outgrid_dz}!=$opt_o &&!$opt_o_override);
|
|
201 |
&antsInfo("WARNING: inconsistent %outgrid_minsamp in input files")
|
|
202 |
if (defined($P{outgrid_minsamp}) && $P{outgrid_minsamp}*2!=$opt_k &&!$opt_k_override);
|
29
|
203 |
|
|
204 |
$bin_length = sprintf('%d & %d',round($bin_length),($P{ADCP_bin_length}))
|
|
205 |
unless (round($bin_length) == round($P{ADCP_bin_length}));
|
|
206 |
$pulse_length = sprintf('%d & %d',round($pulse_length),round($P{ADCP_pulse_length}))
|
|
207 |
unless (round($pulse_length) == round($P{ADCP_pulse_length}));
|
|
208 |
$blanking_dist = sprintf('%d & %d',round($blanking_dist),($P{ADCP_blanking_distance}))
|
|
209 |
unless (round($blanking_dist) == round($P{ADCP_blanking_distance}));
|
|
210 |
|
|
211 |
$PROF = $STN = $id; $RUN = antsRequireParam('run_label');
|
|
212 |
undef(@dscMin); undef(@dscMax);
|
|
213 |
do "./EditParams";
|
|
214 |
|
|
215 |
if (@dcw1) { # 2nd file in dual-head profile => plot 1st
|
|
216 |
GMT_psxy('-W2,255/127/80,-');
|
|
217 |
for (my($bi)=0; $bi<=$#dcw1; $bi++) {
|
|
218 |
printf(GMT "%f %f\n",median(@{$dcw1[$bi]}),($bi+0.5)*$opt_o);
|
|
219 |
}
|
|
220 |
GMT_psxy('-W2,46/139/87,-');
|
|
221 |
for (my($bi)=0; $bi<=$#ucw1; $bi++) {
|
|
222 |
printf(GMT "%f %f\n",median(@{$ucw1[$bi]}),($bi+0.5)*$opt_o);
|
|
223 |
}
|
|
224 |
undef(@dcw1); undef(@ucw1);
|
|
225 |
}
|
|
226 |
}
|
30
|
227 |
next if ($ants_[0][$bF]<$P{outgrid_firstbin}-1 || $ants_[0][$bF]>$P{outgrid_lastbin}-1);
|
29
|
228 |
$filt++,next if &isBad();
|
|
229 |
$min_depth = $ants_[0][$dF] if ($ants_[0][$dF] < $min_depth);
|
|
230 |
$max_depth = $ants_[0][$dF] if ($ants_[0][$dF] > $max_depth);
|
|
231 |
my($bi) = $ants_[0][$dF]/$opt_o;
|
|
232 |
if ($ants_[0][$dcF]) { # downcast
|
|
233 |
push(@{$dcw[$bi]},$ants_[0][$wF]); # vertical velocity
|
|
234 |
push(@{$dcw1[$bi]},$ants_[0][$wF]) if ($dual_head);
|
|
235 |
push(@{$dce[$bi]},$ants_[0][$eF]); # elapsed time
|
|
236 |
} else { # upcast
|
|
237 |
push(@{$ucw[$bi]},$ants_[0][$wF]);
|
|
238 |
push(@{$ucw1[$bi]},$ants_[0][$wF]) if ($dual_head);
|
|
239 |
push(@{$uce[$bi]},$ants_[0][$eF]);
|
|
240 |
}
|
|
241 |
}
|
|
242 |
|
|
243 |
if (@dcw1) { # 2nd file in dual-head profile in buffer => plot it
|
|
244 |
GMT_psxy('-W2,255/127/80,.');
|
|
245 |
for (my($bi)=0; $bi<=$#dcw1; $bi++) {
|
|
246 |
printf(GMT "%f %f\n",median(@{$dcw1[$bi]}),($bi+0.5)*$opt_o);
|
|
247 |
}
|
|
248 |
GMT_psxy('-W2,46/139/87,.');
|
|
249 |
for (my($bi)=0; $bi<=$#ucw1; $bi++) {
|
|
250 |
printf(GMT "%f %f\n",median(@{$ucw1[$bi]}),($bi+0.5)*$opt_o);
|
|
251 |
}
|
|
252 |
}
|
|
253 |
|
|
254 |
&antsInfo("%d measurements edited (%d%% of total)",$filt,round(100*$filt/$r))
|
|
255 |
if ($filt > 0);
|
|
256 |
|
|
257 |
#----------------------------------------------------------------------
|
|
258 |
# Average and Output Profile, Add to Plot
|
|
259 |
#----------------------------------------------------------------------
|
|
260 |
|
|
261 |
@antsNewLayout = ('depth','hab',
|
|
262 |
'dc_elapsed','dc_w','dc_w.mad','dc_w.nsamp',
|
|
263 |
'uc_elapsed','uc_w','uc_w.mad','uc_w.nsamp');
|
|
264 |
|
|
265 |
if ($dual_head) { # selected %PARAMs only
|
|
266 |
&antsAddParams('profile_id',$id,'lat',$P{lat},'lon',$P{lon});
|
|
267 |
&antsAddParams($dayNoP,$dn,'run_label',"$first_label & $P{run_label}");
|
30
|
268 |
&antsAddParams('outgrid_dz',$opt_o,'outgrid_minsamp',$opt_k);
|
|
269 |
&antsAddParams('outgrid_firstbin',$P{outgrid_firstbin},'outgrid_lastbin',$P{outgrid_lastbin});
|
29
|
270 |
&antsAddParams('ADCP_bin_length',round($bin_length),'ADCP_pulse_length',round($pulse_length))
|
|
271 |
&antsAddParams('ADCP_blanking_distance',round($blanking_dist));
|
|
272 |
&antsAddParams('min_depth',round($min_depth),'max_depth',round($max_depth));
|
|
273 |
&antsAddParams('water_depth',$P{water_depth},'water_depth.sig',$P{water_depth.sig});
|
|
274 |
undef($antsOldHeaders);
|
|
275 |
}
|
|
276 |
|
|
277 |
&antsInfo("WARNING: unknown water depth (no height-above-bottom)")
|
|
278 |
unless numberp($P{water_depth});
|
|
279 |
|
|
280 |
my(@dcwm,@ucwm,@dcns,@ucns,@dcwmad,@ucwmad);
|
|
281 |
for (my($bi)=0; $bi<=max($#dcw,$#ucw); $bi++) {
|
|
282 |
$dcwm[$bi] = median(@{$dcw[$bi]});
|
|
283 |
$ucwm[$bi] = median(@{$ucw[$bi]});
|
|
284 |
$dcns[$bi] = @{$dcw[$bi]};
|
|
285 |
$ucns[$bi] = @{$ucw[$bi]};
|
|
286 |
$dcwmad[$bi] = mad2($dcwm[$bi],@{$dcw[$bi]});
|
|
287 |
$ucwmad[$bi] = mad2($ucwm[$bi],@{$ucw[$bi]});
|
|
288 |
push(@{$out[$bi]},
|
|
289 |
($bi+0.5)*$opt_o,
|
|
290 |
(numberp($P{water_depth}) ? $P{water_depth}-($bi+0.5)*$opt_o : nan),
|
|
291 |
avg(@{$dce[$bi]}),
|
|
292 |
(($dcns[$bi]>=$opt_k)?$dcwm[$bi]:nan),(($dcns[$bi]>=$opt_k)?$dcmad[$bi]:nan),
|
|
293 |
scalar(@{$dcw[$bi]}),
|
|
294 |
avg(@{$uce[$bi]}),
|
|
295 |
(($ucns[$bi]>=$opt_k)?$ucwm[$bi]:nan),(($ucns[$bi]>=$opt_k)?$ucmad[$bi]:nan),
|
|
296 |
scalar(@{$ucw[$bi]}));
|
|
297 |
&antsOut(@{$out[$bi]});
|
|
298 |
}
|
|
299 |
|
|
300 |
if ($opt_p) { # complete plot
|
|
301 |
GMT_setR($R);
|
|
302 |
|
|
303 |
GMT_psxy('-W4,255/127/80'); # median profiles
|
|
304 |
for (my($bi)=0; $bi<=$#dcw1; $bi++) {
|
|
305 |
printf(GMT "%f %f\n",$dcwm[$bi],($bi+0.5)*$opt_o);
|
|
306 |
}
|
|
307 |
GMT_psxy('-W4,46/139/87');
|
|
308 |
for (my($bi)=0; $bi<=$#ucw1; $bi++) {
|
|
309 |
printf(GMT "%f %f\n",$ucwm[$bi],($bi+0.5)*$opt_o);
|
|
310 |
}
|
|
311 |
|
|
312 |
GMT_psxy('-Sc0.1 -G255/127/80'); # m.a.d. profiles
|
|
313 |
for (my($bi)=0; $bi<=$#dcw1; $bi++) {
|
|
314 |
printf(GMT "%f %f\n",$dcwmad[$bi],($bi+0.5)*$opt_o);
|
|
315 |
}
|
|
316 |
GMT_psxy('-Sc0.1 -G46/139/87');
|
|
317 |
for (my($bi)=0; $bi<=$#ucw1; $bi++) {
|
|
318 |
printf(GMT "%f %f\n",$ucwmad[$bi],($bi+0.5)*$opt_o);
|
|
319 |
}
|
|
320 |
|
|
321 |
GMT_setR($R2);
|
|
322 |
GMT_psxy('-Mn -W1,255/127/80');
|
|
323 |
for (my($bi)=0; $bi<=$#dcw1; $bi++) {
|
|
324 |
printf(GMT "%f %f\n",$dcns[$bi],($bi+0.5)*$opt_o);
|
|
325 |
}
|
|
326 |
GMT_psxy('-Mn -W1,46/139/87');
|
|
327 |
for (my($bi)=0; $bi<=$#dcw1; $bi++) {
|
|
328 |
printf(GMT "%f %f\n",$ucns[$bi],($bi+0.5)*$opt_o);
|
|
329 |
}
|
|
330 |
|
|
331 |
GMT_psbasemap('-Bf10a1000-950:" # of Samples":N');
|
|
332 |
GMT_psbasemap('-Ba1000-900N'); GMT_psbasemap('-Ba1000-850N');
|
|
333 |
|
|
334 |
$depth_tics = ($ymax-$ymin< 1000) ? 'f10a100' : 'f100a500';
|
|
335 |
GMT_setR($R);
|
|
336 |
GMT_psbasemap('-Bf0.01a10-10.05:"Vertical Velocity [m/s] ":/' .
|
|
337 |
$depth_tics . ':"Depth [m]":WeS');
|
|
338 |
GMT_psbasemap('-Ba10-9.95S'); GMT_psbasemap('-Ba10-9.85S');
|
|
339 |
|
|
340 |
GMT_setR('-R0/1/0/1');
|
|
341 |
GMT_pstext('-Gblue -N');
|
|
342 |
if (defined($outfile)) { print(GMT "0.01 -0.06 14 0 0 TL $outfile\n"); }
|
|
343 |
else { printf(GMT "0.01 -0.06 14 0 0 TL %03d\n",$id); }
|
|
344 |
GMT_pstext();
|
|
345 |
print(GMT '0.62 0.98 12 0 0 MR m.a.d.');
|
|
346 |
GMT_end();
|
|
347 |
}
|
|
348 |
|
|
349 |
&antsExit(0);
|