V6.8
authorA.M. Thurnherr <athurnherr@yahoo.com>
Sun, 12 Mar 2017 12:00:31 -0400
changeset 30 1a1a12d5edc1
parent 29 f41d125405a6
child 31 a93075e0b008
V6.8
.lsfit.poly
.nminterp.linear
HISTORY
ants.pl
antsexprs.pl
antsio.pl
antsusage.pl
libSBE.pl
libconv.pl
libvec.pl
new file mode 100644
--- /dev/null
+++ b/.lsfit.poly
@@ -0,0 +1,125 @@
+#======================================================================
+#                    . 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
+#                    (c) 1999 A.M. Thurnherr
+#                    uE-Info: 118 16 NIL 0 0 72 2 2 4 NIL ofnI
+#======================================================================
+
+# What you need to provide if you wanna fit a different
+# linear model function to your data:
+#	- a number of global variables to be set during loading
+#	- a number of subs to perform admin tasks (usage, init, ...)
+#	- a sub to evaluate the basis funs at a given x value; each
+#	  y value must be stored in @A (beginning with
+#	  A[1]!!!).
+#	- the interface is documented between +++++++ lines
+
+# fit polynomial (sum of A_i x^i) to data
+# NB: - preferable to [./.lmfit.poly]
+
+# HISTORY:
+#	Jul 31, 1999: - adapted from [./.lmfit.poly]
+#	Aug 01, 1999: - changed &modelEvaluate() interface
+#	Aug 02, 1999: - added &antsDescription()
+#   Mar 17, 2001: - param->arg
+#	Jul 12, 2004: - made poly-order argument into -o option
+#	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)
+
+#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+#
+# THE FOLLOWING VARIABLES MUST BE SET GLOBALLY (i.e. during loading)
+#
+#	$modelOpts			string of allowed options
+#	$modelOptsUsage		usage information string for options
+#	$modelMinArgs		min # of arguments of model
+#	$modelArgsUsage		usage information string for arguments
+#
+# The following variables may be set later but not after &modelInit()
+#
+#	$modelNFit			number of params to fit in model
+#	@nameA				symbolic names of model parameters
+#
+# You should call &antsDescription() for the -c option here
+#
+#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+$modelOpts = "o:";
+$modelOptsUsage = "-o)rder <n>";
+$modelMinArgs = 0;
+$modelArgsUsage = "";
+
+#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+#
+# &modelUsage()		mangle parameters; NB: there may be `infinite' # of
+#					filenames after model arguments; this usually sets
+#					@A (the model parameters) but these can later be
+#					calculated heuristically during &modelInit()
+#
+#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+sub modelUsage()
+{
+	my($c);
+	
+	$modelNFit = &antsCardOpt($opt_o) + 1;						# order of polynomial
+	die("$0 (.lsfit.poly): ERROR! -o required\n")
+		unless (defined($opt_o) && $opt_o >= 0);
+	&antsUsageError() unless ($#ARGV < 0 || -r $ARGV[0]);
+}
+
+#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+#
+# &modelInit()		initializes model after reading of data
+#
+#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+sub modelInit()
+{
+	for ($c=0; $c<$modelNFit; $c++) {				# init coefficients
+		$A[$c+1] = nan;
+		$nameA[$c+1] = "c$c";						# and names
+	}
+}
+
+#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+#
+# &modelEvaluate(idx,xfnr,vals)	evaluate polynomial basis funs at x
+#		idx				       	current index in @ants_
+#		xfnr					field number of x field
+#		vals					reference to return values (1-relative!)
+#
+#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+sub modelEvaluate($$$)
+{
+	my($idx,$xfnr,$valsR) = @_;
+	my($i);
+
+	$valsR->[1] = 1;
+	for ($i=2; $i<=$#{$valsR}; $i++) {
+		$valsR->[$i] = $valsR->[$i-1] * $ants_[$idx][$xfnr];
+    }
+}
+
+#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+# &modelCleanup()	cleans up after fitting but before output
+#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+sub modelCleanup() 
+{
+	return unless ($opt_o == 2);		# calculate loc of extremum on parabolic fits
+
+	my($extX) = -$A[2] / (2 * $A[3]);
+	if ($A[3] > 0) {
+		&antsInfo(".lsfit.poly: minimum at %.1f",$extX);
+	} elsif ($A[3] < 0) {
+		&antsInfo(".lsfit.poly: maximum at %.1f",$extX);
+	} else {
+		&antsInfo(".lsfit.poly: saddle point at %.1f",$extX);
+	}
+}
+
+1;
new file mode 100644
--- /dev/null
+++ b/.nminterp.linear
@@ -0,0 +1,108 @@
+#======================================================================
+#                    . N M I N T E R P . L I N E A R 
+#                    doc: Wed Nov 22 21:01:09 2000
+#                    dlm: Thu Jan 23 13:39:13 2014
+#                    (c) 2000 A.M. Thurnherr
+#                    uE-Info: 19 61 NIL 0 0 72 2 2 4 NIL ofnI
+#======================================================================
+
+# linear interpolation for [fillgaps]
+
+# HISTORY:
+#	Apr  6, 2006: - created from [.interp.linear]
+#	Jul 28, 2006: - added xf to ISInit() args
+#	Jul 30, 2006: - added max-gap support
+#	Aug  8, 2008: - documentation
+#	Sep 23, 2011: - added support for %RECNO
+#				  - removed xv from interp() args
+#	Oct 19, 2011: - code did not work for %RECNO and trailing missing vals
+#	Jan 23, 2014: - implemented huge speedup for sparse files
+
+# NOTES:
+#	- in contrast to the [.interp.*] routines, the [.nminterp.*] routines:
+#		1) do not assume that x values increase monotonically
+#		2) can handle nans
+#		3) cannot be used with multiple buffers
+#		4) use %RECNO when xfnr==-1
+
+#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+#
+# THE FOLLOWING VARIABLES MUST BE SET GLOBALLY (i.e. during loading)
+#
+#	$ISOpts				string of allowed options
+#	$ISOptsUsage		usage information string for options
+#
+#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+$ISOpts = "";
+$ISOptsUsage = "";
+
+#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+#
+# &ISUsage() 	mangle parameters (options, really)
+#
+#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+sub ISUsage() {}
+
+#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+#
+# &ISInit(f,xf)				init interpolation of field f
+#       f					field number
+#		xf					x field number or -1 for %RECNO
+#       <ret val>           none
+#
+#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+sub ISInit($$) {}
+
+#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+#
+# &interpolate(xf,mg,f,lvr,cr)		interpolate field f
+#		xf							x field or -1 for %RECNO
+#		mg							max allowed x gap
+#		f							field number to interpolate
+#		lvr							last record with valid y val
+#		cr							current record
+#		<ret val>					interpolated value
+#
+# NB:
+#	- handle f == xf
+#	- return undef if interpolation cannot be carried out
+#	- x VALUES MAY NOT BE MONOTONIC
+#
+#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+{ my(@nvr);		# static: next valid record (per field)
+
+	sub interpolate($$$$$$)
+	{
+		my($xf,$mg,$f,$lvr,$cr) = @_;
+	
+		return $ants_[$cr][$xf] if ($xf == $f);
+		return $ants_[$lvr][$f] 				# edge value is ok
+			if ($xf>=0 && equal($ants_[$cr][$xf],$ants_[$lvr][$xf])) ||
+			   ($xf<0 && $cr==$lvr);
+	
+		unless ($nvr[$f] > $cr) {
+			$nvr[$f] = $cr + 1;
+			while ($nvr[$f] <= $#ants_ && !numberp($ants_[$nvr[$f]][$f])) { $nvr[$f]++; }
+		}
+	
+		return undef if ($nvr[$f] > $#ants_);
+		return undef
+			if ($xf>=0 && abs($ants_[$nvr[$f]][$xf]-$ants_[$lvr][$xf])>$mg);
+		return $ants_[$nvr[$f]][$f] 				# edge value is ok
+			if ($xf>=0 && equal($ants_[$cr][$xf],$ants_[$nvr[$f]][$xf])) ||
+			   ($xf<0 && $cr==$nvr[$f]);
+	
+		my($sc) = ($xf >= 0)
+				? ($ants_[$cr][$xf] - $ants_[$lvr][$xf]) / ($ants_[$nvr[$f]][$xf] - $ants_[$lvr][$xf])
+				: ($cr - $lvr) / ($nvr[$f] - $lvr);
+		return $ants_[$lvr][$f] + $sc * ($ants_[$nvr[$f]][$f] - $ants_[$lvr][$f]);
+	}
+} # static scope
+
+#----------------------------------------------------------------------
+
+1;
--- a/HISTORY
+++ b/HISTORY
@@ -1,9 +1,9 @@
 #======================================================================
 #                    H I S T O R Y 
 #                    doc: Thu May  7 13:12:05 2015
-#                    dlm: Fri Aug  5 10:34:27 2016
+#                    dlm: Sun Mar 12 11:59:12 2017
 #                    (c) 2015 A.M. Thurnherr
-#                    uE-Info: 83 10 NIL 0 0 72 0 2 4 NIL ofnI
+#                    uE-Info: 108 10 NIL 0 0 72 0 2 4 NIL ofnI
 #======================================================================
 
 May  7, 2015:
@@ -82,3 +82,27 @@
 	- updated [HISTORY]
 	- V6.7 [ants.pl] [.hg/hgrc] 
 
+Aug  7, 2016:
+	- improved vel_u() vel_v()
+
+Aug 24, 2016:
+	- removed ancient heuristics in [antsusage.pl]
+
+Sep 13, 2016:
+	- updated [HISTORY]
+	- made &antsAddParams() more flexible
+
+Jan 27, 2017:
+	- bug in dayNo()
+
+Mar  9, 2017:
+	- adapted [antsexprs.pl] to perl 5.22
+	- updated [HISTORY]
+
+Mar 10, 2017: 
+	- made [libSBE.pl] more flexible
+
+Mar 12, 2017:
+	- hard-linked .lsfit.poly .nminterp.linear from ../bin because these two
+	  are required by LADCP_VKE
+	- V6.8 [ants.pl] [.hg/hgrc] 
--- 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 Aug  5 10:34:49 2016
+#                    dlm: Sun Mar 12 11:59:52 2017
 #                    (c) 1998 A.M. Thurnherr
-#                    uE-Info: 28 21 NIL 0 0 72 2 2 4 NIL ofnI
+#                    uE-Info: 24 60 NIL 0 0 72 2 2 4 NIL ofnI
 #======================================================================
 
 # HISTORY:
@@ -21,11 +21,12 @@
 #  Mar 17, 2016: - updated to V6.5
 #  Mar 29, 2016: - updated to V6.6
 #  Aug  5, 2016: - updated to V6.7
+#  Mar 12, 2017: - updated to V6.8 (for LADCP_w 1.3 release)
 
 exec($ENV{ANTS_PERL},$0,@ARGV),die("$ENV{ANTS_PERL}: $!")
     if (defined($ENV{ANTS_PERL}) && $^X ne $ENV{ANTS_PERL});
 
-$antsLibVersion = 6.7;
+$antsLibVersion = 6.8;
 
 die(sprintf("$0: obsolete library V%.1f; V%.1f required\n",
 	$antsLibVersion,$antsMinLibVersion))
--- a/antsexprs.pl
+++ b/antsexprs.pl
@@ -2,8 +2,8 @@
 #                    A N T S E X P R S . P L 
 #					 (c) 2005 Andreas Thurnherr
 #                    doc: Sat Dec 31 18:35:33 2005
-#                    dlm: Fri May 15 20:12:34 2015
-#                    uE-Info: 183 56 NIL 0 0 70 2 2 4 NIL ofnI
+#                    dlm: Thu Mar  9 10:12:48 2017
+#                    uE-Info: 46 74 NIL 0 0 72 0 2 4 NIL ofnI
 #======================================================================
 
 # HISTORY:
@@ -43,6 +43,7 @@
 #	Feb 20, 2012: - BUG: quoting had not been implemented
 #	Mar 10, 2012: - added ${field..field} syntax to edit exprs
 #	May 15, 2015: - BUG: -S did not work with :: %PARAMs
+#	Mar  9, 2017: - removed perl 5.22 warning about re (non-quoted braces)
 
 $DEBUG = 0;
 
@@ -164,7 +165,7 @@
 	print(STDERR "MID AddrExpr = $expr\n") if ($DEBUG);
 	$expr =~ s{\$%}{%}g;								# allow for $%param
 	$expr =~ s{\$\$}{ AnTsDoLlAr }g;					# escape
-	while ($expr =~ /\${([^}]*)}/) {					# ${field}
+	while ($expr =~ /\$\{([^}]*)\}/) {					# ${field}
 		my($fnr) = cardinalp($1) ? $1-1 : fnr($1);
 		croak("$0: unknown field $1\n") unless ($fnr >= 0);
 		$expr =~ s(\${$1})(AnTsDtArEf\[$fnr\]);
@@ -226,7 +227,7 @@
 
 	$expr =~ s{\$%}{%}g;								# allow for $%param
 	$expr =~ s{\$\$}{AnTsDoLlAr}g;						# escape
-	while ($expr =~ /\${([^}]*)\.\.([^}]*)}/) {			# ${field..field}
+	while ($expr =~ /\$\{([^}]*)\.\.([^}]*)\}/) {			# ${field..field}
 		$antsEditExprUsesFields |= 1;
 		my($ffnr) = cardinalp($1) ? $1-1 : fnr($1);
 		croak("$0: unknown field $1\n") unless ($ffnr >= 0);
@@ -241,7 +242,7 @@
 		}
 		$expr =~ s(\${$1\.\.$2})($expanded);
 	}
-	while ($expr =~ /\${([^}]*)}/) {					# ${field}
+	while ($expr =~ /\$\{([^}]*)\}/) {					# ${field}
 		$antsEditExprUsesFields |= 1;
 		my($fnr) = cardinalp($1) ? $1-1 : fnr($1);
 		croak("$0: unknown field $1\n") unless ($fnr >= 0);
--- 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: Fri Jan 15 10:15:22 2016
+#                    dlm: Fri Mar 10 09:53:21 2017
 #                    (c) 1998 A.M. Thurnherr
-#                    uE-Info: 212 33 NIL 0 0 70 2 2 4 NIL ofnI
+#                    uE-Info: 214 71 NIL 0 0 70 2 2 4 NIL ofnI
 #======================================================================
 
 # HISTORY:
@@ -210,6 +210,8 @@
 #	Jan 15, 2016: - BUG: antsCheckDeps() cannot delete the dependencies after checking because,
 #						 otherwise, dependencies are not inherited => presumably, Sep 27 bug fix has been
 #						 reversed
+#	Sep 13, 2016: - modified &antsAddParams to make more flexible
+#	Mar 10, 2017: - BUT: antsCheckDeps() used ctime instead of mtime!!!
 
 # GENERAL NOTES:
 #	- %P was named without an ants-prefix because associative arrays
@@ -303,12 +305,12 @@
 	  my(@stat) = stat($infile);					# get time
 	  return unless (@stat);						# happens on stdin?
 	  
-	  my($ctimef) = 10; my($ctime) = $stat[$ctimef];
+	  my($mtimef) = 9; my($mtime) = $stat[$mtimef];
 	  for (my($d)=0; $d<=$#antsDeps; $d++) {
 		  @stat = stat($antsDeps[$d]);
 		  if (@stat) {
-			  croak("$0: <$infile> is stale with respect to <$antsDeps[$d]>\n")
-				  unless ($stat[$ctimef] <= $ctime);
+			  croak("$0: <$infile> ($mtime) is stale with respect to <$antsDeps[$d]> ($stat[$mtime])\n")
+				  unless ($stat[$mtimef] <= $mtime);
 		  } elsif (!$warned) {
 			  &antsInfo("WARNING: dependency $antsDeps[$d] (&, possibly, others) not found");
 			  $warned = 1;
@@ -872,14 +874,19 @@
 {
 	my($i);	
 
-	$antsCurParams .= "#ANTS#PARAMS#";
+	$antsCurParams .= "#ANTS#PARAMS#";			# first, create new param spec
 	for ($i=0; $i<$#_; $i+=2) {
 		my($v) = $_[$i+1];
 		$v =~ s/\n/\\n/g;
-		$P{$_[$i]} = $v;
 		$antsCurParams .= " $_[$i]\{$v\}";
 	}
 	$antsCurParams .= "\n";
+
+	for ($i=0; $i<$#_; $i+=2) {					# then, set (overwrite) param vals
+		my($v) = $_[$i+1];
+		$v =~ s/\n/\\n/g;
+		$P{$_[$i]} = $v;
+	}
 }
 
 sub antsFileParams()							# get params from file
--- a/antsusage.pl
+++ b/antsusage.pl
@@ -2,9 +2,9 @@
 #======================================================================
 #                    A N T S U S A G E . P L 
 #                    doc: Fri Jun 19 13:43:05 1998
-#                    dlm: Fri May 15 18:46:22 2015
+#                    dlm: Wed Aug 24 15:06:44 2016
 #                    (c) 1998 A.M. Thurnherr
-#                    uE-Info: 161 75 NIL 0 0 70 2 2 4 NIL ofnI
+#                    uE-Info: 163 46 NIL 0 0 70 2 2 4 NIL ofnI
 #======================================================================
 
 # HISTORY:
@@ -159,6 +159,8 @@
 #	Jan 30, 2015: - added &antsFunOpt()
 #	Jan 31, 2015: - made it work
 #	May 15, 2015: - changed (()) semantics to expand only to existing files
+#	Aug 24, 2016: - removed -ve number heuristics (unshifting a -- under certain conditions),
+#				  	which I believe is ancient
 
 # NOTES:
 #	- ksh expands {}-arguments with commas in them!!! Use + instead
@@ -208,7 +210,10 @@
 	&antsUsageError()									# no args && tty stdin
 		if (!$antsInteractive && $min == 0 && @ARGV == 0 && -t 0);
 	
-	unshift(@ARGV,'--') if ($ARGV[0] =~ /^-\d/);		# -ve number heuristics
+#		The following line of code, disabled Aug 24, 2016, prevents
+#		numerical options from working, e.g. in LADCP_w.
+#
+#	unshift(@ARGV,'--') if ($ARGV[0] =~ /^-\d/);		# -ve number heuristics
 
 	chomp($0 = `basename $0`);							# set scriptname
 	chop($d = `date +%D`);								# build header line
--- 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: Tue May 31 13:12:22 2016
+#                    dlm: Fri Mar 10 09:46:42 2017
 #                    (c) 2014 A.M. Thurnherr
-#                    uE-Info: 287 43 NIL 0 0 72 2 2 4 NIL ofnI
+#                    uE-Info: 20 55 NIL 0 0 72 2 2 4 NIL ofnI
 #======================================================================
 
 # HISTORY:
@@ -17,6 +17,7 @@
 #				    all conducitivities with units not equal to the first cond var
 #				  - 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
 
 #----------------------------------------------------------------------
 # fname_SBE2std($)
@@ -271,6 +272,8 @@
 			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)) {
+				$lat = $deg + $min/60;
 			} else {
 				print(STDERR "$0: WARNING: cannot decode latitude ($')\n");
 				$lat = nan;
@@ -283,6 +286,8 @@
 			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)) {
+				$lon = $deg + $min/60;
 			} else {
 				print(STDERR "$0: WARNING: cannot decode longitude ($')\n");
 				$lon= nan;
--- 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: Thu Aug  7 09:17:59 2014
+#                    dlm: Fri Jan 27 10:47:21 2017
 #                    (c) 1999 A.M. Thurnherr
-#                    uE-Info: 203 27 NIL 0 0 70 2 2 4 NIL ofnI
+#                    uE-Info: 194 13 NIL 0 0 70 2 2 4 NIL ofnI
 #======================================================================
 
 # HISTORY:
@@ -62,6 +62,7 @@
 #	May 22, 2012: - BUG: illegal time spec error was also produced on missing seconds
 #				  - BUG: mmddyy2dec_time() did not allow for optional epoch argument
 #	Aug  7, 2014: - finally cleaned up date conversions
+#	Jan 27, 2017: - BUG: dayNO() numeric month could have leading/trailing whitespace
 
 require "$ANTS/libEOS83.pl";                        # &sigma()
 require "$ANTS/libPOSIX.pl";                        # &floor()
@@ -100,6 +101,8 @@
         &antsFunUsage(-3,"c..","year, month, day[, epoch]",@_);
 	$epoch = $y unless defined($epoch);
 
+	$m =~ s/\s//g;
+
 	unless (cardinalp($m)) {
 		$m = lc($m);
 		if    ($m =~ /^jan/) { $m = 1; }
@@ -188,6 +191,8 @@
 	{
 		my($ds,$ts,$epoch) =
 			&antsFunUsage(-2,"..","date, hh:mm[:ss][, epoch]",@_);
+		$ds =~ s/\s//g;
+		$ts =~ s/\s//g;
 	
 		croak("$0 str2dec_time: date required\n") unless ($ds ne '');
 
--- a/libvec.pl
+++ b/libvec.pl
@@ -1,9 +1,9 @@
 #======================================================================
 #                    L I B V E C . P L 
 #                    doc: Sat Mar 20 12:50:32 1999
-#                    dlm: Fri Jul 29 15:26:45 2016
+#                    dlm: Sun Aug  7 22:06:57 2016
 #                    (c) 1999 A.M. Thurnherr
-#                    uE-Info: 42 32 NIL 0 0 70 2 2 4 NIL ofnI
+#                    uE-Info: 137 37 NIL 0 0 70 2 2 4 NIL ofnI
 #======================================================================
 
 # HISTORY:
@@ -40,6 +40,7 @@
 #						 (previous version only used for 2014 CLIVAR P06
 #						 processing with IMP data with confused coord
 #						 system)
+#	Aug  7, 2016: - made vel_u and vel_v deal with nans
 
 require "$ANTS/libPOSIX.pl";	# acos()
 
@@ -133,7 +134,8 @@
 
 sub cartesian_x(@)
 {
-	my($r,$phi) = &antsFunUsage(2,"ff","<r> <phi>",@_);
+	my($r,$phi) = &antsFunUsage(2,"..","<r> <phi>",@_);
+	return nan unless numbersp($r,$phi);
 	return $r * cos($PI*$phi/180);
 }
 
@@ -141,7 +143,8 @@
 
 sub cartesian_y(@)
 {
-	my($r,$phi) = &antsFunUsage(2,"ff","<r> <phi>",@_);
+	my($r,$phi) = &antsFunUsage(2,"..","<r> <phi>",@_);
+	return nan unless numbersp($r,$phi);
 	return $r * sin($PI*$phi/180);
 }