# HG changeset patch # User A.M. Thurnherr # Date 1401352879 0 # Node ID bb7bb9f83db93eff5e6b73396f76d7acb3637a75 # Parent 591779f6df30c4dab33c0f6cd3c343d49d96f681 . diff --git a/RDI_Coords.pl b/RDI_Coords.pl --- a/RDI_Coords.pl +++ b/RDI_Coords.pl @@ -1,9 +1,9 @@ #====================================================================== # R D I _ C O O R D S . P L # doc: Sun Jan 19 17:57:53 2003 -# dlm: Sat Feb 22 09:43:27 2014 +# dlm: Tue Mar 4 13:35:21 2014 # (c) 2003 A.M. Thurnherr -# uE-Info: 37 0 NIL 0 0 72 0 2 4 NIL ofnI +# uE-Info: 273 60 NIL 0 0 72 0 2 4 NIL ofnI #====================================================================== # RDI Workhorse Coordinate Transformations @@ -34,6 +34,7 @@ # Aug 7, 2013: - BUG: &velBeamToBPInstrument did not return any val unless # all beam velocities are defined # Nov 27, 2013: - added &RDI_pitch(), &tilt_azimuth() +# Mar 4, 2014: - added support for missing PITCH/ROLL/HEADING use strict; use POSIX; @@ -111,7 +112,10 @@ { my($dta,$ens,$v1,$v2,$v3,$v4) = @_; return undef unless (defined($v1) && defined($v2) && - defined($v3) && defined($v4)); + defined($v3) && defined($v4) && + defined($dta->{ENSEMBLE}[$ens]->{PITCH}) && + defined($dta->{ENSEMBLE}[$ens]->{ROLL}) && + defined($dta->{ENSEMBLE}[$ens]->{HEADING})); unless (@I2E && $hdg == $dta->{ENSEMBLE}[$ens]->{HEADING} @@ -162,6 +166,11 @@ my($dta,$ens,$b1,$b2,$b3,$b4) = @_; my($v12,$w12,$v34,$w34); + return (undef,undef,undef,undef) + unless (defined($dta->{ENSEMBLE}[$ens]->{PITCH}) && + defined($dta->{ENSEMBLE}[$ens]->{ROLL}) && + defined($dta->{ENSEMBLE}[$ens]->{HEADING})); + unless (defined($TwoCosBAngle)) { $TwoCosBAngle = 2 * cos(rad($dta->{BEAM_ANGLE})); $TwoSinBAngle = 2 * sin(rad($dta->{BEAM_ANGLE})); @@ -216,6 +225,11 @@ my($dta,$ens,$b1,$b2,$b3,$b4) = @_; my($v12,$w12,$v34,$w34); + return (undef,undef,undef,undef) + unless (defined($dta->{ENSEMBLE}[$ens]->{PITCH}) && + defined($dta->{ENSEMBLE}[$ens]->{ROLL}) && + defined($dta->{ENSEMBLE}[$ens]->{HEADING})); + unless (defined($TwoCosBAngle)) { $TwoCosBAngle = 2 * cos(rad($dta->{BEAM_ANGLE})); $TwoSinBAngle = 2 * sin(rad($dta->{BEAM_ANGLE})); @@ -254,7 +268,9 @@ sub velApplyHdgBias(@) { my($dta,$ens,$v1,$v2,$v3,$v4) = @_; - return undef unless (defined($v1) && defined($v2)); + return (undef,undef,undef,undef) + unless (defined($v1) && defined($v2) && + defined($dta->{ENSEMBLE}[$ens]->{HEADING})); my($sh) = sin(rad(-$dta->{HEADING_BIAS})); my($ch) = cos(rad(-$dta->{HEADING_BIAS})); @@ -272,22 +288,25 @@ sub gimbal_pitch($$) # RDI coord trans manual { my($RDI_pitch,$RDI_roll) = @_; + return 'nan' unless defined($RDI_pitch) && defined($RDI_roll); return deg(atan(tan(rad($RDI_pitch)) * cos(rad($RDI_roll)))); } sub RDI_pitch($$) { my($gimbal_pitch,$roll) = @_; + return 'nan' unless defined($gimbal_pitch) && defined($roll); return deg(atan(tan(rad($gimbal_pitch))/cos(rad($roll)))); } sub tilt_azimuth($$) { my($gimbal_pitch,$roll) = @_; + return 'nan' unless defined($gimbal_pitch) && defined($roll); return angle(deg(atan2(sin(rad($gimbal_pitch)),sin(rad($roll))))); } -# - angle from vertical is home grown and should be treated with caution +# - angle from vertical is home grown # - angle between two unit vectors given by acos(v1 dot v2) # - vertical unit vector v1 = (0 0 1) => dot product = z-component of v2 # - when vertical unit vector is pitched in x direction, followed by @@ -301,6 +320,7 @@ sub angle_from_vertical($$) { my($RDI_pitch,$RDI_roll) = @_; + return 'nan' unless defined($RDI_pitch) && defined($RDI_roll); my($rad_pitch) = atan(tan(rad($RDI_pitch)) * cos(rad($RDI_roll))); return deg(acos(cos($rad_pitch) * cos(rad($RDI_roll)))); } diff --git a/RDI_PD0_IO.pl b/RDI_PD0_IO.pl --- 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: Tue Nov 26 01:29:26 2013 +# dlm: Wed May 7 10:41:18 2014 # (c) 2003 A.M. Thurnherr -# uE-Info: 873 10 NIL 0 0 72 74 2 4 NIL ofnI +# uE-Info: 827 0 NIL 0 0 72 74 2 4 NIL ofnI #====================================================================== # Read RDI BroadBand Binary Data Files (*.[0-9][0-9][0-9]) @@ -54,6 +54,11 @@ # Nov 25, 2013: - renamed from [RDI_BB_Read.pl] # - begin implementing WBWens() # - checkEnsemble() expunged +# Mar 3, 2014: - BUG: WBPens() did not handle incomple ensembles at EOF correctly +# Mar 4, 2014: - added support for DATA_SOURCE_ID +# Apr 24, 2014: - added debug statements to log %-GOOD values +# May 6, 2014: - loosened input format checks +# May 7, 2014: - removed BT_present flag # FIRMWARE VERSIONS: # It appears that different firmware versions generate different file @@ -67,6 +72,14 @@ # 16.21 WH300 (1) LDEO NBP0402 53 # 16.27 WH300 (2) Nash ? 59 +# PD0 IMP FILE FORMAT EXTENSIONS: +# - DATA_SOURCE_ID = 0xA0 | PATCHED_MASK (vs. 0x7F for TRDI PD0 files) +# PATCHED_MASK & 0x04: pitch value has been patched +# PATCHED_MASK & 0x02: roll value has been patched +# PATCHED_MASK & 0x01: heading value has been patched +# - PITCH & ROLL can be missing (0x8000 badval as in velocities) +# - HEADING can be missing (0xF000 badval, as 0x8000 is valid 327.68 heading) + # NOTES: # - RDI stores data in VAX/Intel byte order (little endian) # - the output data structure does not exactly mirror the file data @@ -99,6 +112,7 @@ # &readData() returns perl obj (ref to anonymous hash) with the following # structure: # +# DATA_SOURCE_ID scalar 0x7f (Workhorse, also DVL) # NUMBER_OF_DATA_TYPES scalar 6 (no BT) or 7 # ENSEMBLE_BYTES scalar ?, number of bytes w/o checksum # HEADER_BYTES scalar ? @@ -183,9 +197,9 @@ # BUILT_IN_TEST_ERROR scalar ?,undefined=none # SPEED_OF_SOUND scalar 1400--1600 [m/s] # XDUCER_DEPTH scalar 0.1--999.9 [m] -# HEADING scalar 0--359.99 [deg] -# PITCH scalar -20.00-20.00 [deg] -# ROLL scalar -20.00-20.00 [deg] +# HEADING scalar 0--359.99 [deg] --- IMP EXTENSION: undef +# PITCH scalar -20.00-20.00 [deg] --- IMP EXTENSION: undef +# ROLL scalar -20.00-20.00 [deg] --- IMP EXTENSION: undef # SALINITY scalar 0-40 [psu] # TEMPERATURE scalar -5.00--40.00 [deg] # MIN_PRE_PING_WAIT_TIME scalar ? [s] @@ -317,7 +331,7 @@ ($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,"Data Source",$did,0)); +## $did == 0x7f || die(sprintf($FmtErr,$WBRcfn,"Data Source",$did,0)); printf(STDERR "\n$WBRcfn: WARNING: unexpected number of data types (%d)\n", $dta->{NUMBER_OF_DATA_TYPES}) unless ($dta->{NUMBER_OF_DATA_TYPES} == 6 || @@ -553,7 +567,7 @@ { my($nbins,$fixed_leader_bytes,$E) = @_; my($start_ens,$B1,$B2,$B3,$B4,$I,$id,$bin,$beam,$buf,$dummy,@dta,$i,$cs,@WBRofs); - my($ens,$ensNo,$dayStart,$ens_length,$BT_present,$hid,$did,$ndt); + my($ens,$ensNo,$dayStart,$ens_length,$hid,$did,$ndt); for ($ens=$start_ens=0; 1; $ens++,$start_ens+=$ens_length+2) { # print(STDERR "ens = $ens\n"); @@ -567,10 +581,9 @@ sysread(WBRF,$buf,6) == 6 || last; ($hid,$did,$ens_length,$dummy,$ndt) = unpack('CCvCC',$buf); $hid == 0x7f || die(sprintf($FmtErr,$WBRcfn,"Header",$hid,0)); - $did == 0x7f || die(sprintf($FmtErr,$WBRcfn,"Data Source",$did,0)); - printf(STDERR "\n$WBRcfn: WARNING: unexpected number of data types (%d, ens=$ens)\n",$ndt),last - unless ($ndt == 6 || $ndt == 7); - $BT_present = ($ndt == 7); +## $did == 0x7f || die(sprintf($FmtErr,$WBRcfn,"Data Source",$did,0)); +## printf(STDERR "\n$WBRcfn: WARNING: unexpected number of data types (%d, ens=$ens)\n",$ndt),last +## unless ($ndt == 6 || $ndt == 7); sysread(WBRF,$buf,2*$ndt) == 2*$ndt || die("$WBRcfn: $!"); @WBRofs = unpack("v$ndt",$buf); $fixed_leader_bytes = $WBRofs[1] - $WBRofs[0]; @@ -594,6 +607,8 @@ # Variable Leader #------------------------------ + ${$E}[$ens]->{DATA_SOURCE_ID} = $did; # IMP extension + sysseek(WBRF,$start_ens+$WBRofs[1],0) || die("$WBRcfn: $!"); sysread(WBRF,$buf,4) == 4 || die("$WBRcfn: $!"); ($id,$ensNo) = unpack("vv",$buf); @@ -635,11 +650,22 @@ $BIT_errors++ if (${$E}[$ens]->{BUILT_IN_TEST_ERROR}); ${$E}[$ens]->{XDUCER_DEPTH} /= 10; - ${$E}[$ens]->{HEADING} /= 100; - ${$E}[$ens]->{PITCH} = unpack('s',pack('S',${$E}[$ens]->{PITCH})) / 100; - ${$E}[$ens]->{ROLL} = unpack('s',pack('S',${$E}[$ens]->{ROLL})) / 100; - ${$E}[$ens]->{TEMPERATURE} = - unpack('s',pack('S',${$E}[$ens]->{TEMPERATURE})) / 100; + + #------------------------------------------------- + # IMP EXTENSION: PITCH/ROLL/HEADING CAN BE MISSING + #------------------------------------------------- + + ${$E}[$ens]->{HEADING} = (${$E}[$ens]->{HEADING} == 0xF000) + ? undef + : ${$E}[$ens]->{HEADING} / 100; + ${$E}[$ens]->{PITCH} = (${$E}[$ens]->{PITCH} == 0x8000) + ? undef + : unpack('s',pack('S',${$E}[$ens]->{PITCH})) / 100; + ${$E}[$ens]->{ROLL} = (${$E}[$ens]->{ROLL} == 0x8000) + ? undef + : unpack('s',pack('S',${$E}[$ens]->{ROLL})) / 100; + + ${$E}[$ens]->{TEMPERATURE} = unpack('s',pack('S',${$E}[$ens]->{TEMPERATURE})) / 100; ${$E}[$ens]->{MIN_PRE_PING_WAIT_TIME} *= 60; ${$E}[$ens]->{MIN_PRE_PING_WAIT_TIME} += $B1 + $B2/100; ${$E}[$ens]->{PITCH_STDDEV} /= 10; @@ -780,84 +806,90 @@ die(sprintf($FmtErr,$WBRcfn,"Percent-Good Data",$id,$ens)); for ($i=0,$bin=0; $bin<$nbins; $bin++) { +# printf(STDERR "%-GOOD($bin): "); for ($beam=0; $beam<4; $beam++,$i++) { +# printf(STDERR "$dta[$i] "); ${$E}[$ens]->{PERCENT_GOOD}[$bin][$beam] = $dta[$i]; } +# printf(STDERR "\n"); } - #-------------------- + #----------------------------------------- # Bottom-Track Data - #-------------------- + # - scan through remaining data types + #----------------------------------------- - if ($BT_present) { - sysseek(WBRF,$start_ens+$WBRofs[6],0) || die("$WBRcfn: $!"); + my($nxt); + for ($nxt=6; $nxt<$ndt; $nxt++) { # scan until BT found + sysseek(WBRF,$start_ens+$WBRofs[$nxt],0) || die("$WBRcfn: $!"); sysread(WBRF,$buf,2) == 2 || die("$WBRcfn: $!"); $id = unpack('v',$buf); - - $id == 0x0600 || - die(sprintf($FmtErr,$WBRcfn,"Bottom Track",$id,$ens)); - - sysseek(WBRF,14,1) || die("$WBRcfn: $!"); # BT config - - 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]); - } - for ($beam=0; $beam<4; $beam++) { - ${$E}[$ens]->{BT_VELOCITY}[$beam] = - unpack('s',pack('S',$dta[4+$beam])) / 1000 - if ($dta[4+$beam] != 0x8000); - } - for ($beam=0; $beam<4; $beam++) { - ${$E}[$ens]->{BT_CORRELATION}[$beam] = $dta[8+$beam] - if ($dta[8+$beam]); - } - for ($beam=0; $beam<4; $beam++) { - ${$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 - - 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 - if ($dta[$beam] != 0x8000); - } - for ($beam=0; $beam<4; $beam++) { - ${$E}[$ens]->{BT_RL_CORRELATION}[$beam] = $dta[4+$beam] - if ($dta[4+$beam]); - } - for ($beam=0; $beam<4; $beam++) { - ${$E}[$ens]->{BT_RL_ECHO_AMPLITUDE}[$beam] = $dta[8+$beam]; - } - for ($beam=0; $beam<4; $beam++) { - ${$E}[$ens]->{BT_RL_PERCENT_GOOD}[$beam] = $dta[12+$beam]; - } - - sysseek(WBRF,2,1) || die("$WBRcfn: $!"); # BT config - - 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++) { - ${$E}[$ens]->{BT_RANGE}[$beam] += $dta[5+$beam] * 655.36 - if ($dta[5+$beam]); - } - } # BT present + last if ($id == 0x0600); + } + + next if ($nxt == $ndt); # no BT found => next ens + + + sysseek(WBRF,14,1) || die("$WBRcfn: $!"); # BT config + + 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]); + } + for ($beam=0; $beam<4; $beam++) { + ${$E}[$ens]->{BT_VELOCITY}[$beam] = + unpack('s',pack('S',$dta[4+$beam])) / 1000 + if ($dta[4+$beam] != 0x8000); + } + for ($beam=0; $beam<4; $beam++) { + ${$E}[$ens]->{BT_CORRELATION}[$beam] = $dta[8+$beam] + if ($dta[8+$beam]); + } + for ($beam=0; $beam<4; $beam++) { + ${$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 + + 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 + if ($dta[$beam] != 0x8000); + } + for ($beam=0; $beam<4; $beam++) { + ${$E}[$ens]->{BT_RL_CORRELATION}[$beam] = $dta[4+$beam] + if ($dta[4+$beam]); + } + for ($beam=0; $beam<4; $beam++) { + ${$E}[$ens]->{BT_RL_ECHO_AMPLITUDE}[$beam] = $dta[8+$beam]; + } + for ($beam=0; $beam<4; $beam++) { + ${$E}[$ens]->{BT_RL_PERCENT_GOOD}[$beam] = $dta[12+$beam]; + } + + sysseek(WBRF,2,1) || die("$WBRcfn: $!"); # BT config + + 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++) { + ${$E}[$ens]->{BT_RANGE}[$beam] += $dta[5+$beam] * 655.36 + if ($dta[5+$beam]); + } } # ens loop } @@ -886,22 +918,28 @@ { my($nbins,$fixed_leader_bytes,$E) = @_; my($start_ens,$B1,$B2,$B3,$B4,$I,$id,$bin,$beam,$buf,$dummy,@dta,$i,$cs,@WBPofs); - my($ens,$ensNo,$dayStart,$ens_length,$BT_present,$hid,$did,$ndt); + my($ens,$ensNo,$dayStart,$ens_length,$hid,$ndt); - for ($ens=$start_ens=0; 1; $ens++,$start_ens+=$ens_length+2) { + for ($ens=$start_ens=0; $ens<=$#{$E}; $ens++,$start_ens+=$ens_length+2) { - #---------------------------------------- - # Get ensemble length and # of data types - #---------------------------------------- + #------------------------------ + # Patch Header (Data Source Id) + #------------------------------ sysseek(WBPF,$start_ens,0) || die("$WBPcfn: $!"); - sysread(WBPF,$buf,6) == 6 || last; - ($hid,$did,$ens_length,$dummy,$ndt) = unpack('CCvCC',$buf); - $hid == 0x7f || die(sprintf($FmtErr,$WBPcfn,"Header",$hid,0)); - $did == 0x7f || die(sprintf($FmtErr,$WBPcfn,"Data Source",$did,0)); + sysread(WBPF,$buf,1) || die("$WBPcfn: unexpected EOF"); + ($hid) = unpack('C',$buf); + $hid == 0x7f || die(sprintf($FmtErr,$WBPcfn,"Header",$hid,$ens)); + + $buf = pack('C',${$E}[$ens]->{DATA_SOURCE_ID}); + my($nw) = syswrite(WBPF,$buf,1); + $nw == 1 || die("$WBPcfn: $nw bytes written ($!)"); + + sysread(WBPF,$buf,4) == 4 || die("$WBPcfn: unexpected EOF"); + ($ens_length,$dummy,$ndt) = unpack('vCC',$buf); printf(STDERR "\n$WBPcfn: WARNING: unexpected number of data types (%d, ens=$ens)\n",$ndt),last unless ($ndt == 6 || $ndt == 7); - $BT_present = ($ndt == 7); + sysread(WBPF,$buf,2*$ndt) == 2*$ndt || die("$WBPcfn: $!"); @WBPofs = unpack("v$ndt",$buf); $fixed_leader_bytes = $WBPofs[1] - $WBPofs[0]; @@ -913,10 +951,19 @@ sysseek(WBPF,$start_ens+$WBPofs[1]+12,0) || die("$WBPcfn: $!"); ${$E}[$ens]->{XDUCER_DEPTH} *= 10; - ${$E}[$ens]->{HEADING} *= 100; - - ${$E}[$ens]->{PITCH} = unpack('S',pack('s',${$E}[$ens]->{PITCH}*100)); - ${$E}[$ens]->{ROLL} = unpack('S',pack('s',${$E}[$ens]->{ROLL} *100)); + + # IMP EXTENSIONS + #--------------- + ${$E}[$ens]->{HEADING} = defined(${$E}[$ens]->{HEADING}) + ? ${$E}[$ens]->{HEADING} * 100 + : 0xF000; + ${$E}[$ens]->{PITCH} = defined(${$E}[$ens]->{PITCH}) + ? unpack('S',pack('s',${$E}[$ens]->{PITCH}*100)) + : 0x8000; + ${$E}[$ens]->{ROLL} = defined(${$E}[$ens]->{ROLL}) + ? unpack('S',pack('s',${$E}[$ens]->{ROLL}*100)) + : 0x8000; + ${$E}[$ens]->{TEMPERATURE} = unpack('S',pack('s',${$E}[$ens]->{TEMPERATURE}*100)); @@ -933,20 +980,6 @@ ${$E}[$ens]->{PITCH},${$E}[$ens]->{ROLL}, ${$E}[$ens]->{SALINITY},${$E}[$ens]->{TEMPERATURE}); -# unless ($b1 eq $buf) { -# printf(STDERR "ens = $ens\n"); -# printf(STDERR "hdg: $hdg, ${$E}[$ens]->{HEADING}\n"); -# printf(STDERR "xd: $xd, ${$E}[$ens]->{XDUCER_DEPTH}\n"); -# printf(STDERR "pit: $pit, ${$E}[$ens]->{PITCH}\n"); -# printf(STDERR "rol: $rol, ${$E}[$ens]->{ROLL}\n"); -# printf(STDERR "sal: $sal, ${$E}[$ens]->{SALINITY}\n"); -# printf(STDERR "tem: $tem, ${$E}[$ens]->{TEMPERATURE}\n"); -# -# printf(STDERR "read: %04X %04X %04X %04X %04X %04X %04X written: %04X %04X %04X %04X %04X %04X %04X\n",unpack('v7',$b1),unpack('v7',$buf)); -# -# die; -# } - my($nw) = syswrite(WBPF,$buf,14); $nw == 14 || die("$WBPcfn: $nw bytes written ($!)"); diff --git a/beamStats b/beamStats --- a/beamStats +++ b/beamStats @@ -1,10 +1,10 @@ #!/usr/bin/perl #====================================================================== -# L I S T B I N S +# B E A M S T A T S # doc: Fri Aug 25 15:57:05 2006 -# dlm: Thu Feb 21 15:05:40 2008 +# dlm: Tue Mar 4 13:09:14 2014 # (c) 2006 A.M. Thurnherr -# uE-Info: 32 57 NIL 0 0 72 0 2 4 NIL ofnI +# uE-Info: 33 64 NIL 0 0 72 0 2 4 NIL ofnI #====================================================================== # Split data file into per-bin time series. @@ -30,6 +30,7 @@ # BUG: min() did not work with 1st elt undef # Feb 21, 2008: - BUG: had forgotten to undo debugging changes # - removed missing magdecl warning on -b +# Mar 4, 2014: - added support for missing PITCH/ROLL/HEADING # General Notes: # - everything (e.g. beams) is numbered from 1 @@ -160,9 +161,9 @@ print(P "$dta{ENSEMBLE}[$e]->{DATE} "); print(P "$dta{ENSEMBLE}[$e]->{TIME} "); printf(P "%d ",$dta{ENSEMBLE}[$e]->{UNIX_TIME}-$t0); - print(P "$dta{ENSEMBLE}[$e]->{HEADING} "); - print(P "$dta{ENSEMBLE}[$e]->{PITCH} "); - print(P "$dta{ENSEMBLE}[$e]->{ROLL} "); + print(P defined($dta{ENSEMBLE}[$e]->{HEADING}) ? "$dta{ENSEMBLE}[$e]->{HEADING} " : 'nan '); + print(P defined($dta{ENSEMBLE}[$e]->{PITCH}) ? "$dta{ENSEMBLE}[$e]->{PITCH} " : 'nan '); + print(P defined($dta{ENSEMBLE}[$e]->{ROLL}) ? "$dta{ENSEMBLE}[$e]->{ROLL} " : 'nan '); print(P "$dta{ENSEMBLE}[$e]->{HEADING_STDDEV} "); print(P "$dta{ENSEMBLE}[$e]->{PITCH_STDDEV} "); print(P "$dta{ENSEMBLE}[$e]->{ROLL_STDDEV} "); diff --git a/listBins b/listBins --- a/listBins +++ b/listBins @@ -2,9 +2,9 @@ #====================================================================== # L I S T B I N S # doc: Fri Aug 25 15:57:05 2006 -# dlm: Wed Aug 7 10:04:28 2013 +# dlm: Tue Apr 22 12:39:09 2014 # (c) 2006 A.M. Thurnherr -# uE-Info: 48 46 NIL 0 0 72 2 2 4 NIL ofnI +# uE-Info: 50 45 NIL 0 0 72 2 2 4 NIL ofnI #====================================================================== # Split data file into per-bin time series. @@ -46,6 +46,8 @@ # Apr 29, 2013: - cosmetics # - added warning on missing -S # Aug 7, 2013: - BUG: -w did not respect -d +# Mar 4, 2014: - added support for missing PITCH/ROLL/HEADING +# Apr 22, 2014: - BUG: extraneous semicolon # General Notes: # - everything (e.g. beams) is numbered from 1 @@ -174,9 +176,9 @@ print(P "$dta{ENSEMBLE}[$e]->{DATE} "); print(P "$dta{ENSEMBLE}[$e]->{TIME} "); printf(P "%d ",$dta{ENSEMBLE}[$e]->{UNIX_TIME}-$t0); - print(P "$dta{ENSEMBLE}[$e]->{HEADING} "); - print(P "$dta{ENSEMBLE}[$e]->{PITCH} "); - print(P "$dta{ENSEMBLE}[$e]->{ROLL} "); + print(P defined($dta{ENSEMBLE}[$e]->{HEADING}) ? "$dta{ENSEMBLE}[$e]->{HEADING} " : 'nan '); + print(P defined($dta{ENSEMBLE}[$e]->{PITCH}) ? "$dta{ENSEMBLE}[$e]->{PITCH} " : 'nan '); + print(P defined($dta{ENSEMBLE}[$e]->{ROLL}) ? "$dta{ENSEMBLE}[$e]->{ROLL} " : 'nan '); print(P "$dta{ENSEMBLE}[$e]->{HEADING_STDDEV} "); print(P "$dta{ENSEMBLE}[$e]->{PITCH_STDDEV} "); print(P "$dta{ENSEMBLE}[$e]->{ROLL_STDDEV} "); @@ -250,8 +252,10 @@ next if (defined($first_ens) && $dta{ENSEMBLE}[$e]->{NUMBER} < $first_ens); - $dta{ENSEMBLE}[$e]->{PITCH} -= $P{pitch_bias}; - $dta{ENSEMBLE}[$e]->{ROLL} -= $P{roll_bias}; + $dta{ENSEMBLE}[$e]->{PITCH} -= $P{pitch_bias} + if defined($dta{ENSEMBLE}[$e]->{PITCH}); + $dta{ENSEMBLE}[$e]->{ROLL} -= $P{roll_bias} + if defined($dta{ENSEMBLE}[$e]->{ROLL}); $P{first_ens} = $dta{ENSEMBLE}[$e]->{NUMBER},$fe = $e unless defined($P{first_ens}); diff --git a/listEns b/listEns --- a/listEns +++ b/listEns @@ -2,9 +2,9 @@ #====================================================================== # L I S T E N S # doc: Sat Jan 18 18:41:49 2003 -# dlm: Wed Aug 7 10:38:17 2013 +# dlm: Tue Mar 4 12:56:36 2014 # (c) 2003 A.M. Thurnherr -# uE-Info: 215 0 NIL 0 0 72 2 2 4 NIL ofnI +# uE-Info: 46 64 NIL 0 0 72 2 2 4 NIL ofnI #====================================================================== # Print useful info from the ensemble list or dump ensembles to @@ -42,6 +42,8 @@ # - added sounspeed correction warning # - changed -E from prefix to suffix # - added active header line to -E output +# Mar 4, 2014: - added partial support for DATA_SOURCE_ID +# - added support for missing PITCH/ROLL/HEADING # Notes: # - -E outputs data in earth coordinates, unless -b is set also @@ -134,14 +136,19 @@ { my($e) = @_; - printf('%d %lf %d %g %g %g %g %g %g', + printf('%d %lf %d %g', $dta{ENSEMBLE}[$e]->{NUMBER}, $dta{ENSEMBLE}[$e]->{UNIX_TIME}, $dta{ENSEMBLE}[$e]->{XDUCER_FACING_UP} ? 1 : 0, $dta{ENSEMBLE}[$e]->{TEMPERATURE}, - $dta{ENSEMBLE}[$e]->{HEADING}, - $dta{ENSEMBLE}[$e]->{PITCH}, - $dta{ENSEMBLE}[$e]->{ROLL}, + ); + if (defined($dta{ENSEMBLE}[$e]->{HEADING})) { printf(' %g',$dta{ENSEMBLE}[$e]->{HEADING}); } + else { printf(' nan'); } + if (defined($dta{ENSEMBLE}[$e]->{PITCH})) { printf(' %g',$dta{ENSEMBLE}[$e]->{PITCH}); } + else { printf(' nan'); } + if (defined($dta{ENSEMBLE}[$e]->{ROLL})) { printf(' %g',$dta{ENSEMBLE}[$e]->{ROLL}); } + else { printf(' nan'); } + printf(' %g %g', $dta{ENSEMBLE}[$e]->{ADC_XMIT_VOLTAGE}, $dta{ENSEMBLE}[$e]->{ADC_XMIT_CURRENT}, ); @@ -244,10 +251,10 @@ } else { # neither ANTS nor ens files unless ($opt_Q) { if ($dta{FIXED_LEADER_BYTES} >= 53) { - printf(" # Date Time XD Temp Headng Pitch Roll vels(bin1) ESW$addLayout\n"); + printf(" # Date Time XD Temp Headng Pitch Roll #vv DSID ESW$addLayout\n"); printf("-----------------------------------------------------------------------\n"); } else { - printf(" # Date Time XD Temp Headng Pitch Roll vels(bin1)$addLayout\n"); + printf(" # Date Time XD Temp Headng Pitch Roll #vv DSID$addLayout\n"); printf("-------------------------------------------------------------------\n"); } } @@ -256,16 +263,22 @@ { my($e) = @_; - printf('%5d %s %s %s %5.1f %6.1f %5.1f %5.1f %3d', + printf('%5d %s %s %s %5.1f', $dta{ENSEMBLE}[$e]->{NUMBER}, $dta{ENSEMBLE}[$e]->{DATE}, $dta{ENSEMBLE}[$e]->{TIME}, $dta{ENSEMBLE}[$e]->{XDUCER_FACING_UP} ? "UP" : "DN", $dta{ENSEMBLE}[$e]->{TEMPERATURE}, - $dta{ENSEMBLE}[$e]->{HEADING}, - $dta{ENSEMBLE}[$e]->{PITCH}, - $dta{ENSEMBLE}[$e]->{ROLL}, + ); + if (defined($dta{ENSEMBLE}[$e]->{HEADING})) { printf(' %6.1f',$dta{ENSEMBLE}[$e]->{HEADING}); } + else { printf(' nan'); } + if (defined($dta{ENSEMBLE}[$e]->{PITCH})) { printf(' %5.1f',$dta{ENSEMBLE}[$e]->{PITCH}); } + else { printf(' nan'); } + if (defined($dta{ENSEMBLE}[$e]->{ROLL})) { printf(' %5.1f',$dta{ENSEMBLE}[$e]->{ROLL}); } + else { printf(' nan'); } + printf(' %3d 0x%02X', $dta{ENSEMBLE}[$e]->{BIN1VELS}, + $dta{ENSEMBLE}[$e]->{DATA_SOURCE_ID}, ); printf(' 0x%08X',$dta{ENSEMBLE}[$e]->{ERROR_STATUS_WORD}) if ($dta{FIXED_LEADER_BYTES} >= 53); diff --git a/listHdr b/listHdr --- a/listHdr +++ b/listHdr @@ -2,9 +2,9 @@ #====================================================================== # L I S T H D R # doc: Sat Jan 18 18:41:49 2003 -# dlm: Mon Mar 25 19:20:19 2013 +# dlm: Thu Apr 24 14:50:23 2014 # (c) 2003 A.M. Thurnherr -# uE-Info: 79 0 NIL 0 0 72 8 2 4 NIL ofnI +# uE-Info: 33 81 NIL 0 0 72 8 2 4 NIL ofnI #====================================================================== # Print useful info from the RDI BB header @@ -30,6 +30,7 @@ # Jul 9, 2008: - added output regarding available sensors # Mar 20, 2013: - removed DATA_FORMAT stuff # Mar 25, 2013: - added INSTRUMENT_TYPE stuff instead +# Apr 24, 2014: - BUG: USE_3_BEAM_ON_LOW_CORR was reported in water-track setup $0 =~ m{(.*/)[^/]+}; require "$1RDI_BB_Read.pl"; @@ -103,6 +104,7 @@ printf("EARTH_COORDINATES ") if ($hdr{EARTH_COORDINATES}); printf("PITCH_AND_ROLL_USED ") if ($hdr{PITCH_AND_ROLL_USED}); printf("BIN_MAPPING_ALLOWED ") if ($hdr{ALLOW_BIN_MAPPING}); + printf("USE_3_BEAM_ON_LOW_CORR ") if ($hdr{USE_3_BEAM_ON_LOW_CORR}); print("\n"); @@ -149,7 +151,6 @@ printf("NARROW_BANDWIDTH ") if ($hdr{NARROW_BANDWIDTH}); printf("WIDE_BANDWIDTH ") if ($hdr{WIDE_BANDWIDTH}); printf("TRANSMIT_POWER_HIGH ") if ($hdr{TRANSMIT_POWER_HIGH}); - printf("USE_3_BEAM_ON_LOW_CORR ") if ($hdr{USE_3_BEAM_ON_LOW_CORR}); print("\n"); #---------------------------------------------------------------------- diff --git a/mkProfile b/mkProfile --- a/mkProfile +++ b/mkProfile @@ -2,9 +2,9 @@ #====================================================================== # M K P R O F I L E # doc: Sun Jan 19 18:55:26 2003 -# dlm: Thu Feb 13 15:45:20 2014 +# dlm: Sat May 24 22:50:02 2014 # (c) 2003 A.M. Thurnherr -# uE-Info: 283 0 NIL 0 0 72 2 2 4 NIL ofnI +# uE-Info: 797 76 NIL 0 0 72 10 2 4 NIL ofnI #====================================================================== # Make an LADCP Profile by Integrating W (similar to Firing's scan*). @@ -85,6 +85,9 @@ # - finally removed -d/-g # Nov 25, 2013: - expunged checkEnsemble # Feb 13, 2014: - added support set_range_lim() +# Mar 4, 2014: - added support to allow missing PITCH/ROLL/HEADING values +# May 24, 2014: - finally added (gimbal-)pitch & roll to default output +# - renamed heading to hdg and pitchroll to tilt # NOTES: # - the battery values are based on transmission voltages (different @@ -564,12 +567,19 @@ # Step 6: Pitch, Roll, Rotation #====================================================================== +# in case of PITCH/ROLL/HEADING data gaps (IMP data), the calculations +# are not entirely correct, as +# i) the rotation implied by the pre-/post-gap headings is not counted +# ii) the gappy ensembles are counted for calculating the rms vals + my($prrms,$dnprrms,$upprrms) = (0,0,0); my($rotrms,$prerot,$dnrot,$uprot,$postrot) = (0,0,0,0,0); sub rot($) { my($e) = @_; + return 0 + unless defined($dta{ENSEMBLE}[$e]->{HEADING}) && defined($dta{ENSEMBLE}[$e-1]->{HEADING}); my($rot) = $dta{ENSEMBLE}[$e]->{HEADING} - $dta{ENSEMBLE}[$e-1]->{HEADING}; $rot -= 360 if ($rot > 180); @@ -582,10 +592,11 @@ } for (; $e<= $atbottom; $e++) { # downcast - $dta{ENSEMBLE}[$e]->{PITCHROLL} = + $dta{ENSEMBLE}[$e]->{TILT} = &angle_from_vertical($dta{ENSEMBLE}[$e]->{PITCH}, $dta{ENSEMBLE}[$e]->{ROLL}); - $prrms += $dta{ENSEMBLE}[$e]->{PITCHROLL}**2; + $prrms += $dta{ENSEMBLE}[$e]->{TILT}**2 + if numberp($dta{ENSEMBLE}[$e]->{TILT}); $dta{ENSEMBLE}[$e]->{ROTATION} = rot($e); $dnrot += $dta{ENSEMBLE}[$e]->{ROTATION}; @@ -594,10 +605,11 @@ $dnprrms = $prrms; for (; $e<=$lastgood; $e++) { # upcast - $dta{ENSEMBLE}[$e]->{PITCHROLL} = + $dta{ENSEMBLE}[$e]->{TILT} = &angle_from_vertical($dta{ENSEMBLE}[$e]->{PITCH}, $dta{ENSEMBLE}[$e]->{ROLL}); - $prrms += $dta{ENSEMBLE}[$e]->{PITCHROLL}**2; + $prrms += $dta{ENSEMBLE}[$e]->{TILT}**2 + if numberp($dta{ENSEMBLE}[$e]->{TILT}); $dta{ENSEMBLE}[$e]->{ROTATION} = rot($e); $uprot += $dta{ENSEMBLE}[$e]->{ROTATION}; @@ -689,7 +701,7 @@ if defined($opt_M); print("#ANTS#FIELDS# {ens} {time} {elapsed} {secno} {downcast} " . "{w} {w_err} {err_vel} {depth} {depth_err} {seabed} " . - "{pitchroll} {heading} {rotation} " . + "{pitch} {roll} {tilt} {hdg} {rotation} " . "$uFields $addFields\n"); printf("#ANTS#PARAMS# date{$dta{ENSEMBLE}[$firstgood]->{DATE}} " . @@ -704,18 +716,18 @@ "0.8_valid_range{%.1f} " . "max_depth{%.1f} " . "depth_error{%.1f} " . - "min_range{%d} " . - "n_ensembles{%d} " . - "w_gap_time{%d} " . + "min_range{%d} " . + "n_ensembles{%d} " . + "w_gap_time{%d} " . "stderr_w{%.4f} " . - "rms_pitchroll{%.1f} " . - "downcast_rms_pitchroll{%.1f} " . - "upcast_rms_pitchroll{%.1f} " . + "rms_tilt{%.1f} " . + "downcast_rms_tilt{%.1f} " . + "upcast_rms_tilt{%.1f} " . "rms_rotation{%.2f} " . - "deployment_rotations{%d} " . - "downcast_rotations{%d} " . - "upcast_rotations{%d} " . - "recovery_rotations{%d} " . + "deployment_rotations{%d} " . + "downcast_rotations{%d} " . + "upcast_rotations{%d} " . + "recovery_rotations{%d} " . "rms_heave_acceleration{%.2f} " . "bin1_dist{%.1f} " . "bin_length{%.1f} " . @@ -782,7 +794,9 @@ p($dta{ENSEMBLE}[$e]->{DEPTH}); p($dta{ENSEMBLE}[$e]->{DEPTH_ERR}); p($dta{ENSEMBLE}[$e]->{seabed}); - p($dta{ENSEMBLE}[$e]->{PITCHROLL}); + p(&gimbal_pitch($dta{ENSEMBLE}[$e]->{PITCH},$dta{ENSEMBLE}[$e]->{ROLL})); + p($dta{ENSEMBLE}[$e]->{ROLL}); + p($dta{ENSEMBLE}[$e]->{TILT}); p($dta{ENSEMBLE}[$e]->{HEADING}); p($dta{ENSEMBLE}[$e]->{ROTATION}); if (defined($opt_M)) { diff --git a/splitRDI b/splitRDI --- a/splitRDI +++ b/splitRDI @@ -2,9 +2,9 @@ #====================================================================== # S P L I T R D I # doc: Sat Aug 21 22:20:27 2010 -# dlm: Thu Feb 13 14:42:02 2014 +# dlm: Wed Mar 19 16:35:45 2014 # (c) 2010 A.M. Thurnherr -# uE-Info: 19 0 NIL 0 0 72 2 2 4 NIL ofnI +# uE-Info: 36 43 NIL 0 0 72 2 2 4 NIL ofnI #====================================================================== # split RDI files based on list of ensemble numbers (e.g. from yoyo -t) @@ -13,6 +13,7 @@ # Aug 21, 2010: - created # Jun 24, 2011: - replaced -b, -n by -o # Feb 13, 2014: - updated doc +# Mar 19, 2014: - added -s)kip small files # NOTES: # - it is assumed that the input file begins with ensemble #1 @@ -32,13 +33,16 @@ die("Usage: $0 " . "[-o)ut-file ] " . + "[require -m)in to produce output] " . " \n") - unless (&getopts('o:') && @ARGV>=3); + unless (&getopts('o:m:') && @ARGV>=3); $opt_o = substr($ARGV[0],0,3) # default output filename format . '%02d' . substr($ARGV[0],-9) unless defined($opt_o); + +$opt_m = 0 unless defined($opt_m); # default: produce tiny files as well readHeader($ARGV[0],\%hdr); shift; # get length of ensembles $ens_len = $hdr{ENSEMBLE_BYTES} + 2; @@ -48,19 +52,21 @@ $cnr = 0; do { # split data - sysseek(WBRF,($first_ens-2)*$ens_len,0) || + sysseek(WBRF,($first_ens-2)*$ens_len,0) || # read next block of data die("$WBRcfn: $!"); $last_ens++ unless defined($ARGV[0]); $nBytes = ($last_ens-$first_ens+1) * $ens_len; sysread(WBRF,$buf,$nBytes) == $nBytes || die("$WBRcfn: file truncated"); - $fn = sprintf($opt_o,$cnr++); - open(F,">$fn") || die("$fn: $!\n"); - syswrite(F,$buf,$nBytes) == $nBytes || - die("$fn: $!\n"); - close(F); - printf(STDERR "$fn: %d ensembles ($nBytes bytes)\n",$last_ens-$first_ens+1); + if ($last_ens-$first_ens+1 > $opt_m) { # produce file only if sufficient # of ensembles + $fn = sprintf($opt_o,$cnr++); + open(F,">$fn") || die("$fn: $!\n"); + syswrite(F,$buf,$nBytes) == $nBytes || + die("$fn: $!\n"); + close(F); + printf(STDERR "$fn: %d ensembles ($nBytes bytes)\n",$last_ens-$first_ens+1); + } $first_ens = $last_ens+1; $last_ens = $ARGV[0]; shift;