--- a/RDI_PD0_IO.pl
+++ b/RDI_PD0_IO.pl
@@ -1,9 +1,9 @@
#======================================================================
# R D I _ P D 0 _ I O . P L
# doc: Sat Jan 18 14:54:43 2003
-# dlm: Sat Jan 9 17:57:01 2016
+# dlm: Mon Feb 29 12:30:04 2016
# (c) 2003 A.M. Thurnherr
-# uE-Info: 73 64 NIL 0 0 72 10 2 4 NIL ofnI
+# uE-Info: 1232 63 NIL 0 0 72 10 2 4 NIL ofnI
#======================================================================
# Read RDI BroadBand Binary Data Files (*.[0-9][0-9][0-9])
@@ -71,6 +71,11 @@
# - added PRODUCER
# - BUG: writeData() did not work correctly for ECOGIG OC26 moored data (spaces in filename?)
# - added support for patching coordinate system
+# Feb 16, 2016: - added transducer orientation to WBPens()
+# - BUG: most WBPens() error messages used wrong file name
+# Feb 23, 2016: - changed WBRhdr() to use 2nd ensemble (with correct data-source id)
+# Feb 26, 2016: - added basic BT data to WBPens(); not BT_RL_* and BT_SIGNAL_STRENGTH
+# Feb 29, 2016: - LEAP DAY: actually got BT data to work
# FIRMWARE VERSIONS:
# It appears that different firmware versions generate different file
@@ -86,6 +91,11 @@
# PD0 FILE FORMAT EXTENSIONS:
#
+# - file creator encoded in DATA_SOURCE_ID
+#
+# - first ensemble uses default RDI DATA_SOURCE_ID because the LDEO_IX
+# software assumes this
+#
# - DATA_SOURCE_ID = 0x7F original TRDI PD0 file
#
# - DATA_SOURCE_ID = 0xA0 | PATCHED_MASK produced by IMP+LADP
@@ -376,7 +386,14 @@
# HEADER
#--------------------
- $start_ens = skip_initial_trash();
+ skip_initial_trash();
+ sysread(WBRF,$buf,6) == 6 || die("$WBRcfn: $!");
+ ($hid,$did,$dta->{ENSEMBLE_BYTES},$dummy,$dta->{NUMBER_OF_DATA_TYPES})
+ = unpack('CCvCC',$buf);
+ $hid == 0x7f || die(sprintf($FmtErr,$WBRcfn,"Header",$hid,0));
+ $did == 0x7f || die(sprintf($FmtErr,$WBRcfn,"Header",$did,0));
+
+ $start_ens = sysseek(WBRF,$dta->{ENSEMBLE_BYTES}-6+2,1) || die("$WBRcfn: $!");
sysread(WBRF,$buf,6) == 6 || die("$WBRcfn: $!");
($hid,$did,$dta->{ENSEMBLE_BYTES},$dummy,$dta->{NUMBER_OF_DATA_TYPES})
= unpack('CCvCC',$buf);
@@ -910,14 +927,12 @@
next if ($nxt == $ndt); # no BT found => next ens
- sysseek(WBRF,14,1) || die("$WBRcfn: $!"); # BT config
-
+ sysseek(WBRF,14,1) || die("$WBRcfn: $!"); # BT range, velocity, corr, %-good, ...
sysread(WBRF,$buf,28) == 28 || die("$WBRcfn: $!");
@dta = unpack('v4v4C4C4C4',$buf);
-
for ($beam=0; $beam<4; $beam++) {
- ${$E}[$ens]->{BT_RANGE}[$beam] = $dta[$beam] / 100
- if ($dta[$beam]);
+ ${$E}[$ens]->{BT_RANGE}[$beam] = $dta[$beam] / 100 # lower 2 bytes only!
+ if ($dta[$beam]); # (see below for high bytes)
}
for ($beam=0; $beam<4; $beam++) {
${$E}[$ens]->{BT_VELOCITY}[$beam] =
@@ -928,18 +943,16 @@
${$E}[$ens]->{BT_CORRELATION}[$beam] = $dta[8+$beam]
if ($dta[8+$beam]);
}
- for ($beam=0; $beam<4; $beam++) {
+ for ($beam=0; $beam<4; $beam++) { # BT filter parameter
${$E}[$ens]->{BT_EVAL_AMPLITUDE}[$beam] = $dta[12+$beam];
}
for ($beam=0; $beam<4; $beam++) {
${$E}[$ens]->{BT_PERCENT_GOOD}[$beam] = $dta[16+$beam];
}
- sysseek(WBRF,6,1) || die("$WBRcfn: $!"); # BT config
-
+ sysseek(WBRF,6,1) || die("$WBRcfn: $!"); # BT ref level stuff
sysread(WBRF,$buf,20) == 20 || die("$WBRcfn: $!");
@dta = unpack('v4C4C4C4',$buf);
-
for ($beam=0; $beam<4; $beam++) {
${$E}[$ens]->{BT_RL_VELOCITY}[$beam] =
unpack('s',pack('S',$dta[$beam])) / 1000
@@ -956,17 +969,15 @@
${$E}[$ens]->{BT_RL_PERCENT_GOOD}[$beam] = $dta[12+$beam];
}
- sysseek(WBRF,2,1) || die("$WBRcfn: $!"); # BT config
-
+ sysseek(WBRF,2,1) || die("$WBRcfn: $!"); # BT signal strength & BT range high bytes
sysread(WBRF,$buf,9) == 9 || die("$WBRcfn: $!");
@dta = unpack('C4CC4',$buf);
-
for ($beam=0; $beam<4; $beam++) {
${$E}[$ens]->{BT_SIGNAL_STRENGTH}[$beam] = $dta[$beam];
}
${$E}[$ens]->{HIGH_GAIN} if ($dta[4]);
${$E}[$ens]->{LOW_GAIN} unless ($dta[4]);
- for ($beam=0; $beam<4; $beam++) {
+ for ($beam=0; $beam<4; $beam++) { # high bytes (1 byte per beam)
${$E}[$ens]->{BT_RANGE}[$beam] += $dta[5+$beam] * 655.36
if ($dta[5+$beam]);
}
@@ -1051,7 +1062,18 @@
# Fixed Leader
#--------------------
- sysseek(WBPF,$start_ens+$WBPofs[0]+25,0) || die("$WBPcfn: $!"); # jump to EX/Coord-Transform
+ sysseek(WBPF,$start_ens+$WBPofs[0]+4,0) # system config (transducer orientation)
+ || die("$WBPcfn: $!");
+ sysread(WBPF,$buf,1) == 1 || die("$WBPcfn: $!");
+ $B1 = unpack('C',$buf);
+ $B1 |= 0x80 if ($dta->{ENSEMBLE}[$ens]->{XDUCER_FACING_UP});
+ $B1 &= 0x7F if ($dta->{ENSEMBLE}[$ens]->{XDUCER_FACING_DOWN});
+ $buf = pack('C',$B1);
+ sysseek(WBPF,$start_ens+$WBPofs[0]+4,0)
+ || die("$WBPcfn: $!");
+ syswrite(WBPF,$buf,1) == 1 || die("$WBPcfn: $!");
+
+ sysseek(WBPF,$start_ens+$WBPofs[0]+25,0) || die("$WBPcfn: $!"); # EX / coord-transformation
sysread(WBPF,$buf,1) == 1 || die("$WBPcfn: $!");
my($EX) = unpack('C',$buf);
if ($dta->{BEAM_COORDINATES}) {
@@ -1073,9 +1095,9 @@
$dta->{ENSEMBLE}[$ens]->{XDUCER_DEPTH} = round($dta->{ENSEMBLE}[$ens]->{XDUCER_DEPTH}*10);
- #-----------------------------
- # IMP allows for missing value
- #-----------------------------
+ #---------------------------------
+ # NB: IMP allows for missing value
+ #---------------------------------
$dta->{ENSEMBLE}[$ens]->{HEADING} = defined($dta->{ENSEMBLE}[$ens]->{HEADING})
? round($dta->{ENSEMBLE}[$ens]->{HEADING}*100)
@@ -1104,7 +1126,7 @@
# Velocity Data
#--------------------
- sysseek(WBPF,$start_ens+$WBPofs[2]+2,0) || die("$WBRcfn: $!"); # skip velocity data id (assume it is correct)
+ sysseek(WBPF,$start_ens+$WBPofs[2]+2,0) || die("$WBPcfn: $!"); # skip velocity data id (assume it is correct)
for ($bin=0; $bin<$nbins; $bin++) {
for ($beam=0; $beam<4; $beam++) {
$dta->{ENSEMBLE}[$ens]->{VELOCITY}[$bin][$beam] = defined($dta->{ENSEMBLE}[$ens]->{VELOCITY}[$bin][$beam])
@@ -1120,7 +1142,7 @@
# Correlation Data
#--------------------
- sysseek(WBPF,$start_ens+$WBPofs[3]+2,0) || die("$WBRcfn: $!");
+ sysseek(WBPF,$start_ens+$WBPofs[3]+2,0) || die("$WBPcfn: $!");
for ($bin=0; $bin<$nbins; $bin++) {
for ($beam=0; $beam<4; $beam++) {
$buf = pack('C',$dta->{ENSEMBLE}[$ens]->{CORRELATION}[$bin][$beam]);
@@ -1133,7 +1155,7 @@
# Echo Intensity Data
#--------------------
- sysseek(WBPF,$start_ens+$WBPofs[4]+2,0) || die("$WBRcfn: $!");
+ sysseek(WBPF,$start_ens+$WBPofs[4]+2,0) || die("$WBPcfn: $!");
for ($bin=0; $bin<$nbins; $bin++) {
for ($beam=0; $beam<4; $beam++) {
@@ -1147,7 +1169,7 @@
# Percent Good Data
#--------------------
- sysseek(WBPF,$start_ens+$WBPofs[5]+2,0) || die("$WBRcfn: $!");
+ sysseek(WBPF,$start_ens+$WBPofs[5]+2,0) || die("$WBPcfn: $!");
for ($i=0,$bin=0; $bin<$nbins; $bin++) {
for ($beam=0; $beam<4; $beam++,$i++) {
@@ -1164,17 +1186,55 @@
my($nxt);
for ($nxt=6; $nxt<$ndt; $nxt++) { # scan until BT found
- sysseek(WBPF,$start_ens+$WBPofs[$nxt],0) || die("$WBRcfn: $!");
- sysread(WBPF,$buf,2) == 2 || die("$WBRcfn: $!");
+ sysseek(WBPF,$start_ens+$WBPofs[$nxt],0) || die("$WBPcfn: $!");
+ sysread(WBPF,$buf,2) == 2 || die("$WBPcfn: $!");
$id = unpack('v',$buf);
last if ($id == 0x0600);
}
unless ($nxt == $ndt) { # BT found
- sysseek(WBPF,14,1) || die("$WBRcfn: $!"); # skip BT config
- # NOT YET IMPLEMENTED
- }
+ sysseek(WBPF,14,1) || die("$WBPcfn: $!"); # skip BT config
+ for ($beam=0; $beam<4; $beam++) { # BT range low bytes (2 per beam)
+ $buf = pack('v',round($dta->{ENSEMBLE}[$ens]->{BT_RANGE}[$beam] * 100) & 0xFFFF);
+ my($nw) = syswrite(WBPF,$buf,2);
+ $nw == 2 || die("$WBPcfn: $nw bytes written ($!)");
+ }
+
+ for ($beam=0; $beam<4; $beam++) { # BT velocities
+ $buf = pack('v',unpack('S',pack('s',
+ defined($dta->{ENSEMBLE}[$ens]->{BT_VELOCITY}[$beam])
+ ? round($dta->{ENSEMBLE}[$ens]->{BT_VELOCITY}[$beam]*1000)
+ : 0x8000)));
+ my($nw) = syswrite(WBPF,$buf,2);
+ $nw == 2 || die("$WBPcfn: $nw bytes written ($!)");
+ }
+
+ for ($beam=0; $beam<4; $beam++) { # BT correlation
+ $buf = pack('C',$dta->{ENSEMBLE}[$ens]->{BT_CORRELATION}[$beam]);
+ my($nw) = syswrite(WBPF,$buf,1);
+ $nw == 1 || die("$WBPcfn: $nw bytes written ($!)");
+ }
+
+ for ($beam=0; $beam<4; $beam++) { # BT evaluation amp of matching filter
+ $buf = pack('C',$dta->{ENSEMBLE}[$ens]->{BT_EVAL_AMPLITUDE}[$beam]);
+ my($nw) = syswrite(WBPF,$buf,1);
+ $nw == 1 || die("$WBPcfn: $nw bytes written ($!)");
+ }
+
+ for ($beam=0; $beam<4; $beam++) { # BT percent good
+ $buf = pack('C',$dta->{ENSEMBLE}[$ens]->{BT_PERCENT_GOOD}[$beam]);
+ my($nw) = syswrite(WBPF,$buf,1);
+ $nw == 1 || die("$WBPcfn: $nw bytes written ($!)");
+ }
+ sysseek(WBPF,33,1) || die("$WBPcfn: $!"); # BT range high bytes (1 per beam)
+ for ($beam=0; $beam<4; $beam++) {
+ $buf = pack('C',(round($dta->{ENSEMBLE}[$ens]->{BT_RANGE}[$beam]*100) & 0xFF0000) >> 16);
+ my($nw) = syswrite(WBPF,$buf,1);
+ $nw == 1 || die("$WBPcfn: $nw bytes written ($!)");
+ }
+
+ } # if BT found
#----------------
# Update Checksum