--- a/.lsfit.poly
+++ b/.lsfit.poly
@@ -1,9 +1,9 @@
#======================================================================
# . L S F I T . P O L Y
# doc: Wed Feb 24 09:40:06 1999
-# dlm: Thu Jan 10 16:47:06 2013
+# dlm: Sun May 13 08:25:37 2018
# (c) 1999 A.M. Thurnherr
-# uE-Info: 118 16 NIL 0 0 72 2 2 4 NIL ofnI
+# uE-Info: 114 36 NIL 0 0 72 2 2 4 NIL ofnI
#======================================================================
# What you need to provide if you wanna fit a different
@@ -27,6 +27,7 @@
# Jul 28, 2006: - Version 3.3 [HISTORY]
# Sep 19, 2011: - moved part of the usage code into init() to allow use in [pgram]
# Jan 10, 2013: - added extremum output when fitting parabola (-o 2)
+# May 13, 2018: - BUG: replaced opt_o with modelNFit in &modelCleanup()
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#
@@ -110,7 +111,7 @@
sub modelCleanup()
{
- return unless ($opt_o == 2); # calculate loc of extremum on parabolic fits
+ return unless ($0 eq 'lsfit' && $modelNFit == 3); # calculate loc of extremum on parabolic fits with lsfit only
my($extX) = -$A[2] / (2 * $A[3]);
if ($A[3] > 0) {
old mode 100755
new mode 100644
--- a/HISTORY
+++ b/HISTORY
@@ -1,9 +1,9 @@
#======================================================================
# H I S T O R Y
# doc: Thu May 7 13:12:05 2015
-# dlm: Sat Dec 23 16:20:34 2017
+# dlm: Tue Nov 27 12:57:11 2018
# (c) 2015 A.M. Thurnherr
-# uE-Info: 10 11 NIL 0 0 70 0 2 4 NIL ofnI
+# uE-Info: 184 51 NIL 0 0 70 0 2 4 NIL ofnI
#======================================================================
May 7, 2015:
@@ -154,3 +154,33 @@
- improvements to [libALEC.pl]
- removed ambiguous date warning from [libconv.pl]
+Dec 23, 2017:
+ - published V7.0
+
+----------------------------------------------------------------------
+
+Mar 3 - Apr 23, 2018:
+ - multiple improvements to [libSBE.pl]
+
+Mar 28, 2018:
+ - added &loadInstrumentTransformation() to [libRDI_coords.pl]
+
+Apr 23, 2018:
+ - bugfix in [antsio.pl]
+
+Apr 25, 2018:
+ - added eps_VKE() to [libLADCP.pl]
+
+May 13, 2018:
+ - bugfix in [.lsfit.poly]
+
+May 22, 2018:
+ - added NMEA2dec_time() to [libconv.pl]
+
+May 22 - Jun 9, 2018:
+ - multiple improvements to [libIMP.pl]
+
+Nov 27, 2018:
+ - update version number in [ants.pl] [.hg/hgrc]
+ - updated HISTORY
+ - published V7.1
old mode 100755
new mode 100644
--- a/ants.pl
+++ b/ants.pl
@@ -2,9 +2,9 @@
#======================================================================
# A N T S . P L
# doc: Fri Jun 19 14:01:06 1998
-# dlm: Fri Dec 8 13:11:21 2017
+# dlm: Tue Nov 27 12:57:36 2018
# (c) 1998 A.M. Thurnherr
-# uE-Info: 31 20 NIL 0 0 72 2 2 4 NIL ofnI
+# uE-Info: 27 60 NIL 0 0 72 2 2 4 NIL ofnI
#======================================================================
# HISTORY:
@@ -24,11 +24,12 @@
# Mar 12, 2017: - updated to V6.8 (for LADCP_w 1.3 release)
# Nov 20, 2017: - updated to V6.9 (for DT KVH software)
# Dec 8, 2017: - updated to V7.0 (to avoid absolute-path symlink)
+# Nov 27, 2018: - updaetd to V7.1 (for LADCP_w 1.4 release)
exec($ENV{ANTS_PERL},$0,@ARGV),die("$ENV{ANTS_PERL}: $!")
if (defined($ENV{ANTS_PERL}) && $^X ne $ENV{ANTS_PERL});
-$antsLibVersion = 7.0;
+$antsLibVersion = 7.1;
die(sprintf("$0: obsolete library V%.1f; V%.1f required\n",
$antsLibVersion,$antsMinLibVersion))
--- a/antsio.pl
+++ b/antsio.pl
@@ -2,9 +2,9 @@
#======================================================================
# A N T S I O . P L
# doc: Fri Jun 19 19:22:51 1998
-# dlm: Wed Apr 5 13:45:32 2017
+# dlm: Mon Apr 23 14:20:58 2018
# (c) 1998 A.M. Thurnherr
-# uE-Info: 215 83 NIL 0 0 70 2 2 4 NIL ofnI
+# uE-Info: 216 82 NIL 0 0 70 2 2 4 NIL ofnI
#======================================================================
# HISTORY:
@@ -213,6 +213,7 @@
# Sep 13, 2016: - modified &antsAddParams to make more flexible
# Mar 10, 2017: - BUG: antsCheckDeps() used ctime instead of mtime!!!
# Apr 5, 2017: - BUG: stale file mtime dependency info was not printed correctly
+# Apr 23, 2018: - BUG: @antsLayout was not kept up-to-date when layout-changes are allowed
# GENERAL NOTES:
# - %P was named without an ants-prefix because associative arrays
@@ -486,10 +487,12 @@
# DONE WITH HEADER PARSING
+ # Handle Layout changes:
+ # - only allow when $antsAllowEmbeddedLayoutChange is set
+ # - ensure that antsLayout always contains up-to-date Layout
croak("$0: embedded layout change when reading file $ARGV <@antsLayout> -> <@Layout>")
if (!$antsAllowEmbeddedLayoutChange && @Layout && @antsLayout && ("@Layout" ne "@antsLayout"));
-
- @antsLayout = @Layout unless (@antsLayout);
+ @antsLayout = @Layout if (@Layout);
$P{RECNO} = -1 unless defined($P{RECNO}); # set pseudo %PARAMs
$P{LINENO} = -1 unless defined($P{LINENO});
--- a/libCPT.pl
+++ b/libCPT.pl
@@ -1,9 +1,9 @@
#======================================================================
# L I B C P T . P L
# doc: Wed Nov 15 12:28:49 2000
-# dlm: Fri May 9 11:40:01 2008
+# dlm: Mon May 14 21:29:00 2018
# (c) 2000 A.M. Thurnherr
-# uE-Info: 25 31 NIL 0 0 72 2 2 4 NIL ofnI
+# uE-Info: 75 58 NIL 0 0 72 2 2 4 NIL ofnI
#======================================================================
# HISTORY:
@@ -23,6 +23,9 @@
# Aug 16, 2006: - BUG: last level was returned on value < first level
# May 9, 2008: - adapted to GMT 4.3 (see also IMPLEMENTATION NOTES
# in [mkCPT])
+# Mar 26, 2018: - BUG: fg colors could not be set?!?!?!?! (both F and B set bg color)
+# - implemented color scaling for input files with rgb vals 0-1
+# May 14, 2016: - added input file check
#----------------------------------------------------------------------
# CPT File Parsing
@@ -65,10 +68,11 @@
if ($f[0] eq 'B') {
$CPT{bg_R} = $f[1]; $CPT{bg_G} = $f[2]; $CPT{bg_B} = $f[3];
} elsif ($f[0] eq 'F') {
- $CPT{bg_R} = $f[1]; $CPT{bg_G} = $f[2]; $CPT{bg_B} = $f[3];
+ $CPT{fg_R} = $f[1]; $CPT{fg_G} = $f[2]; $CPT{fg_B} = $f[3];
} elsif ($f[0] eq 'N') {
$CPT{nan_R} = $f[1]; $CPT{nan_G} = $f[2]; $CPT{nan_B} = $f[3];
} else {
+ croak("$0: format error - 7 fields expected on line: $_") unless ($#f >= 7);
$CPT{from_z}[$CPT{levels}] = $f[0];
$CPT{from_R}[$CPT{levels}] = $f[1];
$CPT{from_G}[$CPT{levels}] = $f[2];
@@ -82,7 +86,27 @@
}
$CPT{color_model} = 'RGB' unless defined($CPT{color_model});
croak("$0: color model $CPT{color_model} not implemented\n")
- unless ($CPT{color_model} =~ '\+?RGB' || $CPT{color_model} =~ '\+?HSV');
+ unless ($CPT{color_model} =~ '\+?[Rr][Gg][Bb]' || $CPT{color_model} =~ '\+?[Hh][Ss][Vv]');
+
+ if ($CPT{from_R}[0]>=0 && $CPT{from_R}[0]<=1 && # colors in 0-1 range
+ $CPT{from_G}[0]>=0 && $CPT{from_G}[0]<=1 &&
+ $CPT{from_B}[0]>=0 && $CPT{from_B}[0]<=1 &&
+ $CPT{from_R}[$CPT{levels}-1]>=0 && $CPT{from_R}[$CPT{levels}-1]<=1 &&
+ $CPT{from_G}[$CPT{levels}-1]>=0 && $CPT{from_G}[$CPT{levels}-1]<=1 &&
+ $CPT{from_B}[$CPT{levels}-1]>=0 && $CPT{from_B}[$CPT{levels}-1]<=1) {
+ $CPT{bg_R} = round(255 * $CPT{bg_R}); $CPT{bg_G} = round(255 * $CPT{bg_G}); $CPT{bg_B} = round(255 * $CPT{bg_B});
+ $CPT{fg_R} = round(255 * $CPT{fg_R}); $CPT{fg_G} = round(255 * $CPT{fg_G}); $CPT{fg_B} = round(255 * $CPT{fg_B});
+ $CPT{nan_R} = round(255 * $CPT{nan_R}); $CPT{nan_G} = round(255 * $CPT{nan_G}); $CPT{nan_B} = round(255 * $CPT{nan_B});
+ for (my($i)=0; $i<$CPT{levels}; $i++) {
+ $CPT{from_R}[$i] = round(255 * $CPT{from_R}[$i]);
+ $CPT{from_G}[$i] = round(255 * $CPT{from_G}[$i]);
+ $CPT{from_B}[$i] = round(255 * $CPT{from_B}[$i]);
+ $CPT{to_R}[$i] = round(255 * $CPT{to_R}[$i]);
+ $CPT{to_G}[$i] = round(255 * $CPT{to_G}[$i]);
+ $CPT{to_B}[$i] = round(255 * $CPT{to_B}[$i]);
+ }
+ }
+
return %CPT;
}
--- a/libIMP.pl
+++ b/libIMP.pl
@@ -1,9 +1,9 @@
#======================================================================
# L I B I M P . P L
# doc: Tue Nov 26 21:59:40 2013
-# dlm: Fri Dec 8 13:44:41 2017
+# dlm: Sat Jun 9 12:07:15 2018
# (c) 2017 A.M. Thurnherr
-# uE-Info: 42 73 NIL 0 0 70 2 2 4 NIL ofnI
+# uE-Info: 52 109 NIL 0 0 70 2 2 4 NIL ofnI
#======================================================================
# HISTORY:
@@ -40,6 +40,16 @@
# Nov 20, 2017: - major code cleanup
# Nov 22, 2017: - replaced "IMP" output in routines used by KVH by "IMU"
# Dec 8, 2017: - replaced remaing "IMP" output (e.g. in plot) by "IMU"
+# May 22, 2018: - added data trimming to rot_vec
+# May 23, 2018: - added horizontal field strength to mag calib plot
+# - added support for S/N 8 board inside UL WH300 (neg_piro == 2)
+# May 24, 2018: - continued working (coord_trans == 2)
+# May 25, 2018: - continued working
+# May 30, 2018: - BUG: trimming did not re-calculate elapsed time
+# Jun 5, 2018: - BUG: on -c main magnetometer and accelerometer vectors were
+# modified twice
+# Jun 7, 2018: - relaxed definition of -e
+# Jun 9, 2018: - BUG: some "edge" data (beyond the valid profile) were bogus (does not matter in practice)
#----------------------------------------------------------------------
# gRef() library
@@ -75,67 +85,98 @@
} else {
GMT_psbasemap('-Bg1a.1f.01:"X Magnetic Field [Gauss]":/g1a0.1f0.01:"Y Magnetic Field [Gauss]":WeSn');
}
- GMT_unitcoords(); # sensor info
- if ($sensor_info ne '') {
- GMT_pstext('-F+f12,Helvetica,blue+jTR -N');
- printf(GMT "0.98 0.98 $sensor_info\n");
- }
- GMT_pstext('-F+f14,Helvetica,blue+jTL -N');
+ GMT_unitcoords(); # horizontal field strength
+ GMT_pstext('-F+f12,Helvetica,blue+jTR -N');
+ printf(GMT "0.98 0.98 HF = %.2f Gauss\n",$HF_mag);
+
+ printf(GMT "0.98 0.94 $sensor_info\n") # sensor info
+ if ($sensor_info ne '');
+
+ GMT_pstext('-F+f14,Helvetica,blue+jTL -N'); # profile id
printf(GMT "0.01 1.06 $P{profile_id}\n");
GMT_end();
}
-sub rot_vecs($) # rotate & output IMU vector data
+sub rot_vecs(@) # rotate & output IMU vector data
{
- my($neg_piro) = @_; # negate KVH pitch/roll data
+ my($coord_trans,$min_elapsed,$max_elapsed,$plot_milapsed,$plot_malapsed) = @_; # negate KVH pitch/roll data if first arg set to 1
+ $min_elapsed = 0 unless defined($min_elapsed);
+ $max_elapsed = 9e99 unless defined($max_elapsed);
+ $plot_milapsed = $min_elapsed unless defined($plot_milapsed);
+ $plot_malapsed = $max_elapsed unless defined($plot_malapsed);
+
while (&antsIn()) {
+ next if ($ants_[0][$elapsedF] < $min_elapsed); # trim data
+ last if ($ants_[0][$elapsedF] > $max_elapsed);
+
my($cpiro) = -1; # current pitch/roll accelerometer
my(@R); # rotation matrix
for (my($i)=0; $i<@vecs; $i++) { # rotate vector data
if ($piro[$i][0] != $cpiro) { # next sensor chip
$cpiro = $piro[$i][0];
- my($pitch) = atan2($ants_[0][$vecs[$cpiro][0]], # eqn 25 from Freescale AN3461
- sqrt($ants_[0][$vecs[$cpiro][1]]**2+$ants_[0][$vecs[$cpiro][2]]**2));
- my($roll) = atan2($ants_[0][$vecs[$cpiro][1]], # eqn 26
- $ants_[0][$vecs[$cpiro][2]]);
- if ($neg_piro) {
+
+ my($accX) = $ants_[0][$vecs[$cpiro][0]];
+ my($accY) = $ants_[0][$vecs[$cpiro][1]];
+ my($accZ) = $ants_[0][$vecs[$cpiro][2]];
+
+ if ($coord_trans == 2) { # S/N 8 inside UL WH300
+ $accY *= -1; $accZ *= -1;
+ }
+
+ my($roll) = atan2($accY,$accZ); # eqn 25 from Freescale AN3461
+ my($pitch) = atan2($accX,sqrt($accY**2+$accZ**2)); # eqn 26 from <Freescale AN3461
+ if ($coord_trans == 1) { # KVH
$pitch *= -1;
$roll *= -1;
- }
+ }
$ants_[0][$piro[$i][1]] = deg($pitch); # add pitch/roll to data
$ants_[0][$piro[$i][2]] = deg($roll);
+
my($sp) = sin($pitch); my($cp) = cos($pitch); # define rotation matrix
my($sr) = sin($roll); my($cr) = cos($roll);
@R = ([ $cp, 0, -$sp ],
[-$sp*$sr, $cr, -$cp*$sr],
[ $sp*$cr, $sr, $cp*$cr]);
}
- my($newX) = ($ants_[0][$vecs[$i][0]]-$bias[$i][0]) * $R[0][0] +
- ($ants_[0][$vecs[$i][1]]-$bias[$i][1]) * $R[0][1] +
- ($ants_[0][$vecs[$i][2]]-$bias[$i][2]) * $R[0][2];
- my($newY) = ($ants_[0][$vecs[$i][0]]-$bias[$i][0]) * $R[1][0] +
- ($ants_[0][$vecs[$i][1]]-$bias[$i][1]) * $R[1][1] +
- ($ants_[0][$vecs[$i][2]]-$bias[$i][2]) * $R[1][2];
- my($newZ) = ($ants_[0][$vecs[$i][0]]-$bias[$i][0]) * $R[2][0] +
- ($ants_[0][$vecs[$i][1]]-$bias[$i][1]) * $R[2][1] +
- ($ants_[0][$vecs[$i][2]]-$bias[$i][2]) * $R[2][2];
- $ants_[0][$vecs[$i][0]] = $newX;
- $ants_[0][$vecs[$i][1]] = $newY;
- $ants_[0][$vecs[$i][2]] = $newZ;
+ my($xval) = $ants_[0][$vecs[$i][0]];
+ my($yval) = $ants_[0][$vecs[$i][1]];
+ my($zval) = $ants_[0][$vecs[$i][2]];
+
+ if ($coord_trans == 2) { # S/N 8 inside UL WH300
+ $yval *= -1; $zval *= -1;
+ }
+
+ $ants_[0][$vecs[$i][0]] = ($xval-$bias[$i][0]) * $R[0][0] +
+ ($yval-$bias[$i][1]) * $R[0][1] +
+ ($zval-$bias[$i][2]) * $R[0][2];
+ $ants_[0][$vecs[$i][1]] = ($xval-$bias[$i][0]) * $R[1][0] +
+ ($yval-$bias[$i][1]) * $R[1][1] +
+ ($zval-$bias[$i][2]) * $R[1][2];
+ $ants_[0][$vecs[$i][2]] = ($xval-$bias[$i][0]) * $R[2][0] +
+ ($yval-$bias[$i][1]) * $R[2][1] +
+ ($zval-$bias[$i][2]) * $R[2][2];
}
my($magX) = $ants_[0][$magXF];
my($magY) = $ants_[0][$magYF];
my($magZ) = $ants_[0][$magZF];
+ my($accX) = $ants_[0][$accXF];
+ my($accY) = $ants_[0][$accYF];
+ my($accZ) = $ants_[0][$accZF];
+
my($HF) = sqrt($magX**2+$magY**2);
my($valid)= ($HF >= $minfac*$HF_mag) && ($HF <= $maxfac*$HF_mag);
my($hdg) = $valid ? mag_heading($magX,$magY) : nan;
- &antsOut($ants_[0][$elapsedF],$ants_[0][$tempF],
+
+ &antsOut($ants_[0][$elapsedF]-$min_elapsed,$ants_[0][$tempF],
RDI_pitch($ants_[0][$pitchF],$ants_[0][$rollF]),$ants_[0][$rollF],
- $hdg,$ants_[0][$accXF],$ants_[0][$accYF],$ants_[0][$accZF],
- $magX,$magY,$magZ,vel_u($HF,$hdg),vel_v($HF,$hdg),$valid);
+ $hdg,$accX,$accY,$accZ,$magX,$magY,$magZ,
+ vel_u($HF,$hdg),vel_v($HF,$hdg),$valid);
+
pl_mag_calib_plot($valid,$magX,$magY)
- if defined($P{profile_id});
+ if defined($P{profile_id}) &&
+ ($ants_[0][$elapsedF] >= $plot_milapsed) &&
+ ($ants_[0][$elapsedF] <= $plot_malapsed);
}
}
@@ -414,7 +455,7 @@
} else {
my($dhist_binsize,$dhist_min_pirom,$dhist_min_mfrac) = split(/,/,$opt_e);
croak("$0: cannot decode -e $opt_e\n")
- unless ($dhist_binsize > 0 && $dhist_min_pirom > 0 && $dhist_min_mfrac > 0);
+ unless ($dhist_binsize > 0 && $dhist_min_pirom > 0 && $dhist_min_mfrac >= 0);
my(@dhist); my($nhist) = my($modeFreq) = 0;
for (my($ens)=$LADCP_begin; $ens<=$LADCP_end; $ens++) {
@@ -638,15 +679,18 @@
for (my($ens)=0; $ens<=$#{$LADCP{ENSEMBLE}}; $ens++) {
my($r) = int(($LADCP{ENSEMBLE}[$ens]->{ELAPSED_TIME} + $IMP{TIME_LAG} - $ants_[0][$elapsedF]) / $IMP{DT});
- if ($r<0 || $r>$#ants_) {
+# print(STDERR "$r\[$ens\,$LADCP{ENSEMBLE}[$ens]->{NUMBER}] = int(($LADCP{ENSEMBLE}[$ens]->{ELAPSED_TIME} + $IMP{TIME_LAG} - $ants_[0][$elapsedF]) / $IMP{DT});\n");
+ if ($r<0 || $r>$#ants_) { # ensemble beyond limits of IMU data
my(@out);
- $out[$elapsedF] = $LADCP{ENSEMBLE}[$ens]->{ELAPSED_TIME} + $IMP{TIME_LAG};
- $out[$L_elapsedF] = $LADCP{ENSEMBLE}[$ens]->{ELAPSED_TIME};
- $out[$L_ensF] = $LADCP{ENSEMBLE}[$ens]->{NUMBER};
- $out[$dcF] = ($ens <= $LADCP_bottom);
+ if ($ens >= $LADCP_begin && $ens <= $LADCP_end) {
+ $out[$elapsedF] = $LADCP{ENSEMBLE}[$ens]->{ELAPSED_TIME} + $IMP{TIME_LAG};
+ $out[$L_elapsedF] = $LADCP{ENSEMBLE}[$ens]->{ELAPSED_TIME};
+ }
+ $out[$L_ensF] = $LADCP{ENSEMBLE}[$ens]->{NUMBER};
+ $out[$dcF] = ($ens <= $LADCP_bottom);
&antsOut(@out);
- } elsif ($ens < $LADCP_begin || $ens > $LADCP_end) {
- $ants_[$r][$L_elapsedF] = $LADCP{ENSEMBLE}[$ens]->{ELAPSED_TIME};
+ } elsif ($ens < $LADCP_begin || $ens > $LADCP_end) { # pre deplyment or post recovery
+ $ants_[$r][$L_elapsedF] = undef;
$ants_[$r][$L_ensF] = $LADCP{ENSEMBLE}[$ens]->{NUMBER};
$ants_[$r][$L_pitchF] = undef;
$ants_[$r][$L_rollF] = undef;
--- a/libLADCP.pl
+++ b/libLADCP.pl
@@ -1,9 +1,9 @@
#======================================================================
# L I B L A D C P . P L
# doc: Wed Jun 1 20:38:19 2011
-# dlm: Mon May 18 09:49:19 2015
+# dlm: Wed Apr 25 17:41:36 2018
# (c) 2011 A.M. Thurnherr
-# uE-Info: 49 12 NIL 0 0 70 2 2 4 NIL ofnI
+# uE-Info: 46 27 NIL 0 0 70 2 2 4 NIL ofnI
#======================================================================
# HISTORY:
@@ -23,11 +23,32 @@
# Jun 26. 2013: - added T_w_z()
# - added parameter checks to processing-specific corrections
# May 18, 2015: - added pulse length to T_w() and T_w_z()
+# Apr 25, 2018: - added eps_VKE() parameterization
require "$ANTS/libvec.pl";
require "$ANTS/libfuns.pl";
#------------------------------------------------------------------------------
+# VKE parameterization for epsilon
+#
+# NOTES:
+# - see Thurnherr et al. (GRL 2015)
+# - calculate eps from p0
+# - optional second argument allows free choice of parameterization constant
+# - default value is from paper, which is slightly lower than the current value
+# used in [LADCP_VKE], which applies the parameterization only to spectra
+# passing a few tests
+#------------------------------------------------------------------------------
+
+sub eps_VKE(@)
+{
+ my($p0,$c) =
+ &antsFunUsage(-1,'.','<p0[m^2/s^2/(rad/m)]> [c[0.021 [1/sqrt(s)]]]',@_);
+ $c = 0.021 unless defined($c);
+ return numberp($p0) ? ($p0 / $c) ** 2 : nan;
+}
+
+#------------------------------------------------------------------------------
# Spectral corrections for LADCP data
#
# NOTES:
@@ -35,7 +56,6 @@
# - to correct, multiply power densities (or power, I think) with corrections
# - apply to down-/up-cast data only
#------------------------------------------------------------------------------
-
#----------------------------------------------------------------------
# 1. Corrections for individual data acquisition and processing steps
#----------------------------------------------------------------------
--- a/libRDI_Coords.pl
+++ b/libRDI_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: Mon Nov 27 07:13:25 2017
+# dlm: Wed Mar 28 12:30:12 2018
# (c) 2003 A.M. Thurnherr
-# uE-Info: 58 62 NIL 0 0 72 10 2 4 NIL ofnI
+# uE-Info: 109 22 NIL 0 0 72 10 2 4 NIL ofnI
#======================================================================
# RDI Workhorse Coordinate Transformations
@@ -56,6 +56,7 @@
# Oct 12, 2017: - documentation
# Nov 26, 2017: - BUG: velBeamtoBPEarth() did not respect missing values
# Nov 27, 2017: - BUG: numbersp() from [antslib.pl] was used
+# Mar 28, 2018: - added &loadInstrumentTransformation()
use strict;
use POSIX;
@@ -74,7 +75,15 @@
$RDI_Coords::beamTransformation = 'LHR90'; # set to 'RDI' to use 1st order transformations from RDI manual
#----------------------------------------------------------------------
-# beam to earth transformation
+# beam to earth transformation
+# - loadInstrumentTransformation(filename) loads a file that contains the
+# output from the PS3 command, which includes the instrument transformation
+# matrix as follows:
+# Instrument Transformation Matrix (Down): Q14:
+# 1.4689 -1.4682 0.0030 -0.0035 24067 -24055 49 -58
+# -0.0036 0.0029 -1.4664 1.4673 -59 48 -24025 24041
+# 0.2658 0.2661 0.2661 0.2657 4355 4359 4359 4354
+# 1.0373 1.0382 -1.0385 -1.0373 16995 17010 -17015 -16995
#----------------------------------------------------------------------
$RDI_Coords::threeBeam_1 = 0; # stats from velBeamToInstrument
@@ -88,6 +97,35 @@
{ # STATIC SCOPE
my(@B2I);
+ sub loadInstrumentTransformation($)
+ {
+ die("loadInstrumentTransformation(): B2I matrix already defined\n")
+ if (@B2I);
+ open(ITF,$_[0]) || die("$_[0]: $!\n");
+ my($row) = 0;
+ while (<ITF>) {
+ if ($row == 0) {
+ next unless m{^Instrument Transformation Matrix \(Down\):};
+ $row = 1;
+ } elsif ($row <= 4) {
+ my(@vals) = split;
+ die("$_[0]: cannot decode row #$row of Instrument Transformation Matrix\n")
+ unless (@vals == 8);
+ for (my($i)=0; $i<4; $i++) {
+ die("$_[0]: cannot decode row #$row of Instrument Transformation Matrix\n")
+ unless numberp($vals[$i]);
+ $B2I[$row-1][$i] = $vals[$i];
+ }
+ $row++;
+ } else {
+ last;
+ }
+ }
+ die("$_[0]: cannot decode Instrument Transformation Matrix (row = $row)\n")
+ unless ($row == 5);
+ close(ITF);
+ }
+
sub velBeamToInstrument(@)
{
my($ADCP,$ens,$v1,$v2,$v3,$v4) = @_;
@@ -134,22 +172,21 @@
}
} # STATIC SCOPE
-#----------------------------------------------------------------------
+#--------------------------------------------------------------------------------------------------------------
# velInstrumentToEarth(\%ADCP,ens,v1,v2,v3,v4) => (u,v,w,e)
# - $RDI_Coords::beamTransformation = 'LHR90'
# - from Lohrmann, Hackett & Roet (J. Tech., 1990)
# - eq A1 maps to RDI matrix M (sec 5.6) with
# alpha = roll
# beta = gimball_pitch
-# psi = calculation_pitch
-# psi = asin{sin(beta) cos(alpha) / sqrt[1- sin(alpha)^2 sin(beta)^2]}
+# psi (pitch used for calculation) = asin{sin(beta) cos(alpha) / sqrt[1- sin(alpha)^2 sin(beta)^2]}
# - (I only checked for 0 heading, but this is sufficient)
# - $RDI_Coords::beamTransformation = 'RDI'
# - default prior to LADCP_w V1.3
# - from RDI manual
# - 99% accurate for p/r<8deg
# => 1cm/s error for 1m/s winch speed!
-#----------------------------------------------------------------------
+#--------------------------------------------------------------------------------------------------------------
{ # STATIC SCOPE
my($hdg,$pitch,$roll,@I2E);
old mode 100755
new mode 100644
--- a/libSBE.pl
+++ b/libSBE.pl
@@ -1,9 +1,9 @@
#======================================================================
# L I B S B E . P L
# doc: Mon Nov 3 12:42:14 2014
-# dlm: Fri Mar 10 09:46:42 2017
+# dlm: Mon Apr 23 21:03:27 2018
# (c) 2014 A.M. Thurnherr
-# uE-Info: 20 55 NIL 0 0 72 2 2 4 NIL ofnI
+# uE-Info: 25 105 NIL 0 0 72 2 2 4 NIL ofnI
#======================================================================
# HISTORY:
@@ -18,6 +18,11 @@
# - added $libSBE_quiet to suppress diagnostic messages
# May 31, 2016: - made successfully decoding lat/lon optional
# Mar 10, 2017: - made lat/lon decoding more flexible
+# Mar 3, 2018: - adapted SBE37 fields (multiple changes)
+# - added default field name for sound speed (sspd)
+# Mar 8, 2018: - BUG: SBE_parseHeader() did not correctly detect missing lat/lon
+# - suppressed warnings in SBE_parseHeader()
+# Apr 23, 2018: - BUG: header lat/lon was incorrectly parsed when there was no spaced before hemisphere
#----------------------------------------------------------------------
# fname_SBE2std($)
@@ -30,13 +35,15 @@
return 'lat' if /^lat/;
return 'lon' if /^lon/;
- return 'press' if /^prDM/;
+ return 'press' if /^pr[dD]M/;
+ return 'sspd' if /^sv[dD]M/;
return 'depth' if /^depSM/;
return 'O2' if /^sbeox0/;
return 'alt_O2' if /^sbeox1/;
return 'salin' if /^sal00/;
return 'alt_salin' if /^sal11/;
return 'elapsed' if /^timeS/;
+ return 'time_jday' if /^timeJV2/;
return 'sigma0' if /^sigma.*00/;
return 'alt_sigma0' if /^sigma.*11/;
return 'rho0' if /^density00/;
@@ -90,24 +97,24 @@
return 'alt_theta0';
}
- if (m{^c0S/m}) { # conductivity with different units
+ if (m{^c0S/m} || m{^cond0S/m}) { # conductivity with different units
return undef
if defined($P{'cond.unit'}) && ($P{'cond.unit'} ne 'S/m');
&antsAddParams('cond.unit','S/m');
return 'cond';
- } elsif (m{^c0mS/cm}) {
+ } elsif (m{^c0mS/cm} || m{^cond0mS/cm}) {
return undef
if defined($P{'cond.unit'}) && ($P{'cond.unit'} ne 'mS/cm');
&antsAddParams('cond.unit','mS/cm');
return 'cond';
}
- if (m{^c1S/m}) {
+ if (m{^c1S/m} || m{^cond1S/m}) {
return undef
if defined($P{'cond.unit'}) && ($P{'cond.unit'} ne 'S/m');
&antsAddParams('cond.unit','S/m');
return 'alt_cond';
- } elsif (m{^c1mS/cm}) {
+ } elsif (m{^c1mS/cm} || m{^cond1mS/cm}) {
return undef
if defined($P{'cond.unit'}) && ($P{'cond.unit'} ne 'mS/cm');
&antsAddParams('cond.unit','mS/cm');
@@ -162,21 +169,21 @@
&antsAddParams('ITS',68); $P{ITS} = 68;
}
- if (m{^c0S/m}) { # conductivity with different units
+ if (m{^c0S/m} || m{^cond0S/m}) { # conductivity with different units
return undef
if defined($P{'cond.unit'}) && ($P{'cond.unit'} ne 'S/m');
&antsAddParams('cond.unit','S/m');
- } elsif (m{^c0mS/cm}) {
+ } elsif (m{^c0mS/cm} || m{^cond0mS/cm}) {
return undef
if defined($P{'cond.unit'}) && ($P{'cond.unit'} ne 'mS/cm');
&antsAddParams('cond.unit','mS/cm');
}
- if (m{^c1S/m}) {
+ if (m{^c1S/m} || m{^cond1S/m}) {
return undef
if defined($P{'cond.unit'}) && ($P{'cond.unit'} ne 'S/m');
&antsAddParams('cond.unit','S/m');
- } elsif (m{^c1mS/cm}) {
+ } elsif (m{^c1mS/cm} || m{^cond1mS/cm}) {
return undef
if defined($P{'cond.unit'}) && ($P{'cond.unit'} ne 'mS/cm');
&antsAddParams('cond.unit','mS/cm');
@@ -268,28 +275,30 @@
if ($hdr =~ /Date\s*:\s*(.*)/);
if (($hdr =~ /Latitude\s*[:=]\s*/) && !defined($lat)) {
- ($deg,$min,$NS) = split(/\s+/,$');
+# ($deg,$min,$NS) = split(/\s+/,$');
+ ($deg,$min,$NS) = ($' =~ m{([^\s]+)\s+(\d+\.\d*)\s*([NS])});
if ($NS eq 'N' || $NS eq 'S') {
$lat = $deg + $min/60;
$lat *= -1 if ($NS eq 'S');
- } elsif (!defined($NS) && abs($deg)<=90 && ($min >= 0) && ($min <= 60)) {
+ } elsif (!defined($NS) && defined($deg) && abs($deg)<=90 && ($min >= 0) && ($min <= 60)) {
$lat = $deg + $min/60;
} else {
- print(STDERR "$0: WARNING: cannot decode latitude ($')\n");
+# print(STDERR "$0: WARNING: cannot decode latitude ($')\n");
$lat = nan;
}
&antsAddParams('lat',$lat);
next;
}
if (($hdr =~ /Longitude\s*[:=]\s*/) && !defined($lon)) {
- ($deg,$min,$EW) = split(/\s+/,$');
+# ($deg,$min,$EW) = split(/\s+/,$');
+ ($deg,$min,$EW) = ($' =~ m{([^\s]+)\s+(\d+\.\d*)\s*([EW])});
if ($EW eq 'E' || $EW eq 'W') {
$lon = $deg + $min/60;
$lon *= -1 if ($EW eq 'W');
- } elsif (!defined($EW) && abs($deg)<=360 && ($min >= 0) && ($min <= 60)) {
+ } elsif (!defined($EW) && defined($deg) && abs($deg)<=360 && ($min >= 0) && ($min <= 60)) {
$lon = $deg + $min/60;
} else {
- print(STDERR "$0: WARNING: cannot decode longitude ($')\n");
+# print(STDERR "$0: WARNING: cannot decode longitude ($')\n");
$lon= nan;
}
&antsAddParams('lon',$lon);
--- a/libconv.pl
+++ b/libconv.pl
@@ -1,9 +1,9 @@
#======================================================================
# L I B C O N V . P L
# doc: Sat Dec 4 13:03:49 1999
-# dlm: Mon Dec 18 14:27:19 2017
+# dlm: Tue May 22 11:19:54 2018
# (c) 1999 A.M. Thurnherr
-# uE-Info: 67 36 NIL 0 0 70 2 2 4 NIL ofnI
+# uE-Info: 68 41 NIL 0 0 70 2 2 4 NIL ofnI
#======================================================================
# HISTORY:
@@ -65,6 +65,7 @@
# Jan 27, 2017: - BUG: dayNo() numeric month could have leading/trailing whitespace
# Jul 6, 2017: - BUG: date conversion routines did not parse 1/5/12 correctly
# Dec 18, 2017: - removed ambiguous-date warning
+# May 22, 2018: - added NMEA2dec_time()
require "$ANTS/libEOS83.pl"; # &sigma()
require "$ANTS/libPOSIX.pl"; # &floor()
@@ -187,6 +188,16 @@
# String to Decimal Time Conversion
#----------------------------------------------------------------------
+sub NMEA2dec_time(@)
+{
+ my($NMEA_string,$epoch) = &antsFunUsage(-1,'.','<NMEA string>[, epoch]',@_);
+
+ # Mar 17 2018 01:23:09
+ my($month,$day,$year,$time) = split(/\s+/,$NMEA_string);
+ $epoch = $year unless defined($epoch);
+ return dayNo($year,$month,$day,$epoch) + frac_day(split(':',$time));
+}
+
{ my($date_fmt);
sub str2dec_time(@) # heuristic
--- a/libfuns.pl
+++ b/libfuns.pl
@@ -1,9 +1,9 @@
#======================================================================
# L I B F U N S . P L
# doc: Wed Mar 24 11:49:13 1999
-# dlm: Thu Jun 4 17:56:37 2015
+# dlm: Fri May 11 11:40:05 2018
# (c) 1999 A.M. Thurnherr
-# uE-Info: 306 13 NIL 0 0 72 2 2 4 NIL ofnI
+# uE-Info: 31 77 NIL 0 0 70 2 2 4 NIL ofnI
#======================================================================
# HISTORY:
@@ -16,10 +16,24 @@
# Sep 7, 2012: - added acosh()
# Jun 4, 2015: - added gaussRand()
# - made normal() more efficient
+# May 11, 2018: - added Nsq()
require "$ANTS/libvec.pl"; # rad()
#----------------------------------------------------------------------
+# Buoyancy-Freuquency Squared
+# - based on signed buoyancy frequency => propagate sign
+#----------------------------------------------------------------------
+
+{ my(@fc);
+ sub Nsq(@)
+ {
+ my($N) = &antsFunUsage(1,'.','[(signed) buoyancy frequency]',\@fc,'N',@_);
+ return ($N < 0) ? -($N**2) : $N**2;
+ }
+}
+
+#----------------------------------------------------------------------
# gaussians/normal distribution
#----------------------------------------------------------------------
--- a/libvec.pl
+++ b/libvec.pl
@@ -1,9 +1,9 @@
#======================================================================
-# . . / L I B / L I B V E C . P L
+# L I B V E C . P L
# doc: Sat Mar 20 12:50:32 1999
-# dlm: Wed Nov 15 18:30:55 2017
+# dlm: Thu May 24 21:51:20 2018
# (c) 1999 A.M. Thurnherr
-# uE-Info: 44 70 NIL 0 0 70 2 2 4 NIL ofnI
+# uE-Info: 170 0 NIL 0 0 70 2 2 4 NIL ofnI
#======================================================================
# HISTORY: