|
1 #!/usr/bin/perl |
|
2 #====================================================================== |
|
3 # L I S T E N S |
|
4 # doc: Sat Jan 18 18:41:49 2003 |
|
5 # dlm: Thu Jul 30 17:42:09 2009 |
|
6 # (c) 2003 A.M. Thurnherr |
|
7 # uE-Info: 247 47 NIL 0 0 72 2 2 4 NIL ofnI |
|
8 #====================================================================== |
|
9 |
|
10 # Print useful info from the ensemble list or dump ensembles to |
|
11 # separate files. |
|
12 |
|
13 # HISTORY: |
|
14 # Jan 18, 2003: - created |
|
15 # Mar 18, 2004: - updated |
|
16 # Sep 15, 2005: - made ESW optional (BB150) |
|
17 # - change RDI binread library name |
|
18 # Aug 25, 2006: - added -r)ange |
|
19 # - added write -E)nsembles |
|
20 # Aug 26, 2006: - added -M)agdecl |
|
21 # Sep 19, 2007: - adapted to new [RDI_BB_Read.pl] (not tested) |
|
22 # Jan 26, 2008: - BUG: diagnostic output had been written to STDOUT |
|
23 # Feb 1, 2008: - BUG: still more diagnostic output written to STDOUT |
|
24 # - BUG: -E/-A combo had ignored -E |
|
25 # - changed %-good fieldnames for earth coordinates |
|
26 # - allowed for 3-beam solutions |
|
27 # Feb 7, 2008: - added -f)ields |
|
28 # Apr 4, 2008: - made -f output nan on undefined values |
|
29 # - BUG: -f fields did not allow array indices |
|
30 # - added in-w)ater data only |
|
31 # - restructured for simplicity |
|
32 # Mar 2, 2009: - added # of valid bin-1 vels to non-ANTS output |
|
33 # Jul 30, 2009: - NaN => nan |
|
34 |
|
35 # Notes: |
|
36 # - -E outputs data in earth coordinates |
|
37 # - -E output is always in ANTS format, ignoring -A |
|
38 # - no soundspeed correction |
|
39 |
|
40 require "getopts.pl"; |
|
41 $0 =~ m{(.*/)[^/]+}; |
|
42 require "$1RDI_BB_Read.pl"; |
|
43 require "$1RDI_Coords.pl"; |
|
44 |
|
45 die("Usage: $0 [-A)nts] [-Q)uiet (errcheck only)] " . |
|
46 "[-f)ields <[name=]FIELD[,...]>] " . |
|
47 "[write -E)nsemples <pref> [-M)agnetic <declination>] [min -p)ercent-good <#>]] " . |
|
48 "[-r)ange <first_ens,last_ens>] [in-w)ater ensembles only]" . |
|
49 "<RDI file...>\n") |
|
50 unless (&Getopts("AE:f:M:p:Qr:w") && $#ARGV >= 0); |
|
51 |
|
52 print(STDERR "WARNING: magnetic declination not set!\n") |
|
53 if defined($opt_E) && !defined($opt_M); |
|
54 |
|
55 die("$0: illegal option combination\n") |
|
56 if ($opt_Q && $opt_A) || ((defined($opt_M) || defined($opt_p)) && !defined($opt_E)); |
|
57 |
|
58 ($first_ens,$last_ens) = split(',',$opt_r) |
|
59 if defined($opt_r); |
|
60 |
|
61 undef($opt_A) if defined($opt_E); |
|
62 |
|
63 $opt_p = 0 unless defined($opt_p); |
|
64 |
|
65 if ($opt_f) { # additional fields |
|
66 @addFields = split(',',$opt_f); |
|
67 foreach my $f (@addFields) { |
|
68 $f =~ s/\s//g; # remove spaces |
|
69 @def = split('=',$f); |
|
70 if (@def == 2) { # name=field |
|
71 $addLayout .= $opt_A ? " {$def[0]}" : " $def[0]"; |
|
72 $f = $def[1]; |
|
73 } else { # field |
|
74 $addLayout .= " {$f}"; |
|
75 } |
|
76 } |
|
77 # print(STDERR "addLayout = $addLayout\n"); |
|
78 # print(STDERR "\@addFields = @addFields\n"); |
|
79 } |
|
80 |
|
81 #---------------------------------------------------------------------- |
|
82 # MAIN |
|
83 #---------------------------------------------------------------------- |
|
84 |
|
85 while (-f $ARGV[0]) { |
|
86 if ($opt_A && !$opt_E) { |
|
87 print("#ANTS#PARAMS# RDI_file{$ARGV[0]}\n"); |
|
88 } elsif (!$opt_Q) { |
|
89 print(STDERR "$ARGV[0]: "); |
|
90 } |
|
91 readData(@ARGV,\%dta); |
|
92 printf(STDERR "%d complete ensembles...\n",scalar(@{$dta{ENSEMBLE}})) |
|
93 unless ($opt_Q); |
|
94 $dta{HEADING_BIAS} = -$opt_M; # magnetic declination |
|
95 shift; |
|
96 |
|
97 if ($dta{BEAM_COORDINATES}) { # coords used |
|
98 $beamCoords = 1; |
|
99 } elsif (!$dta{EARTH_COORDINATES}) { |
|
100 die("$ARGV[0]: only beam and earth coordinates implemented so far\n"); |
|
101 } |
|
102 |
|
103 if ($opt_A) { # select output fmt: ANTS |
|
104 unless ($opt_Q) { |
|
105 printf("#ANTS#PARAMS# N_ensembles{%d}\n",scalar(@{$dta{ENSEMBLE}})); |
|
106 print('#ANTS#FIELDS# {ens} {time} {xducer_up} {temp} {hdg} {pitch} {roll} {XMIT_VOLTAGE} {XMIT_CURRENT}'); |
|
107 print(' {ESW}') if ($dta{DATA_FORMAT} eq 'WH300'); |
|
108 print("$addLayout\n"); |
|
109 } |
|
110 |
|
111 $dumpEns = sub ($) |
|
112 { |
|
113 my($e) = @_; |
|
114 |
|
115 printf('%d %lf %d %g %g %g %g %g %g', |
|
116 $dta{ENSEMBLE}[$e]->{NUMBER}, |
|
117 $dta{ENSEMBLE}[$e]->{UNIX_TIME}, |
|
118 $dta{ENSEMBLE}[$e]->{XDUCER_FACING_UP} ? 1 : 0, |
|
119 $dta{ENSEMBLE}[$e]->{TEMPERATURE}, |
|
120 $dta{ENSEMBLE}[$e]->{HEADING}, |
|
121 $dta{ENSEMBLE}[$e]->{PITCH}, |
|
122 $dta{ENSEMBLE}[$e]->{ROLL}, |
|
123 $dta{ENSEMBLE}[$e]->{ADC_XMIT_VOLTAGE}, |
|
124 $dta{ENSEMBLE}[$e]->{ADC_XMIT_CURRENT}, |
|
125 ); |
|
126 printf(' %08X',$dta{ENSEMBLE}[$e]->{ERROR_STATUS_WORD}) |
|
127 if ($dta{DATA_FORMAT} eq 'WH300'); |
|
128 foreach my $f (@addFields) { |
|
129 my($fn,$fi) = ($f =~ m{([^[]*)(\[.*)}); |
|
130 $fn = $f unless defined($fn); |
|
131 my($v) = eval("\$dta{ENSEMBLE}[$e]->{$fn}$fi"); |
|
132 print(defined($v) ? " $v" : " nan"); |
|
133 } |
|
134 print("\n"); |
|
135 } |
|
136 |
|
137 } elsif ($opt_E) { # one file per ens |
|
138 |
|
139 $dumpEns = sub ($) |
|
140 { |
|
141 my($e) = @_; |
|
142 my($b,$i); |
|
143 my($file) = "$opt_E.$dta{ENSEMBLE}[$e]->{NUMBER}"; |
|
144 |
|
145 open(P,">$file") || die("$file: $!\n"); |
|
146 print(P "#ANTS#PARAMS# " . |
|
147 "BT_u{$dta{ENSEMBLE}[$e]->{BT_VELOCITY}[0]} " . |
|
148 "BT_v{$dta{ENSEMBLE}[$e]->{BT_VELOCITY}[1]} " . |
|
149 "BT_w{$dta{ENSEMBLE}[$e]->{BT_VELOCITY}[2]} " . |
|
150 "BT_e{$dta{ENSEMBLE}[$e]->{BT_VELOCITY}[3]} " . |
|
151 "BT_cor1{$dta{ENSEMBLE}[$e]->{BT_CORRELATION}[0]} " . |
|
152 "BT_cor2{$dta{ENSEMBLE}[$e]->{BT_CORRELATION}[1]} " . |
|
153 "BT_cor3{$dta{ENSEMBLE}[$e]->{BT_CORRELATION}[2]} " . |
|
154 "BT_cor4{$dta{ENSEMBLE}[$e]->{BT_CORRELATION}[3]} " . |
|
155 "BT_amp1{$dta{ENSEMBLE}[$e]->{BT_AMPLITUDE}[0]} " . |
|
156 "BT_amp2{$dta{ENSEMBLE}[$e]->{BT_AMPLITUDE}[1]} " . |
|
157 "BT_amp3{$dta{ENSEMBLE}[$e]->{BT_AMPLITUDE}[2]} " . |
|
158 "BT_amp4{$dta{ENSEMBLE}[$e]->{BT_AMPLITUDE}[3]} " . |
|
159 "\n" |
|
160 ); |
|
161 print(P "#ANTS#FIELDS# " . |
|
162 "{dz} {u} {v} {w} {e} {cor1} {cor2} {cor3} {cor4} " . |
|
163 "{amp1} {amp2} {amp3} {amp4} " |
|
164 ); |
|
165 if ($beamCoords) { |
|
166 print(P "{pcg1} {pcg2} {pcg3} {pcg4}"); |
|
167 } else { |
|
168 print(P "{pc3beam} {pcBadErrVel} {pc1or2beam} {pc4beam}"); |
|
169 } |
|
170 print(P "$addLayout\n"); |
|
171 |
|
172 for (my($b)=0; $b<$dta{N_BINS}; $b++) { |
|
173 my(@v); |
|
174 my($dz) = $dta{DISTANCE_TO_BIN1_CENTER} + $b*$dta{BIN_LENGTH}; |
|
175 |
|
176 if ($beamCoords) { |
|
177 undef($dta{ENSEMBLE}[$e]->{VELOCITY}[$b][0]) |
|
178 if ($dta{ENSEMBLE}[$e]->{PERCENT_GOOD}[$b][0] < $opt_p); |
|
179 undef($dta{ENSEMBLE}[$e]->{VELOCITY}[$b][1]) |
|
180 if ($dta{ENSEMBLE}[$e]->{PERCENT_GOOD}[$b][1] < $opt_p); |
|
181 undef($dta{ENSEMBLE}[$e]->{VELOCITY}[$b][2]) |
|
182 if ($dta{ENSEMBLE}[$e]->{PERCENT_GOOD}[$b][2] < $opt_p); |
|
183 undef($dta{ENSEMBLE}[$e]->{VELOCITY}[$b][3]) |
|
184 if ($dta{ENSEMBLE}[$e]->{PERCENT_GOOD}[$b][3] < $opt_p); |
|
185 @v = velInstrumentToEarth(\%dta,$e, |
|
186 velBeamToInstrument(\%dta, |
|
187 @{$dta{ENSEMBLE}[$e]->{VELOCITY}[$b]})); |
|
188 } else { |
|
189 @v = velApplyHdgBias(\%dta,$e,@{$dta{ENSEMBLE}[$e]->{VELOCITY}[$b]}); |
|
190 } |
|
191 |
|
192 $v[0] = nan unless defined($v[0]); |
|
193 $v[1] = nan unless defined($v[1]); |
|
194 $v[2] = nan unless defined($v[2]); |
|
195 $v[3] = nan unless defined($v[3]); |
|
196 my(@out) = ( |
|
197 $dz,$v[0],$v[1],$v[2],$v[3], |
|
198 @{$dta{ENSEMBLE}[$e]->{CORRELATION}[$b]}, |
|
199 @{$dta{ENSEMBLE}[$e]->{ECHO_AMPLITUDE}[$b]}, |
|
200 @{$dta{ENSEMBLE}[$e]->{PERCENT_GOOD}[$b]} |
|
201 ); |
|
202 foreach my $f (@addFields) { |
|
203 my($fn,$fi) = ($f =~ m{([^[]*)(\[.*)}); |
|
204 $fn = $f unless defined($fn); |
|
205 push(@out,eval("\$dta{ENSEMBLE}[$e]->{$fn}$fi")); |
|
206 } |
|
207 for ($i=0; $i<17+@addFields; $i++) { |
|
208 $out[$i] = nan unless defined($out[$i]); |
|
209 } |
|
210 print(P "@out\n"); |
|
211 } |
|
212 close(P); |
|
213 } |
|
214 |
|
215 } else { # neither ANTS nor ens files |
|
216 unless ($opt_Q) { |
|
217 if ($dta{DATA_FORMAT} eq 'WH300') { |
|
218 printf(" # Date Time XD Temp Headng Pitch Roll vels(bin1) ESW$addLayout\n"); |
|
219 printf("-----------------------------------------------------------------------\n"); |
|
220 } else { |
|
221 printf(" # Date Time XD Temp Headng Pitch Roll vels(bin1)$addLayout\n"); |
|
222 printf("-------------------------------------------------------------------\n"); |
|
223 } |
|
224 } |
|
225 |
|
226 $dumpEns = sub ($) |
|
227 { |
|
228 my($e) = @_; |
|
229 |
|
230 printf('%5d %s %s %s %5.1f %6.1f %5.1f %5.1f %3d', |
|
231 $dta{ENSEMBLE}[$e]->{NUMBER}, |
|
232 $dta{ENSEMBLE}[$e]->{DATE}, |
|
233 $dta{ENSEMBLE}[$e]->{TIME}, |
|
234 $dta{ENSEMBLE}[$e]->{XDUCER_FACING_UP} ? "UP" : "DN", |
|
235 $dta{ENSEMBLE}[$e]->{TEMPERATURE}, |
|
236 $dta{ENSEMBLE}[$e]->{HEADING}, |
|
237 $dta{ENSEMBLE}[$e]->{PITCH}, |
|
238 $dta{ENSEMBLE}[$e]->{ROLL}, |
|
239 $dta{ENSEMBLE}[$e]->{BIN1VELS}, |
|
240 ); |
|
241 printf(' 0x%08X',$dta{ENSEMBLE}[$e]->{ERROR_STATUS_WORD}) |
|
242 if ($dta{DATA_FORMAT} eq 'WH300'); |
|
243 foreach my $f (@addFields) { |
|
244 my($fn,$fi) = ($f =~ m{([^[]*)(\[.*)}); |
|
245 $fn = $f unless defined($fn); |
|
246 my($v) = eval("\$dta{ENSEMBLE}[$e]->{$fn}$fi"); |
|
247 print(defined($v) ? " $v" : " nan"); |
|
248 } |
|
249 print("\n"); |
|
250 } |
|
251 |
|
252 } |
|
253 |
|
254 for ($e=0; $e<=$#{$dta{ENSEMBLE}}; $e++) { |
|
255 next if (defined($first_ens) && |
|
256 $dta{ENSEMBLE}[$e]->{NUMBER} < $first_ens); |
|
257 last if (defined($last_ens) && |
|
258 $dta{ENSEMBLE}[$e]->{NUMBER} > $last_ens); |
|
259 $dta{ENSEMBLE}[$e]->{BIN1VELS} = |
|
260 defined($dta{ENSEMBLE}[$e]->{VELOCITY}[1][0]) + |
|
261 defined($dta{ENSEMBLE}[$e]->{VELOCITY}[1][1]) + |
|
262 defined($dta{ENSEMBLE}[$e]->{VELOCITY}[1][2]) + |
|
263 defined($dta{ENSEMBLE}[$e]->{VELOCITY}[1][3]); |
|
264 next if ($opt_w && $dta{ENSEMBLE}[$e]->{BIN1VELS}<3); |
|
265 |
|
266 die("3-beams used in ensemble #$dta{ENSEMBLE}[$e]->{NUMBER}\n") |
|
267 if ($dta{ENSEMBLE}[$e]->{N_BEAMS_USED} < 4); |
|
268 die("BIT error in ensemble $dta{ENSEMBLE}[$e]->{NUMBER}\n") |
|
269 if defined($dta{ENSEMBLE}[$e]->{BUILT_IN_TEST_ERROR}); |
|
270 die("Low gain in ensemble #$dta{ENSEMBLE}[$e]->{NUMBER}\n") |
|
271 if ($dta{ENSEMBLE}[$e]->{LOW_GAIN}); |
|
272 |
|
273 &$dumpEns($e) |
|
274 unless ($opt_Q); |
|
275 } |
|
276 } |
|
277 |
|
278 exit(0); |