RDI_PD0_IO.pl
changeset 32 7155adf61d77
parent 31 b6ca27a1d19c
child 36 515b06dae59c
--- 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