mkProfile
changeset 8 7ad053ea1742
parent 7 e06925788055
child 11 9c3b147b4372
equal deleted inserted replaced
7:e06925788055 8:7ad053ea1742
     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: Wed Jun 22 05:39:48 2011
     5 #                    dlm: Wed Sep 21 12:03:14 2011
     6 #                    (c) 2003 A.M. Thurnherr
     6 #                    (c) 2003 A.M. Thurnherr
     7 #                    uE-Info: 245 0 NIL 0 0 72 2 2 4 NIL ofnI
     7 #                    uE-Info: 747 30 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:
    73 #	Dec 19, 2010: - finally made -A default and activated output file
    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
    74 #	Jan  5, 2011: - made no-good-ensembles found test much more robust
    75 #	Jun 22, 2011: - added bandwith/power warnings
    75 #	Jun 22, 2011: - added bandwith/power warnings
    76 #				  - added ping-interval calculation
    76 #				  - added ping-interval calculation
    77 #				  - BUG: post-recovery rotations were always zero
    77 #				  - BUG: post-recovery rotations were always zero
       
    78 #	Sep  9, 2011: - BUG: range calculation for Earth coordinate data included bins without
       
    79 #						 valid velocities
       
    80 #	Sep 21, 2010: - added %rms_heave_acceleration
    78 
    81 
    79 # NOTES:
    82 # NOTES:
    80 #	- the battery values are based on transmission voltages (different
    83 #	- the battery values are based on transmission voltages (different
    81 #	  from battery voltages) and reported without units (raw 8-bit a2d
    84 #	  from battery voltages) and reported without units (raw 8-bit a2d
    82 #	  values)
    85 #	  values)
   232 
   235 
   233 unless ($dta{TRANSMIT_POWER_HIGH}) {
   236 unless ($dta{TRANSMIT_POWER_HIGH}) {
   234 	print(STDERR "WARNING: $0 LOW TRANSMIT POWER!\n");
   237 	print(STDERR "WARNING: $0 LOW TRANSMIT POWER!\n");
   235 }
   238 }
   236 
   239 
   237 printf(STDERR "# of ensembles       : %d\n",scalar(@{$dta{ENSEMBLE}}));
   240 printf(STDERR "# of ensembles        : %d\n",scalar(@{$dta{ENSEMBLE}}));
   238 
   241 
   239 my($sdt1,$sdt2,$ndt);
   242 my($sdt1,$sdt2,$ndt);
   240 my($mindt1) = my($mindt2) = 9e99;
   243 my($mindt1) = my($mindt2) = 9e99;
   241 my($maxdt1) = my($maxdt2) = 0;
   244 my($maxdt1) = my($maxdt2) = 0;
   242 for (my($e)=2; $e<=$#{$dta{ENSEMBLE}}; $e+=2,$ndt++) {
   245 for (my($e)=2; $e<=$#{$dta{ENSEMBLE}}; $e+=2,$ndt++) {
   247 	$maxdt1 = $dt1 if ($dt1 > $maxdt1);
   250 	$maxdt1 = $dt1 if ($dt1 > $maxdt1);
   248 	$maxdt2 = $dt2 if ($dt2 > $maxdt2);
   251 	$maxdt2 = $dt2 if ($dt2 > $maxdt2);
   249 	$sdt1 += $dt1; $sdt2 += $dt2;
   252 	$sdt1 += $dt1; $sdt2 += $dt2;
   250 }
   253 }
   251 
   254 
   252 printf(STDERR "Ping intervals       : %.1fs/%.1fs (%.1fs-%.1fs/%.1fs-%.1fs)\n",
   255 printf(STDERR "Ping intervals        : %.1fs/%.1fs",$sdt1/$ndt,$sdt2/$ndt);
   253 			$sdt1/$ndt,$sdt2/$ndt,$mindt1,$maxdt1,$mindt2,$maxdt2);
   256 if ($maxdt1-$mindt1>=0.1 || $maxdt2-$mindt2>=0.1) {
       
   257 	printf(STDERR " (%.1fs-%.1fs/%.1fs-%.1fs)\n",$mindt1,$maxdt1,$mindt2,$maxdt2);
       
   258 } else {
       
   259 	print(STDERR "\n");
       
   260 }
   254 
   261 
   255 #======================================================================
   262 #======================================================================
   256 # Step 1: Integrate w & determine water depth 
   263 # Step 1: Integrate w & determine water depth 
   257 #======================================================================
   264 #======================================================================
   258 
   265 
   259 ($firstgood,$lastgood,$atbottom,$w_gap_time,$zErr,$maxz) =
   266 ($firstgood,$lastgood,$atbottom,$w_gap_time,$zErr,$maxz,$rms_heave_accel) =
   260 	mk_prof(\%dta,!$opt_s,$opt_F,$minb,$maxb,$opt_c,$opt_e,$opt_m);
   267 	mk_prof(\%dta,!$opt_s,$opt_F,$minb,$maxb,$opt_c,$opt_e,$opt_m);
   261 
   268 
   262 unless (($atbottom > $firstgood) && ($lastgood > $atbottom)) {
   269 unless (($atbottom > $firstgood) && ($lastgood > $atbottom)) {
   263 	if ($opt_Q) {
   270 	if ($opt_Q) {
   264 		print(STDERR "$ARGV[0]: no valid cast data found\n");
   271 		print(STDERR "$ARGV[0]: no valid cast data found\n");
   290 	}
   297 	}
   291 }
   298 }
   292 
   299 
   293 ($water_depth,$sig_wd) =									# sea bed
   300 ($water_depth,$sig_wd) =									# sea bed
   294 	find_seabed(\%dta,$atbottom,$beamCoords);
   301 	find_seabed(\%dta,$atbottom,$beamCoords);
   295 
       
   296 #======================================================================
       
   297 # Step 1a: determine alternate Z by using mean/sigma of w in gaps
       
   298 #======================================================================
       
   299 
       
   300 # This does not make much sense for w, because w is always very close
       
   301 # to zero. It might make sense for u and v, though, and it would
       
   302 # be more consistent with the way the displacement uncertainties are
       
   303 # calculated. However, the way the profiles are calculated at the
       
   304 # moment (using the last valid velocity across the gap) is probably
       
   305 # closer to the truth in most cases.
       
   306 
       
   307 #$dta{ENSEMBLE}[$firstgood]->{ALT_Z} = 0;
       
   308 #$dta{ENSEMBLE}[$firstgood]->{ALT_Z_ERR} = 0;
       
   309 #my($sumVar);
       
   310 #for ($e=$firstgood+1; $e<=$lastgood; $e++) {
       
   311 #	my($dt) = $dta{ENSEMBLE}[$e]->{UNIX_TIME} -
       
   312 #			  $dta{ENSEMBLE}[$e-1]->{UNIX_TIME};
       
   313 #	$dta{ENSEMBLE}[$e]->{ALT_Z} =
       
   314 #		$dta{ENSEMBLE}[$e-1]->{ALT_Z} +
       
   315 #		$dt * (defined($dta{ENSEMBLE}[$e-1]->{W}) ?
       
   316 #				$dta{ENSEMBLE}[$e-1]->{W} : $meanW);
       
   317 #	$sumVar += defined($dta{ENSEMBLE}[$e-1]->{W}) ?
       
   318 #				($dta{ENSEMBLE}[$e-1]->{W_ERR} * $dt)**2 : ($dt**2)*$varW;
       
   319 #	$dta{ENSEMBLE}[$e]->{ALT_Z_ERR} = sqrt($sumVar);
       
   320 #}
       
   321 
   302 
   322 #======================================================================
   303 #======================================================================
   323 # Step 2: Integrate u & v
   304 # Step 2: Integrate u & v
   324 #======================================================================
   305 #======================================================================
   325 
   306 
   531 					if defined($dta{ENSEMBLE}[$ens]->{VELOCITY}[$i][$b]);
   512 					if defined($dta{ENSEMBLE}[$ens]->{VELOCITY}[$i][$b]);
   532 			}
   513 			}
   533 	    }
   514 	    }
   534 	} else {
   515 	} else {
   535 		for (my($i)=0; $i<$dta{N_BINS}; $i++) {
   516 		for (my($i)=0; $i<$dta{N_BINS}; $i++) {
       
   517 			next unless defined($dta{ENSEMBLE}[$ens]->{VELOCITY}[$i][0]);
   536 			for (my($b)=0; $b<4; $b++) {
   518 			for (my($b)=0; $b<4; $b++) {
   537 				$good=$i,$this_worst_beam=$b,$nVels[$i][$b]++
   519 				$good=$i,$this_worst_beam=$b,$nVels[$i][$b]++
   538 					if ($dta{ENSEMBLE}[$ens]->{CORRELATION}[$i][$b] >=
   520 					if ($dta{ENSEMBLE}[$ens]->{CORRELATION}[$i][$b] >=
   539 						$dta{MIN_CORRELATION});
   521 						$dta{MIN_CORRELATION});
   540 			}
   522 			}
   674 
   656 
   675 #======================================================================
   657 #======================================================================
   676 # PRODUCE OUTPUT
   658 # PRODUCE OUTPUT
   677 #======================================================================
   659 #======================================================================
   678 
   660 
   679 printf(STDERR "Start of cast        : %s (#%5d) at %6.1fm\n",
   661 printf(STDERR "Start of cast         : %s (#%5d) at %6.1fm\n",
   680 					$dta{ENSEMBLE}[$firstgood]->{TIME},
   662 					$dta{ENSEMBLE}[$firstgood]->{TIME},
   681 					$dta{ENSEMBLE}[$firstgood]->{NUMBER},
   663 					$dta{ENSEMBLE}[$firstgood]->{NUMBER},
   682 					$dta{ENSEMBLE}[$firstgood]->{DEPTH});
   664 					$dta{ENSEMBLE}[$firstgood]->{DEPTH});
   683 printf(STDERR "Bottom of cast (zmax): %s (#%5d) at %6.1fm\n",
   665 printf(STDERR "Bottom of cast (zmax) : %s (#%5d) at %6.1fm\n",
   684 					$dta{ENSEMBLE}[$atbottom]->{TIME},
   666 					$dta{ENSEMBLE}[$atbottom]->{TIME},
   685 					$dta{ENSEMBLE}[$atbottom]->{NUMBER},
   667 					$dta{ENSEMBLE}[$atbottom]->{NUMBER},
   686 					$dta{ENSEMBLE}[$atbottom]->{DEPTH});
   668 					$dta{ENSEMBLE}[$atbottom]->{DEPTH});
   687 if (defined($water_depth)) {
   669 if (defined($water_depth)) {
   688 	printf(STDERR "Seabed               :                      at %6.1fm (+-%dm)\n",$water_depth,$sig_wd);
   670 	printf(STDERR "Seabed                :                      at %6.1fm (+-%dm)\n",$water_depth,$sig_wd);
   689 } else {
   671 } else {
   690 	print(STDERR "Seabed               : not found\n");
   672 	print(STDERR "Seabed                : not found\n");
   691 }
   673 }
   692 printf(STDERR "End of cast (zend)   : %s (#%5d) at %6.1fm\n",
   674 printf(STDERR "End of cast (zend)    : %s (#%5d) at %6.1fm\n",
   693 					$dta{ENSEMBLE}[$lastgood]->{TIME},
   675 					$dta{ENSEMBLE}[$lastgood]->{TIME},
   694 					$dta{ENSEMBLE}[$lastgood]->{NUMBER},
   676 					$dta{ENSEMBLE}[$lastgood]->{NUMBER},
   695 					$dta{ENSEMBLE}[$lastgood]->{DEPTH});
   677 					$dta{ENSEMBLE}[$lastgood]->{DEPTH});
   696 
   678 
   697 printf(STDERR "Rel. Displacement    : x = %d(%d)m / y = %d(%d)m\n",
   679 printf(STDERR "Rel. Displacement     : x = %d(%d)m / y = %d(%d)m\n",
   698 					$dta{ENSEMBLE}[$lastgood]->{X}, $x_err, 
   680 					$dta{ENSEMBLE}[$lastgood]->{X}, $x_err, 
   699 					$dta{ENSEMBLE}[$lastgood]->{Y}, $y_err, 
   681 					$dta{ENSEMBLE}[$lastgood]->{Y}, $y_err, 
   700 				) if defined($opt_M);
   682 				) if defined($opt_M);
   701 
   683 
   702 printf(STDERR "Cast Duration        : %.1f hours (pinging for %.1f hours)\n",
   684 printf(STDERR "Cast Duration         : %.1f hours (pinging for %.1f hours)\n",
   703 					$dta{ENSEMBLE}[$lastgood]->{ELAPSED_TIME} / 3600,
   685 					$dta{ENSEMBLE}[$lastgood]->{ELAPSED_TIME} / 3600,
   704 					($dta{ENSEMBLE}[$#{$dta{ENSEMBLE}}]->{UNIX_TIME} -
   686 					($dta{ENSEMBLE}[$#{$dta{ENSEMBLE}}]->{UNIX_TIME} -
   705 						$dta{ENSEMBLE}[0]->{UNIX_TIME}) / 3600);
   687 						$dta{ENSEMBLE}[0]->{UNIX_TIME}) / 3600);
   706 
   688 
   707 printf(STDERR "Minimum range        : %dm at ensemble %d, beam %d\n",
   689 printf(STDERR "Minimum range         : %dm at ensemble %d, beam %d\n",
   708 				$dta{DISTANCE_TO_BIN1_CENTER} +
   690 				$dta{DISTANCE_TO_BIN1_CENTER} +
   709 					$min_good_bins*$dta{BIN_LENGTH},
   691 					$min_good_bins*$dta{BIN_LENGTH},
   710 				$dta{ENSEMBLE}[$min_good_ens]->{NUMBER},
   692 				$dta{ENSEMBLE}[$min_good_ens]->{NUMBER},
   711 				$worst_beam);
   693 				$worst_beam);
   712 printf(STDERR "80%%-valid bins       : %.1f\n",$gb+1);
   694 printf(STDERR "80%%-valid bins        : %.1f\n",$gb+1);
   713 printf(STDERR "80%%-valid range      : %dm\n",
   695 printf(STDERR "80%%-valid range       : %dm\n",
   714 				$dta{DISTANCE_TO_BIN1_CENTER} + $gb*$dta{BIN_LENGTH});
   696 				$dta{DISTANCE_TO_BIN1_CENTER} + $gb*$dta{BIN_LENGTH});
   715 printf(STDERR "3-beam solutions     : $RDI_Coords::threeBeam_1 " .
   697 printf(STDERR "3-beam solutions      : $RDI_Coords::threeBeam_1 " .
   716 								 	 "$RDI_Coords::threeBeam_2 " .
   698 								 	 "$RDI_Coords::threeBeam_2 " .
   717 								 	 "$RDI_Coords::threeBeam_3 " .
   699 								 	 "$RDI_Coords::threeBeam_3 " .
   718                                  	 "$RDI_Coords::threeBeam_4\n")
   700                                  	 "$RDI_Coords::threeBeam_4\n")
   719 	unless ($opt_4);
   701 	unless ($opt_4);
   720 printf(STDERR "net rotations        : [%d]/%d/%d/[%d]\n",$prerot,$dnrot,$uprot,$postrot);
   702 printf(STDERR "net rotations         : [%d]/%d/%d/[%d]\n",$prerot,$dnrot,$uprot,$postrot);
   721 printf(STDERR "rms pitch/roll       : %.1f/%.1f\n",$dnprrms,$upprrms);
   703 printf(STDERR "rms pitch/roll        : %.1fdeg/%.1fdeg\n",$dnprrms,$upprrms);
       
   704 printf(STDERR "rms heave acceleration: %.2fm/s^2\n",$rms_heave_accel);
   722 
   705 
   723 exit(0) if ($opt_Q);
   706 exit(0) if ($opt_Q);
   724 
   707 
   725 #----------------------------------------------------------------------
   708 #----------------------------------------------------------------------
   726 # output profile in active ANTS format
   709 # output profile in active ANTS format
   759 			 "rms_rotation{%.2f} " .
   742 			 "rms_rotation{%.2f} " .
   760 	 "deployment_rotations{%d} " .
   743 	 "deployment_rotations{%d} " .
   761 	   "downcast_rotations{%d} " .
   744 	   "downcast_rotations{%d} " .
   762 		 "upcast_rotations{%d} " .
   745 		 "upcast_rotations{%d} " .
   763 	   "recovery_rotations{%d} " .
   746 	   "recovery_rotations{%d} " .
       
   747    "rms_heave_acceleration{%.2f} " .
   764 				"bin1_dist{%.1f} " .
   748 				"bin1_dist{%.1f} " .
   765 			   "bin_length{%.1f} " .
   749 			   "bin_length{%.1f} " .
   766 					 "\n",
   750 					 "\n",
   767 			($dta{ENSEMBLE}[$#{$dta{ENSEMBLE}}]->{UNIX_TIME} -
   751 			($dta{ENSEMBLE}[$#{$dta{ENSEMBLE}}]->{UNIX_TIME} -
   768 					$dta{ENSEMBLE}[0]->{UNIX_TIME}),
   752 					$dta{ENSEMBLE}[0]->{UNIX_TIME}),
   774 				$dta{ENSEMBLE}[$firstgood]->{DEPTH},
   758 				$dta{ENSEMBLE}[$firstgood]->{DEPTH},
   775 			$dta{DISTANCE_TO_BIN1_CENTER} +
   759 			$dta{DISTANCE_TO_BIN1_CENTER} +
   776 				$min_good_bins*$dta{BIN_LENGTH},
   760 				$min_good_bins*$dta{BIN_LENGTH},
   777 			scalar(@{$dta{ENSEMBLE}}),
   761 			scalar(@{$dta{ENSEMBLE}}),
   778 			$w_gap_time,$wErr,$prrms,$dnprrms,$upprrms,$rotrms,
   762 			$w_gap_time,$wErr,$prrms,$dnprrms,$upprrms,$rotrms,
   779 			$prerot,$dnrot,$uprot,$postrot,
   763 			$prerot,$dnrot,$uprot,$postrot,$rms_heave_accel,
   780 			$dta{DISTANCE_TO_BIN1_CENTER},
   764 			$dta{DISTANCE_TO_BIN1_CENTER},
   781 			$dta{BIN_LENGTH},
   765 			$dta{BIN_LENGTH},
   782 	  );
   766 	  );
   783 printf("#ANTS#PARAMS# magnetic_declination{$opt_M} " .
   767 printf("#ANTS#PARAMS# magnetic_declination{$opt_M} " .
   784 							  "uv_gap_time{%d} " .
   768 							  "uv_gap_time{%d} " .