LADCP_w_ocean
changeset 49 5006e9158207
parent 48 d9309804b6cf
child 51 0f6d9e64cc4f
equal deleted inserted replaced
48:d9309804b6cf 49:5006e9158207
     1 #!/usr/bin/perl
     1 #!/usr/bin/perl
     2 #======================================================================
     2 #======================================================================
     3 #                    L A D C P _ W _ O C E A N 
     3 #                    L A D C P _ W _ O C E A N 
     4 #                    doc: Fri Dec 17 18:11:13 2010
     4 #                    doc: Fri Dec 17 18:11:13 2010
     5 #                    dlm: Mon Mar  6 13:46:31 2017
     5 #                    dlm: Tue Nov 27 14:04:39 2018
     6 #                    (c) 2010 A.M. Thurnherr
     6 #                    (c) 2010 A.M. Thurnherr
     7 #                    uE-Info: 280 0 NIL 0 0 72 0 2 4 NIL ofnI
     7 #                    uE-Info: 282 15 NIL 0 0 72 2 2 4 NIL ofnI
     8 #======================================================================
     8 #======================================================================
     9 
     9 
    10 # TODO:
    10 # TODO:
    11 #   ! use instrument tilt in sidelobe editing
    11 #   ! use instrument tilt in sidelobe editing
    12 #	- use instrument tilt in e.g. calculation of Sv
    12 #	- use instrument tilt in e.g. calculation of Sv
   275 #	Jul 31, 2016: - BUG: -d did not work because it was handled in [defaults.pl]
   275 #	Jul 31, 2016: - BUG: -d did not work because it was handled in [defaults.pl]
   276 #	Oct 16, 2016: - cosmetics
   276 #	Oct 16, 2016: - cosmetics
   277 #	Dec 22, 2016: - moved $opt_p to [defaults.pl]
   277 #	Dec 22, 2016: - moved $opt_p to [defaults.pl]
   278 #	Dec 23, 2016: - BUG: -u did not set required variables to proceed
   278 #	Dec 23, 2016: - BUG: -u did not set required variables to proceed
   279 #	Mar  6, 2017: - BUG: division by zero when water-depth ~ max(CTD_depth)
   279 #	Mar  6, 2017: - BUG: division by zero when water-depth ~ max(CTD_depth)
       
   280 #	Oct 12, 2017: - BUG: beampair w did not work for earth-coord vels; major re-write
       
   281 #						 of earthcoord code to unify processing
       
   282 #	Nov 26, 2017: - BUG: $bad_beam did not work correctly with bin interpolation
       
   283 #				  - BUG: ping-coherent residual removal did not respect missing values
       
   284 #	Nov 28, 2017: - added $initial_time_lag
       
   285 #				  - expanded semantics of -q to disable time-lagging and residual filters
       
   286 #	Dec  9, 2017: - added $antsSuppressCommonOptions = 1;
       
   287 #	Dec 17, 2017: - added dependencies
       
   288 #	Apr 24, 2018: - added support for $water_depth_db_cmd
       
   289 #	May  1, 2018: - added threshold for reference-layer horizontal speed
       
   290 #				  - added ambiguity velocity check
       
   291 #	May  2, 2018: - BUG: ref-lr threshold did not work
       
   292 #				  - BUG: BT code was called for UL when -h was used
       
   293 #				  - replaced $PPI_seabed_editing_required by &PPI_seabed_editing_required
       
   294 #				  - BUG: surface PPI editing code could not be enabled; added &PPI_surface_editing_required
       
   295 #	Nov  2, 2018: - BUG: for 3-beam solutions, residual{12,34} with affected beam was wrong
   280 # HISTORY END
   296 # HISTORY END
   281 
   297 
   282 # CTD REQUIREMENTS
   298 # CTD REQUIREMENTS
   283 #	- elapsed		elapsed seconds; see note below
   299 #	- elapsed		elapsed seconds; see note below
   284 #	- depth
   300 #	- depth
   369 #------
   385 #------
   370 
   386 
   371 require "$WCALC/defaults.pl";												# load default/option parameters
   387 require "$WCALC/defaults.pl";												# load default/option parameters
   372 
   388 
   373 $antsParseHeader = 0;
   389 $antsParseHeader = 0;
       
   390 $antsSuppressCommonOptions = 1;
   374 &antsUsage('3:4a:b:c:de:g:h:i:k:lm:n:o:p:qr:s:t:uv:Vw:x:',0,
   391 &antsUsage('3:4a:b:c:de:g:h:i:k:lm:n:o:p:qr:s:t:uv:Vw:x:',0,
   375 	"[print software -V)ersion] [-v)erbosity <level[$opt_v]>]",
   392 	"[print software -V)ersion] [-v)erbosity <level[$opt_v]>]",
   376 	"[-q)uick (no single-ping denoising)]",
       
   377     "[require -4)-beam solutions] [-d)isable bin interpolation] [apply beamvel-m)ask <file> if it exists]",
   393     "[require -4)-beam solutions] [-d)isable bin interpolation] [apply beamvel-m)ask <file> if it exists]",
   378 	"[valid LADCP -b)ins <bin,bin[$opt_b]>",
   394 	"[valid LADCP -b)ins <bin,bin[$opt_b]>",
   379 	"[-c)orrelation <min[$opt_c counts]>] [-t)ilt <max[$opt_t deg]> [-e)rr-vel <max[$opt_e m/s]>]",
   395 	"[-c)orrelation <min[$opt_c counts]>] [-t)ilt <max[$opt_t deg]> [-e)rr-vel <max[$opt_e m/s]>]",
   380 	"[-r)esidual <rms.max[,delta.max][$opt_r m/s]>]",
   396 	"[max -r)esidual <rms.max[,delta.max][$opt_r m/s]>]",
   381 	"[-h water <depth|filename>]",
   397 	"[-h water <depth|filename>]",
   382 	"[max LADCP time-series -g)ap <length[$opt_g s]>]",
   398 	"[max LADCP time-series -g)ap <length[$opt_g s]>]",
   383 	"[-i)nitial CTD time offset <guestimate> [-u)se as final]]",
   399 	"[-i)nitial CTD time offset <guestimate> [-u)se as final]]",
   384 	"[calculate -n) <lags,lags[$opt_n]>] [lag -w)indow <sz,sz[$opt_w s]>] [lag-p)iece <CTD_elapsed_min|+[,...]>]",
   400 	"[calculate -n) <lags,lags[$opt_n]>] [lag -w)indow <sz,sz[$opt_w s]>] [lag-p)iece <CTD_elapsed_min|+[,...]>]",
   385 	"[require top-3) lags to account for <frac[$opt_3]> of all]",
   401 	"[require top-3) lags to account for <frac[$opt_3]> of all]",
   386 	"[disable time-l)ag filtering]",
   402 	"[disable time-l)ag filtering]",
   387 	"[pressure-sensor -a)cceleration-derivative correction <residual/CTD_w_tt>]",
   403 	"[pressure-sensor -a)cceleration-derivative correction <residual/CTD_w_tt>]",
   388 	"[-o)utput bin <resolution[$opt_o m]>] [-k) require <min[$opt_k]> samples]",
   404 	"[-o)utput bin <resolution[$opt_o m]>] [-k) require <min[$opt_k]> samples]",
   389 	"[e-x)ecute <perl-expr>]",
   405 	"[e-x)ecute <perl-expr>]",
       
   406 	"[-q)uick-and-dirty (no single-ping denoising, residual and time-lagging filters)]",
   390 	"<profile-id> [run-label]");
   407 	"<profile-id> [run-label]");
   391 
   408 
   392 if ($opt_V) {
   409 if ($opt_V) {
   393 	printf(STDERR "+-------------------------+\n");
   410 	printf(STDERR "+------------------------------+\n");
   394 	printf(STDERR "| LADCP_w Software V%s	|\n",$VERSION);
   411 	printf(STDERR "| LADCP_w Software V%s        |\n",$VERSION);
   395 	printf(STDERR "|(c) 2015- A.M. Thurnherr |\n");
   412 	printf(STDERR "| (c) 2015-2017 A.M. Thurnherr |\n");
   396 	printf(STDERR "+-------------------------+\n");
   413 	printf(STDERR "+------------------------------+\n");
   397 	exit(0);
   414 	exit(0);
   398 }
   415 }
   399 
   416 
   400 &antsUsageError() if ($opt_u && !defined($opt_i));
   417 &antsUsageError() if ($opt_u && !defined($opt_i));
   401 &antsUsageError() unless (@ARGV==1 || @ARGV==2);
   418 &antsUsageError() unless (@ARGV==1 || @ARGV==2);
   431 	croak("$processing_param_file: $!\n");
   448 	croak("$processing_param_file: $!\n");
   432 }
   449 }
   433 require "$WCALC/default_output.pl";										# set default output plots and files
   450 require "$WCALC/default_output.pl";										# set default output plots and files
   434 
   451 
   435 $processing_options = "-k $opt_k -o $opt_o -c $opt_c -t $opt_t -e $opt_e -g $opt_g -3 $opt_3";
   452 $processing_options = "-k $opt_k -o $opt_o -c $opt_c -t $opt_t -e $opt_e -g $opt_g -3 $opt_3";
   436 $processing_options .= " -i $opt_i" if defined($opt_i);
       
   437 $processing_options .= ' -l' if defined($opt_l);
   453 $processing_options .= ' -l' if defined($opt_l);
   438 $processing_options .= ' -q' if defined($opt_q);
   454 
       
   455 if (defined($opt_q)) {													# quick-and-dirty
       
   456 	$processing_options .= ' -q';
       
   457 	$opt_l = 1;															# disable time-lagging filter
       
   458 }
       
   459 
       
   460 if (defined($opt_i)) {													# set initial time lag
       
   461 	$processing_options .= " -i $opt_i";
       
   462 	$initial_time_lag = &antsFloatOpt($opt_i);
       
   463 }
   439 
   464 
   440 if (defined($opt_x)) {													# eval cmd-line expression to override anything
   465 if (defined($opt_x)) {													# eval cmd-line expression to override anything
   441 	$processing_options .= " -x $opt_x";
   466 	$processing_options .= " -x $opt_x";
   442 	eval($opt_x);
   467 	eval($opt_x);
   443 }
   468 }
   445 if ($opt_4) {															# disallow 3-beam solutions
   470 if ($opt_4) {															# disallow 3-beam solutions
   446 	$processing_options .= " -4";
   471 	$processing_options .= " -4";
   447 	$RDI_Coords::minValidVels = 4;
   472 	$RDI_Coords::minValidVels = 4;
   448 }
   473 }
   449 
   474 
   450 if ($opt_d) {
   475 if ($opt_d) {															# disable bin mapping
   451 	$processing_options .= ' -d';
   476 	$processing_options .= ' -d';
   452 	$RDI_Coords::binMapping = 'none';
   477 	$RDI_Coords::binMapping = 'none';
   453 }
   478 }
   454 	
   479 	
   455 if (defined($opt_r)) {													# residuals filters
   480 if (defined($opt_r)) {													# residuals filters
   476 		unless numberp($length_of_timelag_windows[0]) && numberp($length_of_timelag_windows[1]);
   501 		unless numberp($length_of_timelag_windows[0]) && numberp($length_of_timelag_windows[1]);
   477 $processing_options .= " -w $opt_w";
   502 $processing_options .= " -w $opt_w";
   478 
   503 
   479 croak("$0: \$out_basename undefined\n")									# plotting routines use this to label the plots
   504 croak("$0: \$out_basename undefined\n")									# plotting routines use this to label the plots
   480 	unless defined($out_basename);
   505 	unless defined($out_basename);
   481 &antsAddParams('RDI_Coords::binMapping',$RDI_Coords::binMapping);
   506 #&antsAddParams('RDI_Coords::binMapping',$RDI_Coords::binMapping);		# must be set below since binmapping depends on coords
   482 &antsAddParams('processing_options',$processing_options);
   507 &antsAddParams('processing_options',$processing_options);
   483 &antsAddParams('out_basename',$out_basename);
   508 &antsAddParams('out_basename',$out_basename);
   484 &antsAddParams('profile_id',$PROF,'run_label',$RUN);
   509 &antsAddParams('profile_id',$PROF,'run_label',$RUN);
   485 
   510 
   486 #----------------------------------------------------------------------
   511 #----------------------------------------------------------------------
   549 #	- low transmit power
   574 #	- low transmit power
   550 #---------------------------
   575 #---------------------------
   551 
   576 
   552 progress("Reading LADCP data from <$LADCP_file>...\n");
   577 progress("Reading LADCP data from <$LADCP_file>...\n");
   553 readData($LADCP_file,\%LADCP);
   578 readData($LADCP_file,\%LADCP);
       
   579 &antsAddDeps($LADCP_file);
   554 if ($LADCP{BEAM_COORDINATES}) {
   580 if ($LADCP{BEAM_COORDINATES}) {
   555 	progress("\t%d ensembles (beam coordinates)\n",scalar(@{$LADCP{ENSEMBLE}}));
   581 	progress("\t%d ensembles (beam coordinates)\n",scalar(@{$LADCP{ENSEMBLE}}));
   556 } else {
   582 } else {
   557 	progress("\t%d ensembles (Earth coordinates)\n",scalar(@{$LADCP{ENSEMBLE}}));
   583 	progress("\t%d ensembles (Earth coordinates)\n",scalar(@{$LADCP{ENSEMBLE}}));
   558 }
   584 }
   559 
   585 
       
   586 if ($valid_ensemble_range[0] > 0) {					# remove leading invalid records
       
   587 	my($ens) = 0;
       
   588 	while ($ens < @{$LADCP{ENSEMBLE}} && $LADCP{ENSEMBLE}[$ens]->{NUMBER}<$valid_ensemble_range[0]) { $ens++ }
       
   589 	splice(@{$LADCP{ENSEMBLE}},0,$ens);
       
   590 	progress("\t%d invalid leading ensembles removed\n",$ens)
       
   591 }
       
   592 if ($valid_ensemble_range[1] > 0) {					# remove trailing invalid records
       
   593 	my($ens) = 0;
       
   594 	while ($ens < @{$LADCP{ENSEMBLE}} && $LADCP{ENSEMBLE}[$ens]->{NUMBER}<$valid_ensemble_range[1]) { $ens++ }
       
   595 	splice(@{$LADCP{ENSEMBLE}},$ens);
       
   596 	progress("\t%d invalid trailing ensembles removed\n",@{$LADCP{ENSEMBLE}}-$ens)
       
   597 }
       
   598 			   
   560 error("$LADCP_file: cannot process multi-ping ensembles\n")
   599 error("$LADCP_file: cannot process multi-ping ensembles\n")
   561 	unless ($LADCP{PINGS_PER_ENSEMBLE} == 1);
   600 	unless ($LADCP{PINGS_PER_ENSEMBLE} == 1);
   562 warning(2,"$LADCP_file: wide-bandwidth setting\n")
   601 warning(2,"$LADCP_file: wide-bandwidth setting\n")
   563 	if ($LADCP{WIDE_BANDWIDTH});
   602 	if ($LADCP{WIDE_BANDWIDTH});
   564 warning(2,"$LADCP_file: low transmit-power setting\n")
   603 warning(2,"$LADCP_file: low transmit-power setting\n")
   596 &antsAddParams('ADCP_bin_length',$LADCP{BIN_LENGTH},
   635 &antsAddParams('ADCP_bin_length',$LADCP{BIN_LENGTH},
   597 			   'ADCP_pulse_length',$LADCP{TRANSMITTED_PULSE_LENGTH},
   636 			   'ADCP_pulse_length',$LADCP{TRANSMITTED_PULSE_LENGTH},
   598 			   'ADCP_frequency',$LADCP{BEAM_FREQUENCY},
   637 			   'ADCP_frequency',$LADCP{BEAM_FREQUENCY},
   599 			   'ADCP_blanking_distance',$LADCP{BLANKING_DISTANCE});
   638 			   'ADCP_blanking_distance',$LADCP{BLANKING_DISTANCE});
   600 
   639 
       
   640 
   601 #------------------------------------------------------------
   641 #------------------------------------------------------------
   602 # Edit beam-velocity data
   642 # Edit velocity data
   603 #	0) beam-vel mask on -m
   643 #	beam coords:
   604 #		mask file has three columns: from_ens to_ens ignore_beam
   644 #		1) beam-vel mask on -m
   605 #	1) correlation threshold
   645 #		   mask file has three columns: from_ens to_ens ignore_beam
       
   646 #		2) correlation threshold
       
   647 #	Earth coords:
       
   648 #		1) correlation threshold
   606 #------------------------------------------------------------
   649 #------------------------------------------------------------
   607 
   650 
   608 if ($LADCP{BEAM_COORDINATES}) {
   651 if ($LADCP{BEAM_COORDINATES}) {
   609 	progress("Editing beam-velocity data...\n");
   652 	progress("Editing beam-velocity data...\n");
   610 	
   653 	
   661 	}
   704 	}
   662 	error("$LADCP_file: no valid data\n") unless ($nvv > 0);
   705 	error("$LADCP_file: no valid data\n") unless ($nvv > 0);
   663 	progress("\tcorrelation threshold (-c %d counts): %d velocites removed (%d%% of total)\n",$opt_c,$cte,round(100*$cte/$nvv));
   706 	progress("\tcorrelation threshold (-c %d counts): %d velocites removed (%d%% of total)\n",$opt_c,$cte,round(100*$cte/$nvv));
   664 }
   707 }
   665 
   708 
       
   709 #------------------------------------------------------------
       
   710 # Create beam coordinate velocities for Earth-velocity data
       
   711 #	- velocities are replaced "in place"
       
   712 #	- BT velocities are treated separately in [find_seabed.pl]
       
   713 #	- this transformation will remove all 3-beam solutions
       
   714 #	- disable bin mapping because Earth coords are typically bin-remapped
       
   715 #------------------------------------------------------------
       
   716 
       
   717 unless ($LADCP{BEAM_COORDINATES}) {
       
   718 	progress("Replacing earth- with beam-velocities...\n");
       
   719 	for ($ens=0; $ens<=$#{$LADCP{ENSEMBLE}}; $ens++) {
       
   720 		for (my($bin)=$LADCP_firstBin-1; $bin<=$LADCP_lastBin-1; $bin++) {
       
   721 			@{$LADCP{ENSEMBLE}[$ens]->{VELOCITY}[$bin]} = 
       
   722 				&velEarthToBeam(\%LADCP,$ens,@{$LADCP{ENSEMBLE}[$ens]->{VELOCITY}[$bin]});
       
   723         }
       
   724     }
       
   725 	$RDI_Coords::binMapping = 'none';
       
   726 }
       
   727 
       
   728 &antsAddParams('RDI_Coords::binMapping',$RDI_Coords::binMapping);		# finally, bin mapping is known
       
   729 
   666 #-------------------------------------------------------------------
   730 #-------------------------------------------------------------------
   667 # Calculate earth velocities
   731 # Calculate earth velocities
   668 #	- this is done for all bins (not just valid ones), to allow
   732 #	- this is done for all bins (not just valid ones), to allow
   669 #	  useless possibility that invalid bins are used for reflr calcs
   733 #	  useless possibility that invalid bins are used for reflr calcs
   670 #	- also calculate separate beam-pair velocities
   734 #	- also calculate separate beam-pair velocities
   671 #	- the UNEDITED velocities are saved for the BT calculations
   735 #	- the UNEDITED velocities are saved for the BT calculations
   672 #	  (W is required, U & V are only used for stats that have not
   736 #	  (W is required, U & V are only used for stats that have not
   673 #	  been very useful so far)
   737 #	  been very useful so far)
   674 #-------------------------------------------------------------------
   738 #-------------------------------------------------------------------
   675 
   739 
   676 if ($LADCP{BEAM_COORDINATES}) {
   740 my($dummy);
   677 	my($dummy);
   741 progress("Calculating earth-coordinate velocities...\n");
   678 	progress("Calculating earth-coordinate velocities...\n");
   742 if ($bad_beam) {
       
   743 	progress("\tdiscarding velocities from beam $bad_beam\n");
       
   744 	&antsAddParams('bad_beam_discarded',$bad_beam);
       
   745 }
       
   746 $nvw = 0;
       
   747 for ($ens=0; $ens<=$#{$LADCP{ENSEMBLE}}; $ens++) {
       
   748 	$LADCP{ENSEMBLE}[$ens]->{GIMBAL_PITCH} =
       
   749 		gimbal_pitch($LADCP{ENSEMBLE}[$ens]->{PITCH},$LADCP{ENSEMBLE}[$ens]->{ROLL});
       
   750 
   679 	if ($bad_beam) {
   751 	if ($bad_beam) {
   680 		progress("\tdiscarding velocities from beam $bad_beam\n");
   752 		for (my($bin)=0; $bin<=$LADCP{N_BINS}-1; $bin++) {
   681 		&antsAddParams('bad_beam_discarded',$bad_beam);
   753 			undef($LADCP{ENSEMBLE}[$ens]->{VELOCITY}[$bin][$bad_beam-1]);
   682 	}
   754 			undef($LADCP{ENSEMBLE}[$ens]->{BT_VELOCITY}[$bin][$bad_beam-1]);
   683 	$nvw = 0;
   755 		}
   684 	for ($ens=0; $ens<=$#{$LADCP{ENSEMBLE}}; $ens++) {
   756     }
   685 		$LADCP{ENSEMBLE}[$ens]->{GIMBAL_PITCH} =
   757 
   686 		 	gimbal_pitch($LADCP{ENSEMBLE}[$ens]->{PITCH},$LADCP{ENSEMBLE}[$ens]->{ROLL});
   758 	for (my($bin)=$LADCP_firstBin-1; $bin<=$LADCP_lastBin-1; $bin++) {
   687 
   759 		($LADCP{ENSEMBLE}[$ens]->{INTERP_U}[$bin],
   688 		for (my($bin)=$LADCP_firstBin-1; $bin<=$LADCP_lastBin-1; $bin++) {
   760 		 $LADCP{ENSEMBLE}[$ens]->{INTERP_V}[$bin],
   689 			if ($bad_beam) {
   761 		 $LADCP{ENSEMBLE}[$ens]->{INTERP_W}[$bin],
   690 				undef($LADCP{ENSEMBLE}[$ens]->{VELOCITY}[$bin][$bad_beam-1]);
   762 		 $LADCP{ENSEMBLE}[$ens]->{INTERP_ERRVEL}[$bin]) = earthVels(\%LADCP,$ens,$bin);
   691 				undef($LADCP{ENSEMBLE}[$ens]->{BT_VELOCITY}[$bin][$bad_beam-1]);
   763 		($LADCP{ENSEMBLE}[$ens]->{V12}[$bin],$LADCP{ENSEMBLE}[$ens]->{W12}[$bin],
   692 			}
   764 		 $LADCP{ENSEMBLE}[$ens]->{V34}[$bin],$LADCP{ENSEMBLE}[$ens]->{W34}[$bin]) = BPEarthVels(\%LADCP,$ens,$bin);
   693 			($LADCP{ENSEMBLE}[$ens]->{INTERP_U}[$bin],
   765 	}
   694 			 $LADCP{ENSEMBLE}[$ens]->{INTERP_V}[$bin],
   766 
   695 			 $LADCP{ENSEMBLE}[$ens]->{INTERP_W}[$bin],
   767 	for (my($bin)=$LADCP_firstBin-1; $bin<=$LADCP_lastBin-1; $bin++) {
   696 			 $LADCP{ENSEMBLE}[$ens]->{INTERP_ERRVEL}[$bin]) = earthVels(\%LADCP,$ens,$bin);
   768 		$LADCP{ENSEMBLE}[$ens]->{U}[$bin] = $LADCP{ENSEMBLE}[$ens]->{INTERP_U}[$bin];
   697 			($LADCP{ENSEMBLE}[$ens]->{V12}[$bin],$LADCP{ENSEMBLE}[$ens]->{W12}[$bin],
   769 		$LADCP{ENSEMBLE}[$ens]->{V}[$bin] = $LADCP{ENSEMBLE}[$ens]->{INTERP_V}[$bin];
   698 			 $LADCP{ENSEMBLE}[$ens]->{V34}[$bin],$LADCP{ENSEMBLE}[$ens]->{W34}[$bin]) = BPEarthVels(\%LADCP,$ens,$bin);
   770 		$LADCP{ENSEMBLE}[$ens]->{W}[$bin] = $LADCP{ENSEMBLE}[$ens]->{INTERP_W}[$bin];
   699 		}
   771 		$LADCP{ENSEMBLE}[$ens]->{ERRVEL}[$bin] = $LADCP{ENSEMBLE}[$ens]->{INTERP_ERRVEL}[$bin];
   700 
   772 		undef($LADCP{ENSEMBLE}[$ens]->{INTERP_U}[$bin]);
   701 		for (my($bin)=$LADCP_firstBin-1; $bin<=$LADCP_lastBin-1; $bin++) {
   773 		undef($LADCP{ENSEMBLE}[$ens]->{INTERP_V}[$bin]);
   702 			$LADCP{ENSEMBLE}[$ens]->{U}[$bin] = $LADCP{ENSEMBLE}[$ens]->{INTERP_U}[$bin];
   774 		undef($LADCP{ENSEMBLE}[$ens]->{INTERP_W}[$bin]);
   703 			$LADCP{ENSEMBLE}[$ens]->{V}[$bin] = $LADCP{ENSEMBLE}[$ens]->{INTERP_V}[$bin];
   775 		undef($LADCP{ENSEMBLE}[$ens]->{INTERP_ERRVEL}[$bin]);
   704 			$LADCP{ENSEMBLE}[$ens]->{W}[$bin] = $LADCP{ENSEMBLE}[$ens]->{INTERP_W}[$bin];
   776 
   705 			$LADCP{ENSEMBLE}[$ens]->{ERRVEL}[$bin] = $LADCP{ENSEMBLE}[$ens]->{INTERP_ERRVEL}[$bin];
   777 		if (defined($LADCP{ENSEMBLE}[$ens]->{W}[$bin])) {
   706 			undef($LADCP{ENSEMBLE}[$ens]->{INTERP_U}[$bin]);
   778 			$per_bin_nsamp[$bin]++;
   707 			undef($LADCP{ENSEMBLE}[$ens]->{INTERP_V}[$bin]);
   779 			$nvw++;
   708 			undef($LADCP{ENSEMBLE}[$ens]->{INTERP_W}[$bin]);
   780 		}
   709 			undef($LADCP{ENSEMBLE}[$ens]->{INTERP_ERRVEL}[$bin]);
   781     
   710 
   782 		$LADCP{ENSEMBLE}[$ens]->{U_UNEDITED}[$bin] = $LADCP{ENSEMBLE}[$ens]->{U}[$bin];
   711 			if (defined($LADCP{ENSEMBLE}[$ens]->{W}[$bin])) {
   783 		$LADCP{ENSEMBLE}[$ens]->{V_UNEDITED}[$bin] = $LADCP{ENSEMBLE}[$ens]->{V}[$bin];
   712 				$per_bin_nsamp[$bin]++;
   784 		$LADCP{ENSEMBLE}[$ens]->{W_UNEDITED}[$bin] = $LADCP{ENSEMBLE}[$ens]->{W}[$bin];
   713 				$nvw++;
   785 	}
   714 			}
   786 }
   715 		
   787 progress("\t$nvw valid velocities in bins $LADCP_firstBin-$LADCP_lastBin\n");
   716 			$LADCP{ENSEMBLE}[$ens]->{U_UNEDITED}[$bin] = $LADCP{ENSEMBLE}[$ens]->{U}[$bin];
   788 progress("\t3-beam solutions : $RDI_Coords::threeBeam_1 " .
   717 			$LADCP{ENSEMBLE}[$ens]->{V_UNEDITED}[$bin] = $LADCP{ENSEMBLE}[$ens]->{V}[$bin];
   789 							  "$RDI_Coords::threeBeam_2 " .
   718 			$LADCP{ENSEMBLE}[$ens]->{W_UNEDITED}[$bin] = $LADCP{ENSEMBLE}[$ens]->{W}[$bin];
   790 							  "$RDI_Coords::threeBeam_3 " .
   719 		}
   791 							  "$RDI_Coords::threeBeam_4\n")
   720 	}
   792     unless ($opt_4);
   721 	progress("\t$nvw valid velocities in bins $LADCP_firstBin-$LADCP_lastBin\n");
       
   722 	progress("\t3-beam solutions : $RDI_Coords::threeBeam_1 " .
       
   723 								  "$RDI_Coords::threeBeam_2 " .
       
   724 								  "$RDI_Coords::threeBeam_3 " .
       
   725 								  "$RDI_Coords::threeBeam_4\n")
       
   726 	    unless ($opt_4);
       
   727 } else { # Earth Coordinates
       
   728 	progress("Counting valid vertical velocities...\n");
       
   729 	$nvw = 0;
       
   730 	for ($ens=0; $ens<=$#{$LADCP{ENSEMBLE}}; $ens++) {
       
   731 		$LADCP{ENSEMBLE}[$ens]->{GIMBAL_PITCH} =
       
   732 		 	gimbal_pitch($LADCP{ENSEMBLE}[$ens]->{PITCH},$LADCP{ENSEMBLE}[$ens]->{ROLL});
       
   733 		for (my($bin)=$LADCP_firstBin-1; $bin<=$LADCP_lastBin-1; $bin++) {
       
   734 			($LADCP{ENSEMBLE}[$ens]->{U}[$bin],
       
   735 			 $LADCP{ENSEMBLE}[$ens]->{V}[$bin],
       
   736 			 $LADCP{ENSEMBLE}[$ens]->{W}[$bin],
       
   737 			 $LADCP{ENSEMBLE}[$ens]->{ERRVEL}[$bin]) = @{$LADCP{ENSEMBLE}[$ens]->{VELOCITY}[$bin]};
       
   738 			if (defined($LADCP{ENSEMBLE}[$ens]->{W}[$bin])) {
       
   739 				$per_bin_nsamp[$bin]++;
       
   740 				$nvw++;
       
   741 			}
       
   742 			$LADCP{ENSEMBLE}[$ens]->{U_UNEDITED}[$bin] = $LADCP{ENSEMBLE}[$ens]->{U}[$bin];
       
   743 			$LADCP{ENSEMBLE}[$ens]->{V_UNEDITED}[$bin] = $LADCP{ENSEMBLE}[$ens]->{V}[$bin];
       
   744 			$LADCP{ENSEMBLE}[$ens]->{W_UNEDITED}[$bin] = $LADCP{ENSEMBLE}[$ens]->{W}[$bin];
       
   745 
       
   746 			$LADCP{ENSEMBLE}[$ens]->{V12}[$bin] = $LADCP{ENSEMBLE}[$ens]->{V34}[$bin] = nan;
       
   747 
       
   748 			# for 3-beam solutions, w12 = w34 = w (I think)
       
   749 			($LADCP{ENSEMBLE}[$ens]->{W12}[$bin],$LADCP{ENSEMBLE}[$ens]->{W34}[$bin]) =
       
   750 				velEarthToBPw($LADCP,$ens,@{$LADCP{ENSEMBLE}[$ens]->{VELOCITY}[$bin]});
       
   751 		}
       
   752 	}
       
   753 	progress("\t$nvw valid velocities in bins $LADCP_firstBin-$LADCP_lastBin\n");
       
   754 }
       
   755 
   793 
   756 error("$LADCP_file: insufficient valid velocities\n") unless ($nvw >= $min_valid_vels);
   794 error("$LADCP_file: insufficient valid velocities\n") unless ($nvw >= $min_valid_vels);
   757 
   795 
   758 #----------------------------------------------
   796 #----------------------------------------------
   759 # STEP: Edit earth-coordinate -velocity data
   797 # STEP: Edit earth-coordinate -velocity data
   854 error("deepest depth is at end of cast (no upcast data)\n")
   892 error("deepest depth is at end of cast (no upcast data)\n")
   855 	if ($lastGoodEns-$LADCP_atbottom < 100);
   893 	if ($lastGoodEns-$LADCP_atbottom < 100);
   856 
   894 
   857 #----------------------------------------------------------------------
   895 #----------------------------------------------------------------------
   858 # More editing
   896 # More editing
   859 #	- this requires ${first,last}GoodEns to be known
   897 #	- attitude threshold
       
   898 #	- data in far bins (beyond reliable range)
       
   899 #	- at this stage ${first,last}GoodEns are known
   860 #	- TILT field is set as a side-effect
   900 #	- TILT field is set as a side-effect
   861 #----------------------------------------------------------------------
   901 #----------------------------------------------------------------------
   862 
   902 
   863 progress("Editing additional earth-coordinate velocity data...\n");
   903 progress("Editing additional earth-coordinate velocity data...\n");
   864 &antsAddParams('per_bin_valid_frac_lim',$per_bin_valid_frac_lim);
   904 &antsAddParams('per_bin_valid_frac_lim',$per_bin_valid_frac_lim);
   894 progress("\tattitude threshold (max_tilt = %d deg): %d velocites removed (%d%% of total)\n",
   934 progress("\tattitude threshold (max_tilt = %d deg): %d velocites removed (%d%% of total)\n",
   895 	$opt_t,$pte,round(100*$pte/$nvv));
   935 	$opt_t,$pte,round(100*$pte/$nvv));
   896 progress("\tvelocities beyond bin $first_bad_bin (<%d%% valid values): %d velocites removed (%d%% of total in bins $LADCP_firstBin-$LADCP_lastBin)\n",
   936 progress("\tvelocities beyond bin $first_bad_bin (<%d%% valid values): %d velocites removed (%d%% of total in bins $LADCP_firstBin-$LADCP_lastBin)\n",
   897 	round(100*$per_bin_valid_frac_lim),$fprm,round(100*$fprm/$nvw));
   937 	round(100*$per_bin_valid_frac_lim),$fprm,round(100*$fprm/$nvw));
   898 
   938 
   899 #--------------
   939 #----------------------------------------------------------------------
   900 # Read CTD data
   940 # Read CTD data
   901 #--------------
   941 #----------------------------------------------------------------------
   902 
   942 
   903 progress("Reading CTD data from <$CTD_file>...\n");
   943 progress("Reading CTD data from <$CTD_file>...\n");
   904 open(STDIN,$CTD_file) || error("$CTD_file: $!\n");
   944 open(STDIN,$CTD_file) || error("$CTD_file: $!\n");
   905 error("$CTD_file: no data\n") unless (&antsIn());
   945 error("$CTD_file: no data\n") unless (&antsIn());
   906 undef($antsOldHeaders);
   946 undef($antsOldHeaders);
   907 
   947 
       
   948 &antsAddDeps($CTD_file);
   908 &antsAddParams('lat',$P{lat}) if defined($P{lat});
   949 &antsAddParams('lat',$P{lat}) if defined($P{lat});
   909 &antsAddParams('lon',$P{lon}) if defined($P{lon});
   950 &antsAddParams('lon',$P{lon}) if defined($P{lon});
   910 
   951 
   911 ($CTD_elapsed,$CTD_depth,$CTD_svel) = &fnr('elapsed','depth','ss');
   952 ($CTD_elapsed,$CTD_depth,$CTD_svel) = &fnr('elapsed','depth','ss');
   912 $CTD_w 	  		= &fnrNoErr('w_CTD');
   953 $CTD_w 	  		= &fnrNoErr('w_CTD');
   976 
  1017 
   977 #-------------------
  1018 #-------------------
   978 # Determine time lag
  1019 # Determine time lag
   979 #-------------------
  1020 #-------------------
   980 
  1021 
   981 if (defined($opt_i)) {
  1022 if (defined($initial_time_lag)) {
   982 	progress("Setting initial time lag...\n");
  1023 	progress("Setting initial time lag...\n");
   983 	$CTD{TIME_LAG} = $opt_i;
  1024 	$CTD{TIME_LAG} = $initial_time_lag;
   984 	progress("\t-i => elapsed(CTD) ~ elapsed(LADCP) + %.1fs\n",$CTD{TIME_LAG});
  1025 	progress("\t-i => elapsed(CTD) ~ elapsed(LADCP) + %.1fs\n",$CTD{TIME_LAG});
   985 } else {
  1026 } else {
   986 	progress("Guestimating time lag...\n");
  1027 	progress("Guestimating time lag...\n");
   987 	
  1028 	
   988 	my($CTD_10pct_down) = 0;
  1029 	my($CTD_10pct_down) = 0;
  1189 # Find Seabed & Edit data
  1230 # Find Seabed & Edit data
  1190 #	1) contaminated by sidelobe reflection from seabed and sea surface
  1231 #	1) contaminated by sidelobe reflection from seabed and sea surface
  1191 #	2) PPI 
  1232 #	2) PPI 
  1192 #----------------------------------------------------------------------------
  1233 #----------------------------------------------------------------------------
  1193 
  1234 
  1194 error("$0: conflicting water-depth information provided by user\n")					# this can only happen if
  1235 error("$0: conflicting water-depth information provided by user\n")					# only happens when $water_depth is set explicitly
  1195 	if defined($opt_h) && defined($water_depth);									# the user is setting $water_depth
  1236 	if defined($opt_h) && defined($water_depth);									
  1196 																					# explicitly?!
  1237 																					
  1197 if (defined($opt_h)) {																# deal with user-provided water-depth info
  1238 if (defined($opt_h)) {																# handle user-provided water-depth info
  1198 	if (numberp($opt_h)) {
  1239 	if (numberp($opt_h)) {
  1199 		$water_depth = $opt_h;
  1240 		$water_depth = $opt_h;
  1200 	} elsif (-f $opt_h) {
  1241 	} elsif (-f $opt_h) {
  1201 		open(WDF,$opt_h) || error("$opt_h: $_\n");
  1242 		open(WDF,$opt_h) || error("$opt_h: $_\n");
  1202 		$water_depth = &antsFileScanParam(WDF,'water_depth');
  1243 		$water_depth = &antsFileScanParam(WDF,'water_depth');
  1205 	} else {
  1246 	} else {
  1206 		error("$0: -h $opt_h defines neither number nor existing file\n");
  1247 		error("$0: -h $opt_h defines neither number nor existing file\n");
  1207     }
  1248     }
  1208 }
  1249 }
  1209 	
  1250 	
  1210 #die("assertion failed (water_depth = $water_depth)")
       
  1211 #	unless (!defined($water_depth) || numberp($water_depth));
       
  1212 
       
  1213 if (!defined($water_depth) &&														# find seabed in data
  1251 if (!defined($water_depth) &&														# find seabed in data
  1214 		$LADCP{ENSEMBLE}[$LADCP_atbottom]->{XDUCER_FACING_DOWN}) {
  1252 		$LADCP{ENSEMBLE}[$LADCP_atbottom]->{XDUCER_FACING_DOWN}) {
  1215 	progress("Finding seabed...\n");
  1253 	progress("Finding seabed...\n");
  1216 	($water_depth,$sig_water_depth) =
  1254 	($water_depth,$sig_water_depth) =
  1217 		find_backscatter_seabed($LADCP{ENSEMBLE}[$LADCP_atbottom]->{CTD_DEPTH});
  1255 		find_backscatter_seabed($LADCP{ENSEMBLE}[$LADCP_atbottom]->{CTD_DEPTH});
  1224 	}
  1262 	}
  1225 	if (!$SS_use_BT && !defined($water_depth) && defined($water_depth_BT)) {		# warn if use of BT was not
  1263 	if (!$SS_use_BT && !defined($water_depth) && defined($water_depth_BT)) {		# warn if use of BT was not
  1226 		warning(1,"using water_depth from ADCP BT data\n");							# explicitly requested
  1264 		warning(1,"using water_depth from ADCP BT data\n");							# explicitly requested
  1227 		$SS_use_BT = 1;
  1265 		$SS_use_BT = 1;
  1228 	}
  1266 	}
  1229 	if ($SS_use_BT) {																# water depth from BT data
  1267 	if ($SS_use_BT && numberp($water_depth_BT)) {									# water depth from BT data
  1230 		&antsAddParams('water_depth_from','BT_data');
  1268 		&antsAddParams('water_depth_from','BT_data');
  1231 		$water_depth = $water_depth_BT;
  1269 		$water_depth = $water_depth_BT;
  1232 		$sig_water_depth = $sig_water_depth_BT;
  1270 		$sig_water_depth = $sig_water_depth_BT;
  1233     } else {																		# water depth from WT data
  1271     } elsif (defined($water_depth)) {												# water depth from WT data
  1234 		&antsAddParams('water_depth_from','echo_amplitudes');
  1272 		&antsAddParams('water_depth_from','echo_amplitudes');
  1235 	}
  1273 	}
  1236 }
  1274 }
  1237 	
  1275 	
  1238 if (defined($water_depth)) {														# 1 or 2 water depths available
  1276 if (defined($water_depth)) {														# 1 or 2 water depths available
  1250 		warning(2,"water depth ($water_depth m) < max CTD depth ($CTD_maxdepth m) ignored\n");
  1288 		warning(2,"water depth ($water_depth m) < max CTD depth ($CTD_maxdepth m) ignored\n");
  1251 		undef($water_depth);
  1289 		undef($water_depth);
  1252 	}
  1290 	}
  1253 }
  1291 }
  1254 
  1292 
       
  1293 if (!defined($water_depth) && defined($water_depth_db_cmd)) {						# set water depth from data base
       
  1294 	error("$0: lat/lon required for running $water_depth_db_cmd\n")
       
  1295 		unless numbersp($P{lat},$P{lon});
       
  1296 	chomp($water_depth = `$water_depth_db_cmd $P{lon} $P{lat}`);
       
  1297 	error("$0: command '$water_depth_db_cmd $P{lon} $P{lat}' did not return valid water depth\n")
       
  1298 		unless numberp($water_depth);
       
  1299 	&antsAddParams('water_depth_from',"$water_depth_db_cmd $P{lon} $P{lat}");
       
  1300 }
       
  1301 
  1255 if (defined($water_depth)) {														# set %PARAMs
  1302 if (defined($water_depth)) {														# set %PARAMs
  1256 	&antsAddParams('water_depth',$water_depth,'water_depth.sig',$sig_water_depth);
  1303 	&antsAddParams('water_depth',$water_depth,'water_depth.sig',$sig_water_depth);
  1257 } else {
  1304 } else {
  1258 	warning(2,"unknown water depth --- cannot edit sidelobes or PPI near the seabed\n");
  1305 	warning(2,"unknown water depth --- cannot edit sidelobes or PPI near the seabed\n");
  1259 	&antsAddParams('water_depth','unknown','water_depth.sig','nan');
  1306 	&antsAddParams('water_depth','unknown','water_depth.sig','nan');
  1274 	        &antsAddParams('sidelobe_editing','surface+seabed','vessel_draft',$vessel_draft);
  1321 	        &antsAddParams('sidelobe_editing','surface+seabed','vessel_draft',$vessel_draft);
  1275 	    } else {
  1322 	    } else {
  1276 	        &antsAddParams('sidelobe_editing','seabed');
  1323 	        &antsAddParams('sidelobe_editing','seabed');
  1277 	    }
  1324 	    }
  1278 
  1325 
  1279 		$PPI_editing |= eval($PPI_seabed_editing_required);
  1326 		if (&PPI_seabed_editing_required()) {
  1280 		if ($PPI_editing) {
       
  1281 			&antsAddParams('PPI_editing','seabed');
  1327 			&antsAddParams('PPI_editing','seabed');
  1282 			&antsAddParams('PPI_extend_upper_limit',$PPI_extend_upper_limit)
  1328 			&antsAddParams('PPI_extend_upper_limit',$PPI_extend_upper_limit)
  1283 				if numberp($PPI_extend_upper_limit);
  1329 				if numberp($PPI_extend_upper_limit);
  1284 			progress("Editing data to remove PPI from seabed...\n");
  1330 			progress("Editing data to remove PPI from seabed...\n");
  1285 			progress("\tConstructing depth-average soundspeed profile...\n");
  1331 			progress("\tConstructing depth-average soundspeed profile...\n");
  1321         }
  1367         }
  1322         &antsAddParams('sidelobe_editing','surface+seabed','vessel_draft',$vessel_draft);
  1368         &antsAddParams('sidelobe_editing','surface+seabed','vessel_draft',$vessel_draft);
  1323     } else {
  1369     } else {
  1324         &antsAddParams('sidelobe_editing','surface','vessel_draft',$vessel_draft);
  1370         &antsAddParams('sidelobe_editing','surface','vessel_draft',$vessel_draft);
  1325     } 
  1371     } 
  1326 	if ($PPI_editing) {
  1372 	if (&PPI_surface_editing_required()) {
  1327 		&antsAddParams('PPI_editing','surface');
  1373 		&antsAddParams('PPI_editing','surface');
  1328 		&antsAddParams('PPI_extend_upper_limit',$PPI_extend_upper_limit)
  1374 		&antsAddParams('PPI_extend_upper_limit',$PPI_extend_upper_limit)
  1329 			if numberp($PPI_extend_upper_limit);
  1375 			if numberp($PPI_extend_upper_limit);
  1330 		progress("Editing data to remove PPI from sea surface...\n");
  1376 		progress("Editing data to remove PPI from sea surface...\n");
  1331 		  progress("\tConstructing depth-average soundspeed profile...\n");
  1377 		  progress("\tConstructing depth-average soundspeed profile...\n");
  1339 	    progress("\t$nvrm velocities from $nerm ensembles removed\n");
  1385 	    progress("\t$nvrm velocities from $nerm ensembles removed\n");
  1340 	}
  1386 	}
  1341 }
  1387 }
  1342 
  1388 
  1343 #----------------------------------------------------------------------
  1389 #----------------------------------------------------------------------
       
  1390 # Check For Ambiguity Velocity Problems
       
  1391 #----------------------------------------------------------------------
       
  1392 
       
  1393 progress("Checking for ambiguity velocity violations...\n");
       
  1394 
       
  1395 my($ambiguity_velocity) = ambiguity_velocity($LADCP{BEAM_FREQUENCY},
       
  1396 											 $LADCP{BEAM_ANGLE},
       
  1397 											 $LADCP{SPEED_OF_SOUND},
       
  1398 											 $LADCP{TRANSMIT_LAG_DISTANCE});
       
  1399 &antsAddParams('ambiguity_velocity',$ambiguity_velocity);
       
  1400 my($nbad) = 0;
       
  1401 for (my($ens)=$firstGoodEns; $ens<=$lastGoodEns; $ens++) {
       
  1402 	next unless numberp($LADCP{ENSEMBLE}[$ens]->{CTD_DEPTH});
       
  1403 	next unless ($CTD{W}[$LADCP{ENSEMBLE}[$ens]->{CTD_SCAN}] > $ambiguity_velocity);
       
  1404 	$nbad++;
       
  1405 }
       
  1406 
       
  1407 my($badf) = $nbad / ($lastGoodEns - $firstGoodEns + 1);			# fraction of bad values
       
  1408 if ($bad > 0.01) {												# allow 1% violations before warning is triggered
       
  1409 	warning(2,"%d ensembles (%d%% of total) have CTD_w > ambiguity velocity of %.1 m/s\n",
       
  1410 		$nbad,round(100*$badf),$ambiguity_velocity);
       
  1411 } elsif ($nbad > 0) {
       
  1412 	info("\t%d ensembles (%d%% of total) have CTD_w > ambiguity velocity of %.1 m/s",
       
  1413 		$nbad,round(100*$badf),$ambiguity_velocity);
       
  1414 } else {
       
  1415 	info("\tnone found\n");
       
  1416 }
       
  1417 
       
  1418 #----------------------------------------------------------------------
  1344 # Data Editing after LADCP and CTD data have been merged
  1419 # Data Editing after LADCP and CTD data have been merged
  1345 #	1) surface layer editing
  1420 #	1) surface layer editing
  1346 #	2) Execute user-supplied $edit_data_hook
  1421 #	2) reference-layer horizontal velocity threshold
       
  1422 #	3) Execute user-supplied $edit_data_hook
  1347 #----------------------------------------------------------------------
  1423 #----------------------------------------------------------------------
  1348 
  1424 
  1349 progress("Removing data from instrument at surface...\n");
  1425 progress("Removing data from instrument at surface...\n");
  1350 &antsAddParams('surface_layer_depth',$surface_layer_depth);
  1426 &antsAddParams('surface_layer_depth',$surface_layer_depth);
  1351 $nerm = editSurfLayer($firstGoodEns,$lastGoodEns,$surface_layer_depth);
  1427 $nerm = editSurfLayer($firstGoodEns,$lastGoodEns,$surface_layer_depth);
  1352 progress("\t$nerm ensembles removed\n");
  1428 progress("\t$nerm ensembles removed\n");
       
  1429 
       
  1430 progress("Removing data collected at large horizontal package speeds...\n");
       
  1431 $max_hspeed = &max_hspeed();												# defined in [defaults.h]
       
  1432 &antsAddParams('max_hspeed',$max_hspeed);
       
  1433 $nerm = editLargeHSpeeds($firstGoodEns,$lastGoodEns,$max_hspeed);
       
  1434 my($nermf) = $nerm / ($lastGoodEns - $firstGoodEns + 1);
       
  1435 info("\treference-layer horizontal speed threshold (max_hspeed = %g m/s): %d ensembles removed (%d%% of total)\n",
       
  1436 	$max_hspeed,$nerm,round(100*$nermf));
       
  1437 warning(2,"large fraction (%d%%) of samples exceed reference-layer horizontal speed threshold\n",round(100*$nermf))
       
  1438 	if ($nermf > 0.05);		
  1353 
  1439 
  1354 if (defined($post_merge_hook)) {
  1440 if (defined($post_merge_hook)) {
  1355 	progress("Executing user-supplied \$post_merge_hook...\n");
  1441 	progress("Executing user-supplied \$post_merge_hook...\n");
  1356 	&{$post_merge_hook}($firstGoodEns,$lastGoodEns);
  1442 	&{$post_merge_hook}($firstGoodEns,$lastGoodEns);
  1357 }
  1443 }
  1567 		next unless numberp($LADCP{ENSEMBLE}[$ens]->{MEDIAN_RESIDUAL_W});
  1653 		next unless numberp($LADCP{ENSEMBLE}[$ens]->{MEDIAN_RESIDUAL_W});
  1568 		
  1654 		
  1569 		for ($bin=$LADCP_firstBin-1; $bin<=$LADCP_lastBin-1; $bin++) {		# subtract from ocean velocities
  1655 		for ($bin=$LADCP_firstBin-1; $bin<=$LADCP_lastBin-1; $bin++) {		# subtract from ocean velocities
  1570 			next unless numberp($LADCP{ENSEMBLE}[$ens]->{W}[$bin]);
  1656 			next unless numberp($LADCP{ENSEMBLE}[$ens]->{W}[$bin]);
  1571 			$LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W}[$bin] -=
  1657 			$LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W}[$bin] -=
  1572 				$LADCP{ENSEMBLE}[$ens]->{MEDIAN_RESIDUAL_W};
  1658 				$LADCP{ENSEMBLE}[$ens]->{MEDIAN_RESIDUAL_W}
       
  1659 					if numberp($LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W}[$bin]);
  1573 			$LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W12}[$bin] -=
  1660 			$LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W12}[$bin] -=
  1574 				$LADCP{ENSEMBLE}[$ens]->{MEDIAN_RESIDUAL_W};
  1661 				$LADCP{ENSEMBLE}[$ens]->{MEDIAN_RESIDUAL_W}
       
  1662 					if numberp($LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W12}[$bin]);
  1575 			$LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W34}[$bin] -=
  1663 			$LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W34}[$bin] -=
  1576 				$LADCP{ENSEMBLE}[$ens]->{MEDIAN_RESIDUAL_W};
  1664 				$LADCP{ENSEMBLE}[$ens]->{MEDIAN_RESIDUAL_W}
       
  1665 					if numberp($LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W34}[$bin]);
  1577 		}
  1666 		}
  1578 		
  1667 		
  1579 		$LADCP{ENSEMBLE}[$ens]->{REFLR_W} -=								# NB: this can be nan here
  1668 		$LADCP{ENSEMBLE}[$ens]->{REFLR_W} -=								# NB: this can be nan here
  1580 			$LADCP{ENSEMBLE}[$ens]->{MEDIAN_RESIDUAL_W}
  1669 			$LADCP{ENSEMBLE}[$ens]->{MEDIAN_RESIDUAL_W}
  1581 				if numberp($LADCP{ENSEMBLE}[$ens]->{REFLR_W});
  1670 				if numberp($LADCP{ENSEMBLE}[$ens]->{REFLR_W});
  1585 
  1674 
  1586     progress("\tre-binning profile data...\n");
  1675     progress("\tre-binning profile data...\n");
  1587     
  1676     
  1588 	for (my($bi)=0; $bi<=$#{$DNCAST{ENSEMBLE}}; $bi++) {					# bin data
  1677 	for (my($bi)=0; $bi<=$#{$DNCAST{ENSEMBLE}}; $bi++) {					# bin data
  1589 		for (my($i)=0; $i<@{$DNCAST{W}[$bi]}; $i++) {						# code works if MEDIAN_RESIDUAL_W is nan (possible?) 
  1678 		for (my($i)=0; $i<@{$DNCAST{W}[$bi]}; $i++) {						# code works if MEDIAN_RESIDUAL_W is nan (possible?) 
  1590 			$DNCAST{W}  [$bi][$i] -= $LADCP{ENSEMBLE}[$DNCAST{ENSEMBLE}[$bi][$i]]->{MEDIAN_RESIDUAL_W};
  1679 			$DNCAST{W}  [$bi][$i] -= $LADCP{ENSEMBLE}[$DNCAST{ENSEMBLE}[$bi][$i]]->{MEDIAN_RESIDUAL_W}
  1591 			$DNCAST{W12}[$bi][$i] -= $LADCP{ENSEMBLE}[$DNCAST{ENSEMBLE}[$bi][$i]]->{MEDIAN_RESIDUAL_W};
  1680 				if numberp($DNCAST{W}[$bi][$i]);
  1592 			$DNCAST{W34}[$bi][$i] -= $LADCP{ENSEMBLE}[$DNCAST{ENSEMBLE}[$bi][$i]]->{MEDIAN_RESIDUAL_W};
  1681 			$DNCAST{W12}[$bi][$i] -= $LADCP{ENSEMBLE}[$DNCAST{ENSEMBLE}[$bi][$i]]->{MEDIAN_RESIDUAL_W}
  1593 		}
  1682 				if numberp($DNCAST{W12}[$bi][$i]);
  1594 		$DNCAST{MEDIAN_W}  [$bi] = median(@{$DNCAST{W}[$bi]});
  1683 			$DNCAST{W34}[$bi][$i] -= $LADCP{ENSEMBLE}[$DNCAST{ENSEMBLE}[$bi][$i]]->{MEDIAN_RESIDUAL_W}
  1595 		$DNCAST{MEDIAN_W12}[$bi] = median(@{$DNCAST{W12}[$bi]});
  1684 				if numberp($DNCAST{W34}[$bi][$i]);
  1596 		$DNCAST{MEDIAN_W34}[$bi] = median(@{$DNCAST{W34}[$bi]});
  1685 		}
       
  1686 		$DNCAST{MEDIAN_W}  [$bi] = median(@{$DNCAST{W}[$bi]}) 	if numberp($DNCAST{MEDIAN_W}  [$bi]);
       
  1687 		$DNCAST{MEDIAN_W12}[$bi] = median(@{$DNCAST{W12}[$bi]}) if numberp($DNCAST{MEDIAN_W12}[$bi]);
       
  1688 		$DNCAST{MEDIAN_W34}[$bi] = median(@{$DNCAST{W34}[$bi]}) if numberp($DNCAST{MEDIAN_W34}[$bi]);
  1597 		$DNCAST{MAD_W}	   [$bi] = mad2($DNCAST{MEDIAN_W}[$bi],@{$DNCAST{W}[$bi]});
  1689 		$DNCAST{MAD_W}	   [$bi] = mad2($DNCAST{MEDIAN_W}[$bi],@{$DNCAST{W}[$bi]});
  1598 	}
  1690 	}
  1599 	for (my($bi)=0; $bi<=$#{$UPCAST{ENSEMBLE}}; $bi++) {
  1691 	for (my($bi)=0; $bi<=$#{$UPCAST{ENSEMBLE}}; $bi++) {
  1600 		for (my($i)=0; $i<@{$UPCAST{W}[$bi]}; $i++) {
  1692 		for (my($i)=0; $i<@{$UPCAST{W}[$bi]}; $i++) {
  1601 			$UPCAST{W}  [$bi][$i] -= $LADCP{ENSEMBLE}[$UPCAST{ENSEMBLE}[$bi][$i]]->{MEDIAN_RESIDUAL_W};
  1693 			$UPCAST{W}  [$bi][$i] -= $LADCP{ENSEMBLE}[$UPCAST{ENSEMBLE}[$bi][$i]]->{MEDIAN_RESIDUAL_W}
  1602 			$UPCAST{W12}[$bi][$i] -= $LADCP{ENSEMBLE}[$UPCAST{ENSEMBLE}[$bi][$i]]->{MEDIAN_RESIDUAL_W};
  1694 				if numberp($UPCAST{W}[$bi][$i]);
  1603 			$UPCAST{W34}[$bi][$i] -= $LADCP{ENSEMBLE}[$UPCAST{ENSEMBLE}[$bi][$i]]->{MEDIAN_RESIDUAL_W};
  1695 			$UPCAST{W12}[$bi][$i] -= $LADCP{ENSEMBLE}[$UPCAST{ENSEMBLE}[$bi][$i]]->{MEDIAN_RESIDUAL_W}
  1604 		}
  1696 				if numberp($UPCAST{W12}[$bi][$i]);
  1605 		$UPCAST{MEDIAN_W}  [$bi] = median(@{$UPCAST{W}[$bi]});
  1697 			$UPCAST{W34}[$bi][$i] -= $LADCP{ENSEMBLE}[$UPCAST{ENSEMBLE}[$bi][$i]]->{MEDIAN_RESIDUAL_W}
  1606 		$UPCAST{MEDIAN_W12}[$bi] = median(@{$UPCAST{W12}[$bi]});
  1698 				if numberp($UPCAST{W34}[$bi][$i]);
  1607 		$UPCAST{MEDIAN_W34}[$bi] = median(@{$UPCAST{W34}[$bi]});
  1699 		}
       
  1700 		$UPCAST{MEDIAN_W}  [$bi] = median(@{$UPCAST{W}[$bi]})	if numberp($UPCAST{MEDIAN_W}  [$bi]);
       
  1701 		$UPCAST{MEDIAN_W12}[$bi] = median(@{$UPCAST{W12}[$bi]})	if numberp($UPCAST{MEDIAN_W12}[$bi]);
       
  1702 		$UPCAST{MEDIAN_W34}[$bi] = median(@{$UPCAST{W34}[$bi]})	if numberp($UPCAST{MEDIAN_W34}[$bi]);
  1608 		$UPCAST{MAD_W}	   [$bi] = mad2($UPCAST{MEDIAN_W}[$bi],@{$UPCAST{W}[$bi]});
  1703 		$UPCAST{MAD_W}	   [$bi] = mad2($UPCAST{MEDIAN_W}[$bi],@{$UPCAST{W}[$bi]});
  1609 	}
  1704 	}
  1610 
  1705 
  1611 } # unless ($opt_q);
  1706 } # unless ($opt_q);
  1612 
  1707 
  1613 #----------------------------------------------------------------------
  1708 #----------------------------------------------------------------------
  1614 # remove ensembles with large rms residuals
  1709 # remove ensembles with large rms residuals
  1615 #----------------------------------------------------------------------
  1710 #----------------------------------------------------------------------
  1616 
  1711 
  1617 if (defined($opt_r)) {
  1712 if (defined($opt_r) && !$opt_q) {
  1618 	progress("Applying residuals filters...\n");	
  1713 	progress("Applying residuals filters...\n");	
  1619 	
  1714 	
  1620 	progress("\trms residuals > $residuals_rms_max: ");
  1715 	progress("\trms residuals > $residuals_rms_max: ");
  1621 	my($nerm) = editResiduals_rmsMax($firstGoodEns,$lastGoodEns,$residuals_rms_max);
  1716 	my($nerm) = editResiduals_rmsMax($firstGoodEns,$lastGoodEns,$residuals_rms_max);
  1622 	progress("$nerm ensembles removed (%d%% of total)\n",round(100*$nerm/($lastGoodEns-$firstGoodEns+1)));
  1717 	progress("$nerm ensembles removed (%d%% of total)\n",round(100*$nerm/($lastGoodEns-$firstGoodEns+1)));
  1709 	for ($bin=$LADCP_firstBin-1; $bin<=$LADCP_lastBin-1; $bin++) {
  1804 	for ($bin=$LADCP_firstBin-1; $bin<=$LADCP_lastBin-1; $bin++) {
  1710 		next unless ($bin+1>=$outGrid_firstBin && $bin+1<=$outGrid_lastBin);
  1805 		next unless ($bin+1>=$outGrid_firstBin && $bin+1<=$outGrid_lastBin);
  1711 		next unless numberp($LADCP{ENSEMBLE}[$ens]->{W}[$bin]);
  1806 		next unless numberp($LADCP{ENSEMBLE}[$ens]->{W}[$bin]);
  1712 		my($bi) = $bindepth[$bin]/$opt_o;
  1807 		my($bi) = $bindepth[$bin]/$opt_o;
  1713 		next unless numberp($DNCAST{MEDIAN_W}[$bi]);
  1808 		next unless numberp($DNCAST{MEDIAN_W}[$bi]);
  1714 		push(@{$DNCAST{RESIDUAL12}[$bi]},$LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W12}[$bin]-$DNCAST{MEDIAN_W}[$bi]);
  1809 		push(@{$DNCAST{RESIDUAL12}[$bi]},$LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W12}[$bin]-$DNCAST{MEDIAN_W}[$bi])
  1715 		push(@{$DNCAST{RESIDUAL34}[$bi]},$LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W34}[$bin]-$DNCAST{MEDIAN_W}[$bi]);
  1810 			if numberp($LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W12}[$bin]);
       
  1811 		push(@{$DNCAST{RESIDUAL34}[$bi]},$LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W34}[$bin]-$DNCAST{MEDIAN_W}[$bi])
       
  1812 			if numberp($LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W34}[$bin]);
  1716     }
  1813     }
  1717 }
  1814 }
  1718 for (my($bi)=0; $bi<=$#{$DNCAST{ENSEMBLE}}; $bi++) {
  1815 for (my($bi)=0; $bi<=$#{$DNCAST{ENSEMBLE}}; $bi++) {
  1719 	$DNCAST{MEAN_RESIDUAL12}[$bi] = avg(@{$DNCAST{RESIDUAL12}[$bi]});
  1816 	$DNCAST{MEAN_RESIDUAL12}[$bi] = avg(@{$DNCAST{RESIDUAL12}[$bi]});
  1720 	$DNCAST{MEAN_RESIDUAL34}[$bi] = avg(@{$DNCAST{RESIDUAL34}[$bi]});
  1817 	$DNCAST{MEAN_RESIDUAL34}[$bi] = avg(@{$DNCAST{RESIDUAL34}[$bi]});
  1726 	for ($bin=$LADCP_firstBin-1; $bin<=$LADCP_lastBin-1; $bin++) {
  1823 	for ($bin=$LADCP_firstBin-1; $bin<=$LADCP_lastBin-1; $bin++) {
  1727 		next unless ($bin+1>=$outGrid_firstBin && $bin+1<=$outGrid_lastBin);
  1824 		next unless ($bin+1>=$outGrid_firstBin && $bin+1<=$outGrid_lastBin);
  1728 		next unless numberp($LADCP{ENSEMBLE}[$ens]->{W}[$bin]);
  1825 		next unless numberp($LADCP{ENSEMBLE}[$ens]->{W}[$bin]);
  1729 		my($bi) = $bindepth[$bin]/$opt_o;
  1826 		my($bi) = $bindepth[$bin]/$opt_o;
  1730 		next unless numberp($UPCAST{MEDIAN_W}[$bi]);
  1827 		next unless numberp($UPCAST{MEDIAN_W}[$bi]);
  1731 		push(@{$UPCAST{RESIDUAL12}[$bi]},$LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W12}[$bin]-$UPCAST{MEDIAN_W}[$bi]);
  1828 		push(@{$UPCAST{RESIDUAL12}[$bi]},$LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W12}[$bin]-$UPCAST{MEDIAN_W}[$bi])
  1732 		push(@{$UPCAST{RESIDUAL34}[$bi]},$LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W34}[$bin]-$UPCAST{MEDIAN_W}[$bi]);
  1829 			if numberp($LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W12}[$bin]);
       
  1830 		push(@{$UPCAST{RESIDUAL34}[$bi]},$LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W34}[$bin]-$UPCAST{MEDIAN_W}[$bi])
       
  1831 			if numberp($LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W34}[$bin]);
  1733     }
  1832     }
  1734 }
  1833 }
  1735 for (my($bi)=0; $bi<=$#{$UPCAST{ENSEMBLE}}; $bi++) {
  1834 for (my($bi)=0; $bi<=$#{$UPCAST{ENSEMBLE}}; $bi++) {
  1736 	$UPCAST{MEAN_RESIDUAL12}[$bi] = avg(@{$UPCAST{RESIDUAL12}[$bi]});
  1835 	$UPCAST{MEAN_RESIDUAL12}[$bi] = avg(@{$UPCAST{RESIDUAL12}[$bi]});
  1737 	$UPCAST{MEAN_RESIDUAL34}[$bi] = avg(@{$UPCAST{RESIDUAL34}[$bi]});
  1836 	$UPCAST{MEAN_RESIDUAL34}[$bi] = avg(@{$UPCAST{RESIDUAL34}[$bi]});
  1840 
  1939 
  1841 #--------------------------------------------------
  1940 #--------------------------------------------------
  1842 # Calculate BT-referenced vertical-velocity profile
  1941 # Calculate BT-referenced vertical-velocity profile
  1843 #--------------------------------------------------
  1942 #--------------------------------------------------
  1844 
  1943 
  1845 if (defined($water_depth)) {
  1944 if ($LADCP{ENSEMBLE}[$LADCP_atbottom]->{XDUCER_FACING_DOWN} && defined($water_depth)) {
       
  1945 	
  1846 	progress("Calculating BT-referenced vertical velocities\n");
  1946 	progress("Calculating BT-referenced vertical velocities\n");
  1847 	calc_BTprof($firstGoodEns,$lastGoodEns,$water_depth,$sig_water_depth);
  1947 	calc_BTprof($firstGoodEns,$lastGoodEns,$water_depth,$sig_water_depth);
  1848 
  1948 
  1849 	my($sumSq) = my($n) = 0;
  1949 	my($sumSq) = my($n) = 0;
  1850 	for (my($bi)=0; $bi<=$#{$BT{MEDIAN_W}}; $bi++) {
  1950 	for (my($bi)=0; $bi<=$#{$BT{MEDIAN_W}}; $bi++) {
  1885 		}
  1985 		}
  1886 			
  1986 			
  1887 	    $of = ">$of" unless ($of =~ /^$|^\s*\|/);
  1987 	    $of = ">$of" unless ($of =~ /^$|^\s*\|/);
  1888 		open(STDOUT,$of) || error("$of: $!\n");
  1988 		open(STDOUT,$of) || error("$of: $!\n");
  1889 		undef($antsActiveHeader) unless ($ANTS_TOOLS_AVAILABLE);
  1989 		undef($antsActiveHeader) unless ($ANTS_TOOLS_AVAILABLE);
       
  1990 
       
  1991 		sub res($$)
       
  1992 		{
       
  1993 			my($meas,$mean) = @_;
       
  1994 			return numberp($meas) ? ($meas - $mean) : undef;
       
  1995 		}
  1890 	    
  1996 	    
  1891 		for ($ens=$firstGoodEns; $ens<$LADCP_atbottom; $ens++) {						# downcast
  1997 		for ($ens=$firstGoodEns; $ens<$LADCP_atbottom; $ens++) {						# downcast
  1892 		  next unless numberp($LADCP{ENSEMBLE}[$ens]->{CTD_DEPTH});
  1998 		  next unless numberp($LADCP{ENSEMBLE}[$ens]->{CTD_DEPTH});
  1893 		  my(@bindepth) = binDepths($ens);
  1999 		  my(@bindepth) = binDepths($ens);
  1894 		  for ($bin=$LADCP_firstBin-1; $bin<=$LADCP_lastBin-1; $bin++) {
  2000 		  for ($bin=$LADCP_firstBin-1; $bin<=$LADCP_lastBin-1; $bin++) {
  1900 				  $bindepth[$bin],$LADCP{ENSEMBLE}[$ens]->{CTD_DEPTH},1,
  2006 				  $bindepth[$bin],$LADCP{ENSEMBLE}[$ens]->{CTD_DEPTH},1,
  1901 				  $LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W}[$bin],
  2007 				  $LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W}[$bin],
  1902 				  $LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W12}[$bin],
  2008 				  $LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W12}[$bin],
  1903 				  $LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W34}[$bin],
  2009 				  $LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W34}[$bin],
  1904 				  $LADCP{ENSEMBLE}[$ens]->{V12}[$bin],$LADCP{ENSEMBLE}[$ens]->{V34}[$bin],
  2010 				  $LADCP{ENSEMBLE}[$ens]->{V12}[$bin],$LADCP{ENSEMBLE}[$ens]->{V34}[$bin],
  1905 				  $LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W}[$bin] - $DNCAST{MEDIAN_W}[$bi],
  2011 				  res($LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W}[$bin],$DNCAST{MEDIAN_W}[$bi]),
  1906 				  $LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W12}[$bin] - $DNCAST{MEDIAN_W}[$bi],
  2012 				  res($LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W12}[$bin],$DNCAST{MEDIAN_W}[$bi]),
  1907 				  $LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W34}[$bin] - $DNCAST{MEDIAN_W}[$bi],
  2013 				  res($LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W34}[$bin],$DNCAST{MEDIAN_W}[$bi]),
  1908 				  $CTD{W}[$LADCP{ENSEMBLE}[$ens]->{CTD_SCAN}],
  2014 				  $CTD{W}[$LADCP{ENSEMBLE}[$ens]->{CTD_SCAN}],
  1909 				  $CTD{W_t}[$LADCP{ENSEMBLE}[$ens]->{CTD_SCAN}],
  2015 				  $CTD{W_t}[$LADCP{ENSEMBLE}[$ens]->{CTD_SCAN}],
  1910 				  $CTD{W_tt}[$LADCP{ENSEMBLE}[$ens]->{CTD_SCAN}],
  2016 				  $CTD{W_tt}[$LADCP{ENSEMBLE}[$ens]->{CTD_SCAN}],
  1911 				  $LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_W}[$bin],
  2017 				  $LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_W}[$bin],
  1912 				  $LADCP{ENSEMBLE}[$ens]->{REFLR_W},
  2018 				  $LADCP{ENSEMBLE}[$ens]->{REFLR_W},
  1940 				  $bindepth[$bin],$LADCP{ENSEMBLE}[$ens]->{CTD_DEPTH},0,
  2046 				  $bindepth[$bin],$LADCP{ENSEMBLE}[$ens]->{CTD_DEPTH},0,
  1941 				  $LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W}[$bin],
  2047 				  $LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W}[$bin],
  1942 				  $LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W12}[$bin],
  2048 				  $LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W12}[$bin],
  1943 				  $LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W34}[$bin],
  2049 				  $LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W34}[$bin],
  1944 				  $LADCP{ENSEMBLE}[$ens]->{V12}[$bin],$LADCP{ENSEMBLE}[$ens]->{V34}[$bin],
  2050 				  $LADCP{ENSEMBLE}[$ens]->{V12}[$bin],$LADCP{ENSEMBLE}[$ens]->{V34}[$bin],
  1945 				  $LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W}[$bin] - $UPCAST{MEDIAN_W}[$bi],
  2051 				  res($LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W}[$bin],$UPCAST{MEDIAN_W}[$bi]),
  1946 				  $LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W12}[$bin] - $UPCAST{MEDIAN_W}[$bi],
  2052 				  res($LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W12}[$bin],$UPCAST{MEDIAN_W}[$bi]),
  1947 				  $LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W34}[$bin] - $UPCAST{MEDIAN_W}[$bi],
  2053 				  res($LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W34}[$bin],$UPCAST{MEDIAN_W}[$bi]),
  1948 				  $CTD{W}[$LADCP{ENSEMBLE}[$ens]->{CTD_SCAN}],
  2054 				  $CTD{W}[$LADCP{ENSEMBLE}[$ens]->{CTD_SCAN}],
  1949 				  $CTD{W_t}[$LADCP{ENSEMBLE}[$ens]->{CTD_SCAN}],
  2055 				  $CTD{W_t}[$LADCP{ENSEMBLE}[$ens]->{CTD_SCAN}],
  1950 				  $CTD{W_tt}[$LADCP{ENSEMBLE}[$ens]->{CTD_SCAN}],
  2056 				  $CTD{W_tt}[$LADCP{ENSEMBLE}[$ens]->{CTD_SCAN}],
  1951 				  $LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_W}[$bin],
  2057 				  $LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_W}[$bin],
  1952 				  $LADCP{ENSEMBLE}[$ens]->{REFLR_W},
  2058 				  $LADCP{ENSEMBLE}[$ens]->{REFLR_W},