- adapted to work with IMPed moored ADCP data
authorAndreas Thurnherr <ant@ldeo.columbia.edu>
Mon, 20 Apr 2020 15:42:28 -0400
changeset 52 5b07a9b89aee
parent 51 148c092b3a09
child 53 51c5988a7f1f
- adapted to work with IMPed moored ADCP data - fixed bug in RDI_PD0_IO
RDI_PD0_IO.pl
RDI_Utils.pl
patchPD0
--- 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: Sun Apr 12 20:02:30 2020
+#                    dlm: Tue Apr 14 21:43:23 2020
 #                    (c) 2003 A.M. Thurnherr
-#					 uE-Info: 123 72 NIL 0 0 72 0 2 4 NIL ofnI
+#					 uE-Info: 126 73 NIL 0 0 72 0 2 4 NIL ofnI
 #======================================================================
     
 # Read RDI PD0 binary data files (*.[0-9][0-9][0-9])
@@ -121,7 +121,9 @@
 #	Feb 13, 2020: - added support for $readDataProgress (to Jun 13 version)
 #	Apr 12, 2020: - merged laptop and whoosher versions which both implemented
 #					progreass; not sure whether this merge is successful
-	
+#				  - disabled duplicate ens detection, which turns reading into
+#					O(N^2) process
+#	Apr 14, 2020: - BUG: WBPens did not work for ens# > 65535 (high byte)	
     
 # FIRMWARE VERSIONS:
 #	It appears that different firmware versions generate different file
@@ -831,15 +833,18 @@
 		sysread(WBRF,$buf,1) == 1 || die("$WBRcfn: $!");
 		$ensNo += unpack('C',$buf) << 16;
 
-		for (my($i)=$ens; $i>0; $i--) {											# check for duplicate ens; e.g. 2018 S4P 24UL
-			if (${$E}[$i]->{NUMBER} == $ensNo) {									
-				$RDI_PD0_IO::File_Dirty = 1;
-				print(STDERR "WARNING (RDI_PD0_IO): duplicate ensemble $ensNo skipped\n");
-				pop(@{$E});
-				$ens--;
-				next ENSEMBLE;
-			}
-		}
+##		CODE DISABLED BECAUSE IT TAKES TOO MUCH TIME ON LARGE FILES.
+##		NOT SURE HOW COMMON DUPLICATE ENSEMBLES ARE.		
+##
+##		for (my($i)=$ens; $i>0; $i--) {											# check for duplicate ens; e.g. 2018 S4P 24UL
+##			if (${$E}[$i]->{NUMBER} == $ensNo) {									
+##				$RDI_PD0_IO::File_Dirty = 1;
+##				print(STDERR "WARNING (RDI_PD0_IO): duplicate ensemble $ensNo skipped\n");
+##				pop(@{$E});
+##				$ens--;
+##				next ENSEMBLE;
+##			}
+##		}
 		    
 		${$E}[$ens]->{NUMBER} = $ensNo;
 	    
@@ -1117,8 +1122,8 @@
 	print(STDERR "\n") if ($RDI_PD0_IO::show_progress);
 }
 
-sub WBRdtaIndex($)
-{
+sub WBRdtaIndex($)																# return index of particular data type
+{																				#	where index refers to data sections inside PD0 files
 	my($trgid) = @_;
 	our($ndt,$buf,$id,$start_ens,@WBRofs);
 	
@@ -1250,7 +1255,7 @@
 		sysseek(WBPF,$start_ens+$WBPofs[1]+2,0) || die("$WBPcfn: $!");
 		sysread(WBPF,$buf,2) == 2 || die("$WBPcfn: $!");
 		my($ensNo) = unpack("v",$buf);											# only lower two bytes!!!
-		sysseek(WBPF,$start_ens+$WBPofs[1]+13,0) || die("$WBPcfn: $!");			# jump to high byte
+		sysseek(WBPF,$start_ens+$WBPofs[1]+11,0) || die("$WBPcfn: $!");			# jump to high byte
 		sysread(WBPF,$buf,1) == 1 || die("$WBPcfn: $!");
 		$ensNo += unpack('C',$buf) << 16;
 		die("ensNo = $ensNo (should be $dta->{ENSEMBLE}[$ens]->{NUMBER})\n")
--- a/RDI_Utils.pl
+++ b/RDI_Utils.pl
@@ -1,9 +1,9 @@
 #======================================================================
 #                    R D I _ U T I L S . P L 
 #                    doc: Wed Feb 12 10:21:32 2003
-#                    dlm: Wed Jun 26 09:05:05 2019
+#                    dlm: Mon Apr 13 14:07:54 2020
 #                    (c) 2003 A.M. Thurnherr
-#                    uE-Info: 300 27 NIL 0 0 72 0 2 4 NIL ofnI
+#                    uE-Info: 68 53 NIL 0 0 72 0 2 4 NIL ofnI
 #======================================================================
 
 # miscellaneous RDI-specific utilities
@@ -65,9 +65,12 @@
 #					- disable %-good screening with $min_pctg == 0
 # 	Jun 26, 2019: - increased short-gap in mk_prof from 5s to 6s to allow processing
 #					of RTi test file with 5s ensembles
+#	Apr 13, 2020: - added $RDI_Utils::No_Gap_Warnings
 
 use strict;
 
+$RDI_Utils::No_Gap_Warnings = 0;		# set to 1 to suppress gap warnings
+
 #======================================================================
 # fake_BT_RANGE(dta ptr)
 #======================================================================
@@ -514,7 +517,7 @@
 		} elsif ($dt > 15) {
 	       	printf(STDERR "WARNING: long-ish w gap at ens#%d-%d (dt=%.1fs)\n",
 				$dta->{ENSEMBLE}[$lastgood+1]->{NUMBER},$dta->{ENSEMBLE}[$e-1]->{NUMBER},$dt)
-					unless defined($ENV{NO_GAP_WARNINGS});
+					unless defined($ENV{NO_GAP_WARNINGS}) || $RDI_Utils::No_Gap_Warnings;
 		}
 	
 		$dta->{ENSEMBLE}[$e]->{DEPTH} = $z;
--- a/patchPD0
+++ b/patchPD0
@@ -2,9 +2,9 @@
 #======================================================================
 #                    P A T C H P D 0 
 #                    doc: Tue Aug 23 20:00:15 2016
-#                    dlm: Mon Jul  1 16:56:51 2019
+#                    dlm: Tue Apr 14 21:28:49 2020
 #                    (c) 2010 A.M. Thurnherr
-#                    uE-Info: 189 0 NIL 0 0 72 2 2 4 NIL ofnI
+#                    uE-Info: 103 26 NIL 0 0 72 2 2 4 NIL ofnI
 #======================================================================
 
 $antsSummary = 'patch TRDI PD0 file with external attitude data';
@@ -20,11 +20,12 @@
 #	Jun 13, 2017: - added pitch and roll to -o
 #				  - BUG: ??? does -o handle pitch and roll ANOMALIES correctly?
 #	Jun 30, 2019: - -o did not work with single argument
+#	Apr 14, 2020: - adapted to use for moored ADCP data as well
 
 # PATCH-FILE REQUIREMENTS (ANTS format)
-#	- %LADCP_pitch.mu %LADCP_roll.mu		mean LADCP pitch and roll
-#	- %IMU_hdg_offset						heading offset of external IMU
-#	- LADCP_ens								ADCP ensemble number
+#	- %[L]ADCP_pitch.mu %[L]ADCP_roll.mu	mean ADCP pitch and roll
+#	- %IM[UP]_hdg_offset					heading offset of external IMU
+#	- [L]ADCP_ens							ADCP ensemble number
 #	- pitch, roll							external pitch/roll *anomalies* 
 #	- hdg									external heading rotated into ADCP coord system
 
@@ -73,14 +74,14 @@
 
 $RDI_PD0_IO::OVERRIDE_Y2K_CLOCK = $opt_c;
 
-$LADCP_file  = &antsFileArg();
+$ADCP_file  = &antsFileArg();
 $outPD0 = $ARGV[0]; shift;
 
 #----------------------------------------------------------------------
-# Step 1: Read LADCP Data
+# Step 1: Read ADCP Data
 #----------------------------------------------------------------------
 
-readData($LADCP_file,\%LADCP);												# TRDI PD0 file
+readData($ADCP_file,\%ADCP);												# TRDI PD0 file
 
 #----------------------------------------------------------------------
 # Step 2: Process External Attidue Input to Patch PD0 file
@@ -88,13 +89,20 @@
 
 &antsIn();																	# load first IMP record
 
-my($ensF) 	= &fnr('LADCP_ens');
+my($ensF) = &fnrNoErr('ADCP_ens');
+$ensF = &fnr('LADCP_ens') unless defined($ensF);
+
 my($pitchF) = &fnr('pitch');
 my($rollF)	= &fnr('roll');
 my($hdgF)	= &fnr('hdg');
-my($LADCP_pitch_mean)	= &antsRequireParam('LADCP_pitch.mu');
-my($LADCP_roll_mean)	= &antsRequireParam('LADCP_roll.mu');
 
+my($ADCP_pitch_mean) = $P{'ADCP_pitch.mu'};
+$ADCP_pitch_mean = &antsRequireParam('LADCP_pitch.mu')
+	unless numberp($ADCP_pitch_mean);
+
+my($ADCP_roll_mean) = $P{'ADCP_roll.mu'};
+$ADCP_roll_mean = &antsRequireParam('LADCP_roll.mu')
+	unless numberp($ADCP_roll_mean);
 
 my($pofs,$rofs) = (0,0);													# apply externally supplied offset(s)
 my($rho,$crho,$srho);												
@@ -117,13 +125,13 @@
 	$crho = cos(rad($rho));
 	$srho = sin(rad($rho));
 
-	if (defined($pofs)) {													# rotate IMP pitch and roll offsets into new LADCP frame
+	if (defined($pofs)) {													# rotate IMP pitch and roll offsets into new ADCP frame
 		my($IMP_pitch_mean) =  &antsRequireParam('IMP_pitch.mu') * $crho
 									+ &antsRequireParam('IMP_roll.mu') * $srho;
 		my($IMP_roll_mean)  = -&antsRequireParam('IMP_pitch.mu') * $srho
 									+ &antsRequireParam('IMP_roll.mu') * $crho;
-		$LADCP_pitch_mean = $IMP_pitch_mean - $pofs;						# apply externally supplied offsets
-		$LADCP_roll_mean  = $IMP_roll_mean  - $rofs;
+		$ADCP_pitch_mean = $IMP_pitch_mean - $pofs;						# apply externally supplied offsets
+		$ADCP_roll_mean  = $IMP_roll_mean  - $rofs;
 	}
 }
 
@@ -133,11 +141,11 @@
 do {
 	my($ADCP_deployed);
 	my($ens) = $P{RECNO};
-	die("assertion failed [$ants_[0][$ensF] != $LADCP{ENSEMBLE}[$ens]->{NUMBER} --- 1-$LADCP{ENSEMBLE}[0]->{NUMBER} + $P{RECNO} + $d]")
-		unless ($ants_[0][$ensF] == $LADCP{ENSEMBLE}[$ens]->{NUMBER});
-	$LADCP{ENSEMBLE}[$ens]->{DATA_SOURCE_ID} = 0xA0;
+	die("assertion failed [$ants_[0][$ensF] != $ADCP{ENSEMBLE}[$ens]->{NUMBER} --- 1-$ADCP{ENSEMBLE}[0]->{NUMBER} + $P{RECNO} + $d]")
+		unless ($ants_[0][$ensF] == $ADCP{ENSEMBLE}[$ens]->{NUMBER});
+	$ADCP{ENSEMBLE}[$ens]->{DATA_SOURCE_ID} = 0xA0;
 	
-	if (numbersp($ants_[0][$pitchF],$ants_[0][$rollF])) {					# valid IMP data -> patch LADCP ensemble
+	if (numbersp($ants_[0][$pitchF],$ants_[0][$rollF])) {					# valid IMP data -> patch ADCP ensemble
 		$ADCP_deployed = 1;
 		$missing_pr_block_len = 0;
 		if (defined($opt_o)) {												# -o set: rotate pitch and roll into correct coordinates
@@ -149,49 +157,49 @@
 			$ants_[$r][$rollF]	= $rot_r;
         } 
 		if ($opt_p) {														# patch pitch
-			$LADCP{ENSEMBLE}[$ens]->{DATA_SOURCE_ID} |= ($opt_p<<2);
-			$LADCP{ENSEMBLE}[$ens]->{PITCH} = RDI_pitch($LADCP_pitch_mean + $ants_[0][$pitchF],
-														$LADCP_roll_mean  + $ants_[0][$rollF]);
+			$ADCP{ENSEMBLE}[$ens]->{DATA_SOURCE_ID} |= ($opt_p<<2);
+			$ADCP{ENSEMBLE}[$ens]->{PITCH} = RDI_pitch($ADCP_pitch_mean + $ants_[0][$pitchF],
+														$ADCP_roll_mean  + $ants_[0][$rollF]);
 		}
 		if ($opt_r) {														# patch roll
-			$LADCP{ENSEMBLE}[$ens]->{DATA_SOURCE_ID} |= ($opt_r<<1);
-			$LADCP{ENSEMBLE}[$ens]->{ROLL} = $LADCP_roll_mean + $ants_[0][$rollF];
+			$ADCP{ENSEMBLE}[$ens]->{DATA_SOURCE_ID} |= ($opt_r<<1);
+			$ADCP{ENSEMBLE}[$ens]->{ROLL} = $ADCP_roll_mean + $ants_[0][$rollF];
 		}
-    } else {																# no valid IMP pitch and roll => invalidate LADCP data
+    } else {																# no valid IMP pitch and roll => invalidate ADCP data
     	$pr_missing++ if $ADCP_deployed;									# don't count missing before deployment
     	$missing_pr_block_len++;
 		unless ($opt_k)  {
-	    	clearEns(\%LADCP,$ens);
-	    	$LADCP{ENSEMBLE}[$ens]->{DATA_SOURCE_ID}= 0xA0;
+	    	clearEns(\%ADCP,$ens);
+	    	$ADCP{ENSEMBLE}[$ens]->{DATA_SOURCE_ID}= 0xA0;
 	    }
     }
 	    
     if (numberp($ants_[0][$hdgF])) {										# valid IMP heading
-    	$LADCP{ENSEMBLE}[$ens]->{DATA_SOURCE_ID} |= $opt_h;
+    	$ADCP{ENSEMBLE}[$ens]->{DATA_SOURCE_ID} |= $opt_h;
 		$missing_hdg_block_len = 0;
    		if (defined($opt_o)) {												# apply offset on -o; otherwise, data are correctly rotated
 	    	$ants_[0][$hdgF] -= $rho;
 	    	$ants_[0][$hdgF] += 360 if ($ants_[0][$hdgF] < 0);
 	    }
-		$LADCP{ENSEMBLE}[$ens]->{HEADING} = $ants_[0][$hdgF]				# patch heading
+		$ADCP{ENSEMBLE}[$ens]->{HEADING} = $ants_[0][$hdgF]				# patch heading
 			if $opt_h;
-	} else {																# no valid IMP heading => invalidate LADCP data
+	} else {																# no valid IMP heading => invalidate ADCP data
 		$hdg_missing++ if $ADCP_deployed;
 		$missing_hdg_block_len++;
 		unless ($opt_k)  {
-	    	clearEns(\%LADCP,$ens);
-	    	$LADCP{ENSEMBLE}[$ens]->{DATA_SOURCE_ID}= 0xA0;
+	    	clearEns(\%ADCP,$ens);
+	    	$ADCP{ENSEMBLE}[$ens]->{DATA_SOURCE_ID}= 0xA0;
 	    }
 	}
 } while (&antsIn());
 $pr_missing  -= missing_pr_block_len;										# don't count final block (post recovery)
 $hdg_missing -= missing_hdg_block_len;
 
-$LADCP{ENSEMBLE}[0]->{DATA_SOURCE_ID} = 0x7F;								# ensure correct DSID (1st ens: orig; 2nd ens: this prog)
-$LADCP{ENSEMBLE}[1]->{DATA_SOURCE_ID} = 0xA0
-	unless ($LADCP{ENSEMBLE}[1]->{DATA_SOURCE_ID}&0xF0 == 0xA0);
+$ADCP{ENSEMBLE}[0]->{DATA_SOURCE_ID} = 0x7F;								# ensure correct DSID (1st ens: orig; 2nd ens: this prog)
+$ADCP{ENSEMBLE}[1]->{DATA_SOURCE_ID} = 0xA0
+	unless ($ADCP{ENSEMBLE}[1]->{DATA_SOURCE_ID}&0xF0 == 0xA0);
 
-writeData($outPD0,\%LADCP);													# write new PD0
+writeData($outPD0,\%ADCP);													# write new PD0
 
 my($verb) = $opt_k ? 'retained' : 'cleared';
 printf(STDERR "$outPD0: %d pitch/roll & %d heading values $verb\n",$pr_missing,$hdg_missing)