mkProfile
changeset 5 29faa9e6226c
parent 4 7e43b24080af
child 7 e06925788055
equal deleted inserted replaced
4:7e43b24080af 5:29faa9e6226c
     1 #!/usr/bin/perl
     1 #!/usr/bin/perl
     2 #======================================================================
     2 #======================================================================
     3 #                    M K P R O F I L E 
     3 #                    M K P R O F I L E 
     4 #                    doc: Sun Jan 19 18:55:26 2003
     4 #                    doc: Sun Jan 19 18:55:26 2003
     5 #                    dlm: Fri Dec 10 14:52:16 2010
     5 #                    dlm: Wed Jan  5 01:05:50 2011
     6 #                    (c) 2003 A.M. Thurnherr
     6 #                    (c) 2003 A.M. Thurnherr
     7 #                    uE-Info: 231 0 NIL 0 0 72 2 2 4 NIL ofnI
     7 #                    uE-Info: 233 47 NIL 0 0 72 2 2 4 NIL ofnI
     8 #======================================================================
     8 #======================================================================
     9 
     9 
    10 # Make an LADCP Profile by Integrating W (similar to Firing's scan*).
    10 # Make an LADCP Profile by Integrating W (similar to Firing's scan*).
    11 
    11 
    12 # HISTORY:
    12 # HISTORY:
    68 #				  - removed approximations in pitch/roll calcs
    68 #				  - removed approximations in pitch/roll calcs
    69 #	Jul 30, 2009: - typo '<' removed from output
    69 #	Jul 30, 2009: - typo '<' removed from output
    70 #				  - NaN => nan
    70 #				  - NaN => nan
    71 #	Dec  8, 2010: - added zmax/zend labels to output
    71 #	Dec  8, 2010: - added zmax/zend labels to output
    72 #	Dec 10, 2010: - made mkProfile exit with status 0 if no good ens found but -Q is set
    72 #	Dec 10, 2010: - made mkProfile exit with status 0 if no good ens found but -Q is set
       
    73 #	Dec 19, 2010: - finally made -A default and activated output file
       
    74 #	Jan  5, 2011: - made no-good-ensembles found test much more robust
    73 
    75 
    74 # NOTES:
    76 # NOTES:
    75 #	- the battery values are based on transmission voltages (different
    77 #	- the battery values are based on transmission voltages (different
    76 #	  from battery voltages) and reported without units (raw 8-bit a2d
    78 #	  from battery voltages) and reported without units (raw 8-bit a2d
    77 #	  values)
    79 #	  values)
    91 require "$1/RDI_Utils.pl";
    93 require "$1/RDI_Utils.pl";
    92 require "getopts.pl";
    94 require "getopts.pl";
    93 
    95 
    94 $USAGE = "$0 @ARGV";
    96 $USAGE = "$0 @ARGV";
    95 die("Usage: $0 " .
    97 die("Usage: $0 " .
    96 	"[-A)nts] [-Q)uiet] [-F)ilter <script>] " .
    98 	"[-Q)uiet] [-F)ilter <script>] " .
    97 	"[-s)uppress checkensemble()] " .
    99 	"[-s)uppress checkensemble()] " .
    98 	"[require -4)-beam solutions] " .
   100 	"[require -4)-beam solutions] " .
    99 	"[-r)ef-layer <bin|1,bin|6>] [-n) vels <min|2>] " .
   101 	"[-r)ef-layer <bin|1,bin|6>] [-n) vels <min|2>] " .
   100 	"[-e)rr-vel <max|0.1>] [-c)orrelation <min>] " .
   102 	"[-e)rr-vel <max|0.1>] [-c)orrelation <min>] " .
   101 	"[-m)ax <gap>] " .
   103 	"[-m)ax <gap>] " .
   102 	"[-d)rift <dx,dy>] [-g)ps <start lat,lon/end lat,lon>] " .
   104 	"[-d)rift <dx,dy>] [-g)ps <start lat,lon/end lat,lon>] " .
   103 	"[output -f)ields <field[,...]> " .
   105 	"[output -f)ields <field[,...]> " .
   104 	"[-M)agnetic <declination>] [profile -B)ottom <depth>] " .
   106 	"[-M)agnetic <declination>] [profile -B)ottom <depth>] " .
   105 	"<RDI file>\n")
   107 	"<RDI file>\n")
   106 		unless (&Getopts("4AB:F:M:Qd:r:n:e:c:g:f:m:s") && @ARGV == 1);
   108 		unless (&Getopts("4AB:F:M:Qd:r:n:e:c:g:f:m:s") && @ARGV == 1);
   107 
       
   108 die("$0: -Q and -A are mutually exclusive\n")
       
   109 	if ($opt_Q && $opt_A);
       
   110 
   109 
   111 $RDI_Coords::minValidVels = 4 if ($opt_4);			# no 3-beam solutions
   110 $RDI_Coords::minValidVels = 4 if ($opt_4);			# no 3-beam solutions
   112 
   111 
   113 require $opt_F if defined($opt_F);					# load filter
   112 require $opt_F if defined($opt_F);					# load filter
   114 
   113 
   224 #======================================================================
   223 #======================================================================
   225 
   224 
   226 ($firstgood,$lastgood,$atbottom,$w_gap_time,$zErr,$maxz) =
   225 ($firstgood,$lastgood,$atbottom,$w_gap_time,$zErr,$maxz) =
   227 	mk_prof(\%dta,!$opt_s,$opt_F,$minb,$maxb,$opt_c,$opt_e,$opt_m);
   226 	mk_prof(\%dta,!$opt_s,$opt_F,$minb,$maxb,$opt_c,$opt_e,$opt_m);
   228 
   227 
   229 unless (defined($firstgood)) {
   228 unless (($atbottom > $firstgood) && ($lastgood > $atbottom)) {
   230 	if ($opt_Q) {
   229 	if ($opt_Q) {
   231 		print(STDERR "$ARGV[0]: no good ensembles found\n");
   230 		print(STDERR "$ARGV[0]: no valid cast data found\n");
   232 		exit(0);
   231 		exit(0);
   233     } else {
   232     } else {
   234 		die("$ARGV[0]: no good ensembles found\n");
   233 		die("$ARGV[0]: no valid cast data found\n");
   235 	}
   234 	}
   236 }
   235 }
   237 
   236 
   238 if (defined($opt_B)) {										# scale Z
   237 if (defined($opt_B)) {										# scale Z
   239 	my($zscale) = $opt_B / ($dta{ENSEMBLE}[$atbottom]->{DEPTH} -# downcast
   238 	my($zscale) = $opt_B / ($dta{ENSEMBLE}[$atbottom]->{DEPTH} -# downcast
   686                                  	 "$RDI_Coords::threeBeam_4\n")
   685                                  	 "$RDI_Coords::threeBeam_4\n")
   687 	unless ($opt_4);
   686 	unless ($opt_4);
   688 printf(STDERR "net rotations        : [%d]/%d/%d/[%d]\n",$prerot,$dnrot,$uprot,$postrot);
   687 printf(STDERR "net rotations        : [%d]/%d/%d/[%d]\n",$prerot,$dnrot,$uprot,$postrot);
   689 printf(STDERR "rms pitch/roll       : %.1f/%.1f\n",$dnprrms,$upprrms);
   688 printf(STDERR "rms pitch/roll       : %.1f/%.1f\n",$dnprrms,$upprrms);
   690 
   689 
   691 if ($opt_A) {												# ANTS format
   690 exit(0) if ($opt_Q);
   692 	print("#ANTS# [] $USAGE\n");
   691 
   693 	$uFields = "{u} {u_err} {v} {v_err} {x} {x_err} {y} {y_err}"
   692 #----------------------------------------------------------------------
   694 		if defined($opt_M);
   693 # output profile in active ANTS format
   695 	print("#ANTS#FIELDS# {ens} {time} {elapsed} {secno} {downcast} " .
   694 #----------------------------------------------------------------------
   696 						"{w} {w_err} {depth} {depth_err} {depth_BT} " .
   695 
   697 						"{pitchroll} {rotation} " .
   696 print("#!/usr/bin/perl -S list\n");		
   698 		  				"$uFields $addFields\n");
   697 chmod(0777&~umask,*STDOUT);
   699 
   698 
   700    	printf("#ANTS#PARAMS# date{$dta{ENSEMBLE}[$firstgood]->{DATE}} " .
   699 print("#ANTS# [] $USAGE\n");
   701 				   "start_time{$dta{ENSEMBLE}[$firstgood]->{TIME}} " .
   700 $uFields = "{u} {u_err} {v} {v_err} {x} {x_err} {y} {y_err}"
   702 				  "bottom_time{$dta{ENSEMBLE}[$atbottom]->{TIME}} " .
   701 	if defined($opt_M);
   703 				     "end_time{$dta{ENSEMBLE}[$lastgood]->{TIME}} " .
   702 print("#ANTS#FIELDS# {ens} {time} {elapsed} {secno} {downcast} " .
   704 		  "bottom_xmit_voltage{$dta{ENSEMBLE}[$atbottom]->{ADC_XMIT_VOLTAGE}} " .
   703 					"{w} {w_err} {depth} {depth_err} {depth_BT} " .
   705 		  "bottom_xmit_current{$dta{ENSEMBLE}[$atbottom]->{ADC_XMIT_CURRENT}} " .
   704 					"{pitchroll} {rotation} " .
   706 			 "pinging_duration{%.1f} " .
   705 					"$uFields $addFields\n");
   707 			    "cast_duration{%.1f} " .
   706 
   708 	    	   "0.8_valid_bins{%.1f} " .
   707 printf("#ANTS#PARAMS# date{$dta{ENSEMBLE}[$firstgood]->{DATE}} " .
   709 	     	  "0.8_valid_range{%.1f} " .
   708 			   "start_time{$dta{ENSEMBLE}[$firstgood]->{TIME}} " .
   710 				    "max_depth{%.1f} " .
   709 			  "bottom_time{$dta{ENSEMBLE}[$atbottom]->{TIME}} " .
   711 				  "depth_error{%.1f} " .
   710 				 "end_time{$dta{ENSEMBLE}[$lastgood]->{TIME}} " .
   712 				    "min_range{%d} " .
   711 	  "bottom_xmit_voltage{$dta{ENSEMBLE}[$atbottom]->{ADC_XMIT_VOLTAGE}} " .
   713 				  "n_ensembles{%d} " .
   712 	  "bottom_xmit_current{$dta{ENSEMBLE}[$atbottom]->{ADC_XMIT_CURRENT}} " .
   714 				   "w_gap_time{%d} " .
   713 		 "pinging_duration{%.1f} " .
   715 				     "stderr_w{%.4f} " .
   714 			"cast_duration{%.1f} " .
   716 				"rms_pitchroll{%.1f} " .
   715 		   "0.8_valid_bins{%.1f} " .
   717   	   "downcast_rms_pitchroll{%.1f} " .
   716 		  "0.8_valid_range{%.1f} " .
   718 		 "upcast_rms_pitchroll{%.1f} " .
   717 				"max_depth{%.1f} " .
   719 				 "rms_rotation{%.2f} " .
   718 			  "depth_error{%.1f} " .
   720 		 "deployment_rotations{%d} " .
   719 				"min_range{%d} " .
   721 		   "downcast_rotations{%d} " .
   720 			  "n_ensembles{%d} " .
   722 		     "upcast_rotations{%d} " .
   721 			   "w_gap_time{%d} " .
   723 		   "recovery_rotations{%d} " .
   722 				 "stderr_w{%.4f} " .
   724 				    "bin1_dist{%.1f} " .
   723 			"rms_pitchroll{%.1f} " .
   725 				   "bin_length{%.1f} " .
   724    "downcast_rms_pitchroll{%.1f} " .
   726 		  				 "\n",
   725 	 "upcast_rms_pitchroll{%.1f} " .
   727 				($dta{ENSEMBLE}[$#{$dta{ENSEMBLE}}]->{UNIX_TIME} -
   726 			 "rms_rotation{%.2f} " .
   728 						$dta{ENSEMBLE}[0]->{UNIX_TIME}),
   727 	 "deployment_rotations{%d} " .
   729 				$dta{ENSEMBLE}[$lastgood]->{ELAPSED_TIME},
   728 	   "downcast_rotations{%d} " .
   730 				$gb+1,
   729 		 "upcast_rotations{%d} " .
   731 				$dta{DISTANCE_TO_BIN1_CENTER} + $gb*$dta{BIN_LENGTH},
   730 	   "recovery_rotations{%d} " .
   732 				$dta{ENSEMBLE}[$atbottom]->{DEPTH},
   731 				"bin1_dist{%.1f} " .
   733 				$dta{ENSEMBLE}[$lastgood]->{DEPTH} -
   732 			   "bin_length{%.1f} " .
   734 					$dta{ENSEMBLE}[$firstgood]->{DEPTH},
   733 					 "\n",
   735 				$dta{DISTANCE_TO_BIN1_CENTER} +
   734 			($dta{ENSEMBLE}[$#{$dta{ENSEMBLE}}]->{UNIX_TIME} -
   736 					$min_good_bins*$dta{BIN_LENGTH},
   735 					$dta{ENSEMBLE}[0]->{UNIX_TIME}),
   737 				scalar(@{$dta{ENSEMBLE}}),
       
   738 				$w_gap_time,$wErr,$prrms,$dnprrms,$upprrms,$rotrms,
       
   739 				$prerot,$dnrot,$uprot,$postrot,
       
   740 				$dta{DISTANCE_TO_BIN1_CENTER},
       
   741 				$dta{BIN_LENGTH},
       
   742 		  );
       
   743 	printf("#ANTS#PARAMS# magnetic_declination{$opt_M} " .
       
   744 							   	  "uv_gap_time{%d} " .
       
   745 						    	       "mean_u{%.4f} " .
       
   746 							         "stderr_u{%.4f} " .
       
   747 							               "dx{%d} " .
       
   748 							           "dx_err{%d} " .
       
   749 							           "mean_v{%.4f} " .
       
   750 							         "stderr_v{%.4f} " .
       
   751 							               "dy{%d} " .
       
   752 							           "dy_err{%d}\n",
       
   753 		$uv_gap_time,
       
   754 		$dta{ENSEMBLE}[$lastgood]->{X} /
       
   755 			$dta{ENSEMBLE}[$lastgood]->{ELAPSED_TIME},
   736 			$dta{ENSEMBLE}[$lastgood]->{ELAPSED_TIME},
   756 		$uErr, $dta{ENSEMBLE}[$lastgood]->{X}, $x_err,
   737 			$gb+1,
   757 		$dta{ENSEMBLE}[$lastgood]->{Y} /
   738 			$dta{DISTANCE_TO_BIN1_CENTER} + $gb*$dta{BIN_LENGTH},
   758 			$dta{ENSEMBLE}[$lastgood]->{ELAPSED_TIME},
   739 			$dta{ENSEMBLE}[$atbottom]->{DEPTH},
   759 		$vErr, $dta{ENSEMBLE}[$lastgood]->{Y}, $y_err,
   740 			$dta{ENSEMBLE}[$lastgood]->{DEPTH} -
   760 	) if defined ($opt_M);
   741 				$dta{ENSEMBLE}[$firstgood]->{DEPTH},
   761 	print("#ANTS#PARAMS# start_lat{$s_lat} start_lon{$s_lon} " .
   742 			$dta{DISTANCE_TO_BIN1_CENTER} +
   762 						  "end_lat{$e_lat} end_lon{$e_lon} " .
   743 				$min_good_bins*$dta{BIN_LENGTH},
   763 						      "lat{$lat} lon{$lon}\n")
   744 			scalar(@{$dta{ENSEMBLE}}),
   764 		if defined($lat);
   745 			$w_gap_time,$wErr,$prrms,$dnprrms,$upprrms,$rotrms,
   765 	if ($dta{TIME_BETWEEN_PINGS} == 0) {
   746 			$prerot,$dnrot,$uprot,$postrot,
   766 		 print("#ANTS#PARAMS# pinging_rate{staggered}\n");
   747 			$dta{DISTANCE_TO_BIN1_CENTER},
   767 	} else {
   748 			$dta{BIN_LENGTH},
   768 		 printf("#ANTS#PARAMS# pinging_rate{%.2f}\n",
   749 	  );
   769 			1/$dta{TIME_BETWEEN_PINGS});
   750 printf("#ANTS#PARAMS# magnetic_declination{$opt_M} " .
   770     }		
   751 							  "uv_gap_time{%d} " .
   771     printf("#ANTS#PARAMS# drift_x{%d} drift_y{%d} " .
   752 								   "mean_u{%.4f} " .
   772 						 "drift_u{%.3f} drift_v{%.3f} " .
   753 								 "stderr_u{%.4f} " .
   773 		   "\n",$ddx,$ddy,$du,$dv) if defined($ddx);
   754 									   "dx{%d} " .
   774 	if (defined($water_depth)) {
   755 								   "dx_err{%d} " .
   775 		printf("#ANTS#PARAMS# water_depth{%d} sig-water_depth{%d}\n",
   756 								   "mean_v{%.4f} " .
   776 					$water_depth,$sig_wd);
   757 								 "stderr_v{%.4f} " .
   777 	} else {
   758 									   "dy{%d} " .
   778 		print("#ANTS#PARAMS# water_depth{nan} sig-water_depth{nan}\n");
   759 								   "dy_err{%d}\n",
   779 	}
   760 	$uv_gap_time,
       
   761 	$dta{ENSEMBLE}[$lastgood]->{X} /
       
   762 		$dta{ENSEMBLE}[$lastgood]->{ELAPSED_TIME},
       
   763 	$uErr, $dta{ENSEMBLE}[$lastgood]->{X}, $x_err,
       
   764 	$dta{ENSEMBLE}[$lastgood]->{Y} /
       
   765 		$dta{ENSEMBLE}[$lastgood]->{ELAPSED_TIME},
       
   766 	$vErr, $dta{ENSEMBLE}[$lastgood]->{Y}, $y_err,
       
   767 ) if defined ($opt_M);
       
   768 print("#ANTS#PARAMS# start_lat{$s_lat} start_lon{$s_lon} " .
       
   769 					  "end_lat{$e_lat} end_lon{$e_lon} " .
       
   770 						  "lat{$lat} lon{$lon}\n")
       
   771 	if defined($lat);
       
   772 if ($dta{TIME_BETWEEN_PINGS} == 0) {
       
   773 	 print("#ANTS#PARAMS# pinging_rate{staggered}\n");
       
   774 } else {
       
   775 	 printf("#ANTS#PARAMS# pinging_rate{%.2f}\n",
       
   776 		1/$dta{TIME_BETWEEN_PINGS});
       
   777 }	    
       
   778 printf("#ANTS#PARAMS# drift_x{%d} drift_y{%d} " .
       
   779 					 "drift_u{%.3f} drift_v{%.3f} " .
       
   780 	   "\n",$ddx,$ddy,$du,$dv) if defined($ddx);
       
   781 if (defined($water_depth)) {
       
   782 	printf("#ANTS#PARAMS# water_depth{%d} sig-water_depth{%d}\n",
       
   783 				$water_depth,$sig_wd);
       
   784 } else {
       
   785 	print("#ANTS#PARAMS# water_depth{nan} sig-water_depth{nan}\n");
   780 }
   786 }
   781 
   787 
   782 sub p($) { print(defined($_[0])?"$_[0] ":"nan "); }
   788 sub p($) { print(defined($_[0])?"$_[0] ":"nan "); }
   783 sub pb($) { print($_[0]?"1 ":"0 "); }
   789 sub pb($) { print($_[0]?"1 ":"0 "); }
   784 
   790 
   785 unless ($opt_Q) {										# write profile
   791 for ($e=$firstgood; $e<=$lastgood; $e++) {
   786 	for ($e=$firstgood; $e<=$lastgood; $e++) {
   792 	p($dta{ENSEMBLE}[$e]->{NUMBER});
   787 		p($dta{ENSEMBLE}[$e]->{NUMBER});
   793 	p($dta{ENSEMBLE}[$e]->{UNIX_TIME});
   788 		p($dta{ENSEMBLE}[$e]->{UNIX_TIME});
   794 	p($dta{ENSEMBLE}[$e]->{ELAPSED_TIME});
   789 		p($dta{ENSEMBLE}[$e]->{ELAPSED_TIME});
   795 	p($dta{ENSEMBLE}[$e]->{SECNO});
   790 		p($dta{ENSEMBLE}[$e]->{SECNO});
   796 	pb($dta{ENSEMBLE}[$e]->{UNIX_TIME} < $dta{ENSEMBLE}[$atbottom]->{UNIX_TIME});
   791 		pb($dta{ENSEMBLE}[$e]->{UNIX_TIME} < $dta{ENSEMBLE}[$atbottom]->{UNIX_TIME});
   797 	p($dta{ENSEMBLE}[$e]->{W});
   792 		p($dta{ENSEMBLE}[$e]->{W});
   798 	p($dta{ENSEMBLE}[$e]->{W_ERR});
   793 		p($dta{ENSEMBLE}[$e]->{W_ERR});
   799 	p($dta{ENSEMBLE}[$e]->{DEPTH});
   794 		p($dta{ENSEMBLE}[$e]->{DEPTH});
   800 	p($dta{ENSEMBLE}[$e]->{DEPTH_ERR});
   795 		p($dta{ENSEMBLE}[$e]->{DEPTH_ERR});
   801 	p($dta{ENSEMBLE}[$e]->{DEPTH_BT});
   796 		p($dta{ENSEMBLE}[$e]->{DEPTH_BT});
   802 	p($dta{ENSEMBLE}[$e]->{PITCHROLL});
   797 		p($dta{ENSEMBLE}[$e]->{PITCHROLL});
   803 	p($dta{ENSEMBLE}[$e]->{ROTATION});
   798 		p($dta{ENSEMBLE}[$e]->{ROTATION});
   804 	if (defined($opt_M)) {
   799 		if (defined($opt_M)) {
   805 		p($dta{ENSEMBLE}[$e]->{U}); p($dta{ENSEMBLE}[$e]->{U_ERR});
   800 			p($dta{ENSEMBLE}[$e]->{U}); p($dta{ENSEMBLE}[$e]->{U_ERR});
   806 		p($dta{ENSEMBLE}[$e]->{V}); p($dta{ENSEMBLE}[$e]->{V_ERR});
   801 			p($dta{ENSEMBLE}[$e]->{V}); p($dta{ENSEMBLE}[$e]->{V_ERR});
   807 		p($dta{ENSEMBLE}[$e]->{X}); p($dta{ENSEMBLE}[$e]->{X_ERR});
   802 			p($dta{ENSEMBLE}[$e]->{X}); p($dta{ENSEMBLE}[$e]->{X_ERR});
   808 		p($dta{ENSEMBLE}[$e]->{Y}); p($dta{ENSEMBLE}[$e]->{Y_ERR});
   803 			p($dta{ENSEMBLE}[$e]->{Y}); p($dta{ENSEMBLE}[$e]->{Y_ERR});
   809 	}
   804 	    }
   810 	if (defined(@f)) {
   805 		if (defined(@f)) {
   811 		foreach $f (@f) {
   806 			foreach $f (@f) {
   812 			my($fn,$fi) = ($f =~ m{([^[]*)(\[.*)});
   807 				my($fn,$fi) = ($f =~ m{([^[]*)(\[.*)});
   813 			$fn = $f unless defined($fn);
   808 				$fn = $f unless defined($fn);
   814 			p(eval("\$dta{ENSEMBLE}[$e]->{$fn}$fi"));
   809 				p(eval("\$dta{ENSEMBLE}[$e]->{$fn}$fi"));
       
   810 			}
       
   811 		}
   815 		}
   812 		print("\n");
   816 	}
   813 	}
   817 	print("\n");
   814 }
   818 }
   815 
   819 
   816 exit(0);
   820 exit(0);