LADCP_w_ocean
changeset 47 2ccb81b7cea5
parent 46 cc6c4309828a
child 48 d9309804b6cf
equal deleted inserted replaced
46:cc6c4309828a 47:2ccb81b7cea5
     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: Tue May 24 16:33:29 2016
     5 #                    dlm: Sat Jun 11 18:34:12 2016
     6 #                    (c) 2010 A.M. Thurnherr
     6 #                    (c) 2010 A.M. Thurnherr
     7 #                    uE-Info: 1868 26 NIL 0 0 72 2 2 4 NIL ofnI
     7 #                    uE-Info: 272 65 NIL 0 0 72 2 2 4 NIL ofnI
     8 #======================================================================
     8 #======================================================================
     9 
     9 
    10 # TODO:
    10 # TODO:
    11 #   ! plots:
    11 #   ! use instrument tilt in sidelobe editing
       
    12 #	! use instrument tilt in e.g. Sv
       
    13 #
       
    14 #   - plots:
    12 #       - avoid over-plotting axis labels
    15 #       - avoid over-plotting axis labels
    13 #       - allow for different nsamp magnitudes
    16 #       - allow for different nsamp magnitudes
    14 #       - add "dc" "uc" labels
    17 #       - add "dc" "uc" labels
    15 #       - add seabed to eps.VKE profile
    18 #       - add seabed to eps.VKE profile
    16 #       - add seabed to LADCP_w_postproc .wprof output
    19 #       - add seabed to LADCP_w_postproc .wprof output
    17 #   ! use instrument tilt in sidelobe editing
    20 #
    18 #   - worry about water-depth differences (disabled warning) 
    21 #   - worry about water-depth differences (disabled warning) 
    19 #   - make upcast-flag valid for yoyo casts
    22 #   - make upcast-flag valid for yoyo casts
    20 #   - make diagnostic output 3-beam field work for Earth coordinates
    23 #   - make diagnostic output 3-beam field work for Earth coordinates
    21 
    24 
    22 $antsSummary = 'calculate vertical velocities from LADCP & CTD time series';
    25 $antsSummary = 'calculate vertical velocities from LADCP & CTD time series';
   249 #				  - expunged super-confusing $realLastGoodEns
   252 #				  - expunged super-confusing $realLastGoodEns
   250 #				  - removed assumption of default 1500m/s sspd setting during acquisition
   253 #				  - removed assumption of default 1500m/s sspd setting during acquisition
   251 #				  - added w12, w34 for earth-coordinates
   254 #				  - added w12, w34 for earth-coordinates
   252 #   May 19, 2016: - updated to ADCP_tools V1.6
   255 #   May 19, 2016: - updated to ADCP_tools V1.6
   253 #	May 24, 2016: - calc_binDepths() -> binDepths()
   256 #	May 24, 2016: - calc_binDepths() -> binDepths()
       
   257 #	May 26, 2016: - added -d)isable bin interpolation
       
   258 #				  - adapted to w_CTD, w_winch
       
   259 #				  - re-enabled disabled L0 warning
       
   260 #				  - suppressing L0 warnings on screen
       
   261 #	May 27, 2016: - cosmetics
       
   262 #				  - added reflr_w to .wsamp output
       
   263 #	May 29, 2016: - BUG: do ProcessingParams did not handle all errors correctly
       
   264 #	Jun  1, 2016: - made empirical accoustic backscatter correction optional
       
   265 #				  - split [default_paths.pl] to same plus [default_output.pl]
       
   266 #	Jun  2, 2016: - added applyTiltCorrection()
       
   267 #				  - BUG: PPI-editing was no longer enabled automatically
       
   268 #						 for 150kHz instruments
       
   269 #	Jun  3, 2016: - BUG: earth-coordinate data did not have gimbal-pitch
       
   270 #						 calculated
       
   271 #	Jun  6, 2016: - removed applyTiltCorrection()
       
   272 #	Jun 11, 2016: - BUG: w12, w34 were wrong for Earth-coord data
   254 # HISTORY END
   273 # HISTORY END
   255 
   274 
   256 # CTD REQUIREMENTS
   275 # CTD REQUIREMENTS
   257 #	- elapsed		elapsed seconds; see note below
   276 #	- elapsed		elapsed seconds; see note below
   258 #	- depth
   277 #	- depth
   259 #	- ss			sound speed
   278 #	- ss			sound speed
   260 #	- w				ddepth/dt
   279 #	- w[_CTD]		ddepth/dt
       
   280 #	- w_winch		OPTIONAL; winch-speed estimate
   261 #	- temp			OPTIONAL; used for backscatter calculation
   281 #	- temp			OPTIONAL; used for backscatter calculation
   262 #	- %lat/%lon		OPTIONAL
   282 #	- %lat/%lon		OPTIONAL
   263 
   283 
   264 # 2-BEAM SOLUTIONS
   284 # 2-BEAM SOLUTIONS
   265 #	- both for beam- and earth-coordinate data, two separate two-beam
   285 #	- both for beam- and earth-coordinate data, two separate two-beam
   300 #		1) 004DL.prof dc_w depth
   320 #		1) 004DL.prof dc_w depth
   301 #		2) bindata -Sdowncast:1 -Fw.median,depth -n 20 depth 10 004DL.w
   321 #		2) bindata -Sdowncast:1 -Fw.median,depth -n 20 depth 10 004DL.w
   302 
   322 
   303 # VELOCITY AMBIGUITY ERRORS
   323 # VELOCITY AMBIGUITY ERRORS
   304 #	- quite extensive tests with DIMES US2 station 146, which has a lot of
   324 #	- quite extensive tests with DIMES US2 station 146, which has a lot of
   305 #	  ambiguity velocity errors, reveal that -m 1 catches those errors
   325 #	  ambiguity velocity errors, reveal that $w_max_lim catches those errors
   306 #	  quite nicely
   326 #	  quite nicely
   307 #	- even when the errors are not filtered with -m 1, they do not
   327 #	- even when the errors are not filtered with $w_max_lim, they do not
   308 #	  affect the w profiles, as long as the median bin values are used
   328 #	  affect the w profiles, as long as the median bin values are used
   309 
   329 
   310 ($ANTS) 	  = (`which ANTSlib`   =~ m{^(.*)/[^/]*$});
   330 ($ANTS) 	  = (`which ANTSlib`   =~ m{^(.*)/[^/]*$});
   311 ($ADCP_TOOLS) = (`which mkProfile` =~ m{^(.*)/[^/]*$});
   331 ($ADCP_TOOLS) = (`which mkProfile` =~ m{^(.*)/[^/]*$});
   312 ($WCALC) 	  = ($0                =~ m{^(.*)/[^/]*$});
   332 ($WCALC) 	  = ($0                =~ m{^(.*)/[^/]*$});
   342 #------
   362 #------
   343 
   363 
   344 require "$WCALC/defaults.pl";												# load default/option parameters
   364 require "$WCALC/defaults.pl";												# load default/option parameters
   345 
   365 
   346 $antsParseHeader = 0;
   366 $antsParseHeader = 0;
   347 &antsUsage('3:4a:b:c:e:g:h:i:k:lm:n:o:p:qr:s:t:uv:Vw:x:',0,
   367 &antsUsage('3:4a:b:c:de:g:h:i:k:lm:n:o:p:qr:s:t:uv:Vw:x:',0,
   348 	"[print software -V)ersion] [-v)erbosity <level[$opt_v]>]",
   368 	"[print software -V)ersion] [-v)erbosity <level[$opt_v]>]",
   349 	"[-q)uick (no single-ping denoising)]",
   369 	"[-q)uick (no single-ping denoising)]",
   350     "[require -4)-beam solutions] [apply beamvel-m)ask <file> if it exists]",
   370     "[require -4)-beam solutions] [-d)isable bin interpolation] [apply beamvel-m)ask <file> if it exists]",
   351 	"[valid LADCP -b)ins <bin,bin[$opt_b]>",
   371 	"[valid LADCP -b)ins <bin,bin[$opt_b]>",
   352 	"[-c)orrelation <min[$opt_c counts]>] [-t)ilt <max[$opt_t deg]> [-e)rr-vel <max[$opt_e m/s]>]",
   372 	"[-c)orrelation <min[$opt_c counts]>] [-t)ilt <max[$opt_t deg]> [-e)rr-vel <max[$opt_e m/s]>]",
   353 	"[-r)esidual <rms.max[$opt_r m/s]>]",
   373 	"[-r)esidual <rms.max[,delta.max][$opt_r m/s]>]",
   354 	"[-h water <depth|filename>]",
   374 	"[-h water <depth|filename>]",
   355 	"[max LADCP time-series -g)ap <length[$opt_g s]>]",
   375 	"[max LADCP time-series -g)ap <length[$opt_g s]>]",
   356 	"[-i)nitial CTD time offset <guestimate> [-u)se as final]]",
   376 	"[-i)nitial CTD time offset <guestimate> [-u)se as final]]",
   357 	"[calculate -n) <lags,lags[$opt_n]>] [lag -w)indow <sz,sz[$opt_w s]>] [lag-p)iece <CTD_elapsed_min|+[,...]>]",
   377 	"[calculate -n) <lags,lags[$opt_n]>] [lag -w)indow <sz,sz[$opt_w s]>] [lag-p)iece <CTD_elapsed_min|+[,...]>]",
   358 	"[require top-3) lags to account for <frac[$opt_3]> of all]",
   378 	"[require top-3) lags to account for <frac[$opt_3]> of all]",
   384 	shift;
   404 	shift;
   385 } else {
   405 } else {
   386 	$RUN = 'profiles';
   406 	$RUN = 'profiles';
   387 }
   407 }
   388 
   408 
   389 #-----------------------------
   409 #----------------------------------------------------------------
   390 # Handle Processing Parameters
   410 # Handle Processing Parameters
   391 #-----------------------------
   411 #	- paths need to be read first to define ProcessingParams file
   392 
   412 # 	  and output directories
   393 require "$WCALC/default_paths.pl";										# load default input/output paths
   413 #	- processing params file is read next to allow setting
   394 croak("$processing_param_file: $@")
   414 #	  plotting_level
   395 	unless ($err = do "$processing_param_file");						# load processing parameters
   415 #	- default_output.pl is read finally to set any missing output
       
   416 #	  variables to default values
       
   417 #----------------------------------------------------------------
       
   418 
       
   419 require "$WCALC/default_paths.pl";										# define default input/output paths
       
   420 my($retval) = do $processing_param_file;								# load processing parameters
       
   421 if (!defined($retval) && $@ ne '') {
       
   422 	croak("$processing_param_file: $@\n");
       
   423 } elsif (!defined($retval) && $! != 0) {
       
   424 	croak("$processing_param_file: $!\n");
       
   425 }
       
   426 require "$WCALC/default_output.pl";										# set default output plots and files
   396 
   427 
   397 $processing_options = "-k $opt_k -o $opt_o -c $opt_c -t $opt_t -e $opt_e -g $opt_g -3 $opt_3";
   428 $processing_options = "-k $opt_k -o $opt_o -c $opt_c -t $opt_t -e $opt_e -g $opt_g -3 $opt_3";
   398 $processing_options .= " -i $opt_i" if defined($opt_i);
   429 $processing_options .= " -i $opt_i" if defined($opt_i);
   399 $processing_options .= " -r $opt_r" if defined($opt_r);
       
   400 $processing_options .= ' -l' if defined($opt_l);
   430 $processing_options .= ' -l' if defined($opt_l);
   401 $processing_options .= ' -q' if defined($opt_q);
   431 $processing_options .= ' -q' if defined($opt_q);
       
   432 $processing_options .= ' -d' if defined($opt_d);
   402 
   433 
   403 if (defined($opt_x)) {													# eval cmd-line expression to override anything
   434 if (defined($opt_x)) {													# eval cmd-line expression to override anything
   404 	$processing_options .= " -x $opt_x";
   435 	$processing_options .= " -x $opt_x";
   405 	eval($opt_x);
   436 	eval($opt_x);
   406 }
   437 }
   408 if ($opt_4) {															# disallow 3-beam solutions
   439 if ($opt_4) {															# disallow 3-beam solutions
   409 	$processing_options .= " -4";
   440 	$processing_options .= " -4";
   410 	$RDI_Coords::minValidVels = 4;
   441 	$RDI_Coords::minValidVels = 4;
   411 }
   442 }
   412 	
   443 	
       
   444 if (defined($opt_r)) {													# residuals filters
       
   445 	$processing_options .= " -r $opt_r";
       
   446 	($residuals_rms_max,$residuals_delta_max) = split(',',$opt_r);
       
   447 	croak("$0: cannot decode -r $opt_r\n") unless ($residuals_rms_max > 0);
       
   448 }
       
   449 
   413 ($LADCP_firstBin,$LADCP_lastBin) = split(',',$opt_b);					# select valid bins
   450 ($LADCP_firstBin,$LADCP_lastBin) = split(',',$opt_b);					# select valid bins
   414 	croak("$0: cannot decode -b $opt_b\n")
   451 	croak("$0: cannot decode -b $opt_b\n")
   415     	unless (numberp($LADCP_firstBin) &&
   452     	unless (numberp($LADCP_firstBin) &&
   416         	    ($LADCP_lastBin eq '*' || numberp($LADCP_lastBin)));
   453         	    ($LADCP_lastBin eq '*' || numberp($LADCP_lastBin)));
   417 $processing_options .= " -b $opt_b";
   454 $processing_options .= " -b $opt_b";
   428 		unless numberp($length_of_timelag_windows[0]) && numberp($length_of_timelag_windows[1]);
   465 		unless numberp($length_of_timelag_windows[0]) && numberp($length_of_timelag_windows[1]);
   429 $processing_options .= " -w $opt_w";
   466 $processing_options .= " -w $opt_w";
   430 
   467 
   431 croak("$0: \$out_basename undefined\n")									# plotting routines use this to label the plots
   468 croak("$0: \$out_basename undefined\n")									# plotting routines use this to label the plots
   432 	unless defined($out_basename);
   469 	unless defined($out_basename);
       
   470 &antsAddParams('RDI_Coords::binMapping',$RDI_Coords::binMapping);
   433 &antsAddParams('processing_options',$processing_options);
   471 &antsAddParams('processing_options',$processing_options);
   434 &antsAddParams('out_basename',$out_basename);
   472 &antsAddParams('out_basename',$out_basename);
   435 &antsAddParams('profile_id',$PROF,'run_label',$RUN);
   473 &antsAddParams('profile_id',$PROF,'run_label',$RUN);
   436 
   474 
   437 #----------------------------------------------------------------------
   475 #----------------------------------------------------------------------
   465 	if (defined($out_log)) {
   503 	if (defined($out_log)) {
   466 		print(LOGF "\nWARNING (L$lvl): ");
   504 		print(LOGF "\nWARNING (L$lvl): ");
   467 		printf(LOGF @msg);
   505 		printf(LOGF @msg);
   468 		print(LOGF "\n");
   506 		print(LOGF "\n");
   469 	}
   507 	}
   470 	return if ($opt_v == 0);
   508 	return if ($opt_v == 0) || ($lvl == 0);
   471 
   509 
   472 	if ($opt_v == 1) {
   510 	if ($opt_v == 1) {
   473 		print(STDERR "$LADCP_file: ") if defined($LADCP_file);
   511 		print(STDERR "$LADCP_file: ") if defined($LADCP_file);
   474 		print(STDERR "WARNING (L$lvl): ");
   512 		print(STDERR "WARNING (L$lvl): ");
   475 		printf(STDERR @msg);
   513 		printf(STDERR @msg);
   500 #	- low transmit power
   538 #	- low transmit power
   501 #---------------------------
   539 #---------------------------
   502 
   540 
   503 progress("Reading LADCP data from <$LADCP_file>...\n");
   541 progress("Reading LADCP data from <$LADCP_file>...\n");
   504 readData($LADCP_file,\%LADCP);
   542 readData($LADCP_file,\%LADCP);
   505 progress("\t%d ensembles\n",scalar(@{$LADCP{ENSEMBLE}}));
   543 if ($LADCP{BEAM_COORDINATES}) {
       
   544 	progress("\t%d ensembles (beam coordinates)\n",scalar(@{$LADCP{ENSEMBLE}}));
       
   545 } else {
       
   546 	progress("\t%d ensembles (Earth coordinates)\n",scalar(@{$LADCP{ENSEMBLE}}));
       
   547 }
   506 
   548 
   507 error("$LADCP_file: cannot process multi-ping ensembles\n")
   549 error("$LADCP_file: cannot process multi-ping ensembles\n")
   508 	unless ($LADCP{PINGS_PER_ENSEMBLE} == 1);
   550 	unless ($LADCP{PINGS_PER_ENSEMBLE} == 1);
   509 warning(2,"$LADCP_file: wide-bandwidth setting\n")
   551 warning(2,"$LADCP_file: wide-bandwidth setting\n")
   510 	if ($LADCP{WIDE_BANDWIDTH});
   552 	if ($LADCP{WIDE_BANDWIDTH});
   546 			   'ADCP_blanking_distance',$LADCP{BLANKING_DISTANCE});
   588 			   'ADCP_blanking_distance',$LADCP{BLANKING_DISTANCE});
   547 
   589 
   548 #------------------------------------------------------------
   590 #------------------------------------------------------------
   549 # Edit beam-velocity data
   591 # Edit beam-velocity data
   550 #	0) beam-vel mask on -m
   592 #	0) beam-vel mask on -m
       
   593 #		mask file has three columns: from_ens to_ens ignore_beam
   551 #	1) correlation threshold
   594 #	1) correlation threshold
   552 #------------------------------------------------------------
   595 #------------------------------------------------------------
   553 
   596 
   554 if ($LADCP{BEAM_COORDINATES}) {
   597 if ($LADCP{BEAM_COORDINATES}) {
   555 	progress("Editing beam-velocity data...\n");
   598 	progress("Editing beam-velocity data...\n");
   594 		$nvv += countValidBeamVels($ens);
   637 		$nvv += countValidBeamVels($ens);
   595 		$cte += editCorr($ens,$opt_c);
   638 		$cte += editCorr($ens,$opt_c);
   596 	}
   639 	}
   597 	error("$LADCP_file: no valid data\n") unless ($nvv > 0);
   640 	error("$LADCP_file: no valid data\n") unless ($nvv > 0);
   598 	progress("\tcorrelation threshold (-c %d counts): %d velocites removed (%d%% of total)\n",$opt_c,$cte,round(100*$cte/$nvv));
   641 	progress("\tcorrelation threshold (-c %d counts): %d velocites removed (%d%% of total)\n",$opt_c,$cte,round(100*$cte/$nvv));
   599 #	progress("\tattitude threshold (-t %d deg): %d velocites removed (%d%% of total)\n",$opt_t,$pte,round(100*$pte/$nvv));
   642 } else { # if BEAM_COORDINATES
   600 } else {
       
   601 	progress("Editing velocity data...\n");
   643 	progress("Editing velocity data...\n");
   602 	error("$LADCP_file: cannot apply beamvel-mask $opt_m to earth-coordinate data\n")
   644 	error("$LADCP_file: cannot apply beamvel-mask $opt_m to earth-coordinate data\n")
   603 		if defined($opt_m);
   645 		if defined($opt_m);
   604 	$nvv = $cte = 0;
   646 	$nvv = $cte = 0;
   605 	for ($ens=0; $ens<=$#{$LADCP{ENSEMBLE}}; $ens++) {
   647 	for ($ens=0; $ens<=$#{$LADCP{ENSEMBLE}}; $ens++) {
   606 		$nvv += countValidBeamVels($ens);
   648 		$nvv += countValidBeamVels($ens);
   607 		$cte += editCorr_Earthcoords($ens,$opt_c);
   649 		$cte += editCorr_Earthcoords($ens,$opt_c);
   608 	}
   650 	}
   609 	error("$LADCP_file: no valid data\n") unless ($nvv > 0);
   651 	error("$LADCP_file: no valid data\n") unless ($nvv > 0);
   610 	progress("\tcorrelation threshold (-c %d counts): %d velocites removed (%d%% of total)\n",$opt_c,$cte,round(100*$cte/$nvv));
   652 	progress("\tcorrelation threshold (-c %d counts): %d velocites removed (%d%% of total)\n",$opt_c,$cte,round(100*$cte/$nvv));
   611 #	progress("\tattitude threshold (-t %d deg): %d velocites removed (%d%% of total)\n",$opt_t,$pte,round(100*$pte/$nvv));
       
   612 }
   653 }
   613 
   654 
   614 #-------------------------------------------------------------------
   655 #-------------------------------------------------------------------
   615 # Calculate earth velocities
   656 # Calculate earth velocities
   616 #	- this is done for all bins (not just valid ones), to allow
   657 #	- this is done for all bins (not just valid ones), to allow
   628 		progress("\tdiscarding velocities from beam $bad_beam\n");
   669 		progress("\tdiscarding velocities from beam $bad_beam\n");
   629 		&antsAddParams('bad_beam_discarded',$bad_beam);
   670 		&antsAddParams('bad_beam_discarded',$bad_beam);
   630 	}
   671 	}
   631 	$nvw = 0;
   672 	$nvw = 0;
   632 	for ($ens=0; $ens<=$#{$LADCP{ENSEMBLE}}; $ens++) {
   673 	for ($ens=0; $ens<=$#{$LADCP{ENSEMBLE}}; $ens++) {
       
   674 		$LADCP{ENSEMBLE}[$ens]->{GIMBAL_PITCH} =
       
   675 		 	gimbal_pitch($LADCP{ENSEMBLE}[$ens]->{PITCH},$LADCP{ENSEMBLE}[$ens]->{ROLL});
       
   676 
   633 		for (my($bin)=$LADCP_firstBin-1; $bin<=$LADCP_lastBin-1; $bin++) {
   677 		for (my($bin)=$LADCP_firstBin-1; $bin<=$LADCP_lastBin-1; $bin++) {
   634 			if ($bad_beam) {
   678 			if ($bad_beam) {
   635 				undef($LADCP{ENSEMBLE}[$ens]->{VELOCITY}[$bin][$bad_beam-1]);
   679 				undef($LADCP{ENSEMBLE}[$ens]->{VELOCITY}[$bin][$bad_beam-1]);
   636 				undef($LADCP{ENSEMBLE}[$ens]->{BT_VELOCITY}[$bin][$bad_beam-1]);
   680 				undef($LADCP{ENSEMBLE}[$ens]->{BT_VELOCITY}[$bin][$bad_beam-1]);
   637 			}
   681 			}
   638 			($LADCP{ENSEMBLE}[$ens]->{U}[$bin],
   682 			($LADCP{ENSEMBLE}[$ens]->{INTERP_U}[$bin],
   639 			 $LADCP{ENSEMBLE}[$ens]->{V}[$bin],
   683 			 $LADCP{ENSEMBLE}[$ens]->{INTERP_V}[$bin],
   640 			 $LADCP{ENSEMBLE}[$ens]->{W}[$bin],
   684 			 $LADCP{ENSEMBLE}[$ens]->{INTERP_W}[$bin],
   641 			 $LADCP{ENSEMBLE}[$ens]->{ERRVEL}[$bin]) =
   685 			 $LADCP{ENSEMBLE}[$ens]->{INTERP_ERRVEL}[$bin]) = earthVels(\%LADCP,$ens,$bin);
   642 				velBeamToEarth(\%LADCP,$ens,@{$LADCP{ENSEMBLE}[$ens]->{VELOCITY}[$bin]});
   686 			($LADCP{ENSEMBLE}[$ens]->{V12}[$bin],$LADCP{ENSEMBLE}[$ens]->{W12}[$bin],
       
   687 			 $LADCP{ENSEMBLE}[$ens]->{V34}[$bin],$LADCP{ENSEMBLE}[$ens]->{W34}[$bin]) = BPEarthVels(\%LADCP,$ens,$bin);
       
   688 		}
       
   689 
       
   690 		for (my($bin)=$LADCP_firstBin-1; $bin<=$LADCP_lastBin-1; $bin++) {
       
   691 			$LADCP{ENSEMBLE}[$ens]->{U}[$bin] = $LADCP{ENSEMBLE}[$ens]->{INTERP_U}[$bin];
       
   692 			$LADCP{ENSEMBLE}[$ens]->{V}[$bin] = $LADCP{ENSEMBLE}[$ens]->{INTERP_V}[$bin];
       
   693 			$LADCP{ENSEMBLE}[$ens]->{W}[$bin] = $LADCP{ENSEMBLE}[$ens]->{INTERP_W}[$bin];
       
   694 			$LADCP{ENSEMBLE}[$ens]->{ERRVEL}[$bin] = $LADCP{ENSEMBLE}[$ens]->{INTERP_ERRVEL}[$bin];
       
   695 			undef($LADCP{ENSEMBLE}[$ens]->{INTERP_U}[$bin]);
       
   696 			undef($LADCP{ENSEMBLE}[$ens]->{INTERP_V}[$bin]);
       
   697 			undef($LADCP{ENSEMBLE}[$ens]->{INTERP_W}[$bin]);
       
   698 			undef($LADCP{ENSEMBLE}[$ens]->{INTERP_ERRVEL}[$bin]);
       
   699 
   643 			if (defined($LADCP{ENSEMBLE}[$ens]->{W}[$bin])) {
   700 			if (defined($LADCP{ENSEMBLE}[$ens]->{W}[$bin])) {
   644 				$per_bin_nsamp[$bin]++;
   701 				$per_bin_nsamp[$bin]++;
   645 				$nvw++;
   702 				$nvw++;
   646 			}
   703 			}
   647 			$LADCP{ENSEMBLE}[$ens]->{GIMBAL_PITCH} =
   704 		
   648 			 	gimbal_pitch($LADCP{ENSEMBLE}[$ens]->{PITCH},$LADCP{ENSEMBLE}[$ens]->{ROLL});
       
   649 			$LADCP{ENSEMBLE}[$ens]->{U_UNEDITED}[$bin] = $LADCP{ENSEMBLE}[$ens]->{U}[$bin];
   705 			$LADCP{ENSEMBLE}[$ens]->{U_UNEDITED}[$bin] = $LADCP{ENSEMBLE}[$ens]->{U}[$bin];
   650 			$LADCP{ENSEMBLE}[$ens]->{V_UNEDITED}[$bin] = $LADCP{ENSEMBLE}[$ens]->{V}[$bin];
   706 			$LADCP{ENSEMBLE}[$ens]->{V_UNEDITED}[$bin] = $LADCP{ENSEMBLE}[$ens]->{V}[$bin];
   651 			$LADCP{ENSEMBLE}[$ens]->{W_UNEDITED}[$bin] = $LADCP{ENSEMBLE}[$ens]->{W}[$bin];
   707 			$LADCP{ENSEMBLE}[$ens]->{W_UNEDITED}[$bin] = $LADCP{ENSEMBLE}[$ens]->{W}[$bin];
   652 			
       
   653 			($LADCP{ENSEMBLE}[$ens]->{V12}[$bin],$LADCP{ENSEMBLE}[$ens]->{W12}[$bin],
       
   654 			 $LADCP{ENSEMBLE}[$ens]->{V34}[$bin],$LADCP{ENSEMBLE}[$ens]->{W34}[$bin]) =
       
   655 			 	velBeamToBPEarth(\%LADCP,$ens,@{$LADCP{ENSEMBLE}[$ens]->{VELOCITY}[$bin]});
       
   656 		}
   708 		}
   657 	}
   709 	}
   658 	progress("\t$nvw valid velocities in bins $LADCP_firstBin-$LADCP_lastBin\n");
   710 	progress("\t$nvw valid velocities in bins $LADCP_firstBin-$LADCP_lastBin\n");
   659 	progress("\t3-beam solutions : $RDI_Coords::threeBeam_1 " .
   711 	progress("\t3-beam solutions : $RDI_Coords::threeBeam_1 " .
   660 								  "$RDI_Coords::threeBeam_2 " .
   712 								  "$RDI_Coords::threeBeam_2 " .
   663 	    unless ($opt_4);
   715 	    unless ($opt_4);
   664 } else { # Earth Coordinates
   716 } else { # Earth Coordinates
   665 	progress("Counting valid vertical velocities...\n");
   717 	progress("Counting valid vertical velocities...\n");
   666 	$nvw = 0;
   718 	$nvw = 0;
   667 	for ($ens=0; $ens<=$#{$LADCP{ENSEMBLE}}; $ens++) {
   719 	for ($ens=0; $ens<=$#{$LADCP{ENSEMBLE}}; $ens++) {
       
   720 		$LADCP{ENSEMBLE}[$ens]->{GIMBAL_PITCH} =
       
   721 		 	gimbal_pitch($LADCP{ENSEMBLE}[$ens]->{PITCH},$LADCP{ENSEMBLE}[$ens]->{ROLL});
   668 		for (my($bin)=$LADCP_firstBin-1; $bin<=$LADCP_lastBin-1; $bin++) {
   722 		for (my($bin)=$LADCP_firstBin-1; $bin<=$LADCP_lastBin-1; $bin++) {
   669 			($LADCP{ENSEMBLE}[$ens]->{U}[$bin],
   723 			($LADCP{ENSEMBLE}[$ens]->{U}[$bin],
   670 			 $LADCP{ENSEMBLE}[$ens]->{V}[$bin],
   724 			 $LADCP{ENSEMBLE}[$ens]->{V}[$bin],
   671 			 $LADCP{ENSEMBLE}[$ens]->{W}[$bin],
   725 			 $LADCP{ENSEMBLE}[$ens]->{W}[$bin],
   672 			 $LADCP{ENSEMBLE}[$ens]->{ERRVEL}[$bin]) = @{$LADCP{ENSEMBLE}[$ens]->{VELOCITY}[$bin]};
   726 			 $LADCP{ENSEMBLE}[$ens]->{ERRVEL}[$bin]) = @{$LADCP{ENSEMBLE}[$ens]->{VELOCITY}[$bin]};
   679 			$LADCP{ENSEMBLE}[$ens]->{W_UNEDITED}[$bin] = $LADCP{ENSEMBLE}[$ens]->{W}[$bin];
   733 			$LADCP{ENSEMBLE}[$ens]->{W_UNEDITED}[$bin] = $LADCP{ENSEMBLE}[$ens]->{W}[$bin];
   680 
   734 
   681 			$LADCP{ENSEMBLE}[$ens]->{V12}[$bin] = $LADCP{ENSEMBLE}[$ens]->{V34}[$bin] = nan;
   735 			$LADCP{ENSEMBLE}[$ens]->{V12}[$bin] = $LADCP{ENSEMBLE}[$ens]->{V34}[$bin] = nan;
   682 
   736 
   683 			# for 3-beam solutions, the following code sets w12 and w34 equal to w
   737 			# for 3-beam solutions, the following code sets w12 and w34 equal to w
   684 			my($delta) = $LADCP{ENSEMBLE}[$ens]->{ERRVEL}[$bin] * sqrt(2)/2 * tan(rad($LADCP{BEAM_ANGLE}));
   738 			my($delta) = $LADCP{ENSEMBLE}[$ens]->{ERRVEL}[$bin] / sqrt(2) / tan(rad($LADCP{BEAM_ANGLE}));
   685 			$LADCP{ENSEMBLE}[$ens]->{W12}[$bin] = $LADCP{ENSEMBLE}[$ens]->{W}[$bin] - $delta;
   739 			$LADCP{ENSEMBLE}[$ens]->{W12}[$bin] = $LADCP{ENSEMBLE}[$ens]->{W}[$bin] + $delta/2;
   686 			$LADCP{ENSEMBLE}[$ens]->{W34}[$bin] = $LADCP{ENSEMBLE}[$ens]->{W}[$bin] + $delta; 
   740 			$LADCP{ENSEMBLE}[$ens]->{W34}[$bin] = $LADCP{ENSEMBLE}[$ens]->{W}[$bin] - $delta/2; 
   687 		}
   741 		}
   688 	}
   742 	}
   689 	progress("\t$nvw valid velocities in bins $LADCP_firstBin-$LADCP_lastBin\n");
   743 	progress("\t$nvw valid velocities in bins $LADCP_firstBin-$LADCP_lastBin\n");
   690 }
   744 }
   691 
   745 
   842 undef($antsOldHeaders);
   896 undef($antsOldHeaders);
   843 
   897 
   844 &antsAddParams('lat',$P{lat}) if defined($P{lat});
   898 &antsAddParams('lat',$P{lat}) if defined($P{lat});
   845 &antsAddParams('lon',$P{lon}) if defined($P{lon});
   899 &antsAddParams('lon',$P{lon}) if defined($P{lon});
   846 
   900 
   847 ($CTD_elapsed,$CTD_depth,$CTD_svel,$CTD_w) = &fnr('elapsed','depth','ss','w');
   901 ($CTD_elapsed,$CTD_depth,$CTD_svel) = &fnr('elapsed','depth','ss');
   848 $CTD_temp = &fnrNoErr('temp');
   902 $CTD_w 	  		= &fnrNoErr('w_CTD');
       
   903 $CTD_w	  		= &fnr('w') unless defined($CTD_w);
       
   904 $CTD_winchvel 	= &fnrNoErr('w_winch');
       
   905 $CTD_temp 		= &fnrNoErr('temp');
   849 warning(0,"no CTD temperature --- using ADCP temperature instead => Sv degraded!\n",$s)
   906 warning(0,"no CTD temperature --- using ADCP temperature instead => Sv degraded!\n",$s)
   850    unless defined($CTD_temp);
   907    unless defined($CTD_temp);
   851 
   908 
   852 $CTD_maxdepth = -1;
   909 $CTD_maxdepth = -1;
   853 do {																		# read data
   910 do {																		# read data
   855 		unless &antsNumbers($CTD_elapsed);
   912 		unless &antsNumbers($CTD_elapsed);
   856 	push(@{$CTD{ELAPSED}},$ants_[0][$CTD_elapsed]);
   913 	push(@{$CTD{ELAPSED}},$ants_[0][$CTD_elapsed]);
   857 	push(@{$CTD{DEPTH}},  $ants_[0][$CTD_depth]);
   914 	push(@{$CTD{DEPTH}},  $ants_[0][$CTD_depth]);
   858 	push(@{$CTD{SVEL}},   $ants_[0][$CTD_svel]);
   915 	push(@{$CTD{SVEL}},   $ants_[0][$CTD_svel]);
   859 	push(@{$CTD{W}},      $ants_[0][$CTD_w]);
   916 	push(@{$CTD{W}},      $ants_[0][$CTD_w]);
   860 	push(@{$CTD{TEMP}},	  $ants_[0][$CTD_temp]) if defined($CTD_temp);
   917 	push(@{$CTD{TEMP}},	  $ants_[0][$CTD_temp]) 	if defined($CTD_temp);
       
   918 	push(@{$CTD{W_WINCH}},$ants_[0][$CTD_winchvel]) if defined($CTD_winchvel);
   861 	if ($ants_[0][$CTD_depth] > $CTD_maxdepth) {
   919 	if ($ants_[0][$CTD_depth] > $CTD_maxdepth) {
   862 		$CTD_maxdepth = $ants_[0][$CTD_depth];
   920 		$CTD_maxdepth = $ants_[0][$CTD_depth];
   863 		$CTD_atbottom = $#{$CTD{DEPTH}};
   921 		$CTD_atbottom = $#{$CTD{DEPTH}};
   864 	}
   922 	}
   865 } while (&antsIn());
   923 } while (&antsIn());
  1089 	
  1147 	
  1090 if ($nWsq > 0 && $nWsqI > 0) {
  1148 if ($nWsq > 0 && $nWsqI > 0) {
  1091 	&antsAddParams('rms_w_reflr_err',sqrt($sumWsq/$nWsq),'rms_w_reflr_err_interior',sqrt($sumWsqI/$nWsqI));
  1149 	&antsAddParams('rms_w_reflr_err',sqrt($sumWsq/$nWsq),'rms_w_reflr_err_interior',sqrt($sumWsqI/$nWsqI));
  1092 	progress("\t%.2f cm/s rms reference-layer w_ocean, %.2f cm/s away from boundaries\n",
  1150 	progress("\t%.2f cm/s rms reference-layer w_ocean, %.2f cm/s away from boundaries\n",
  1093 						100*sqrt($sumWsq/$nWsq),100*sqrt($sumWsqI/$nWsqI));
  1151 						100*sqrt($sumWsq/$nWsq),100*sqrt($sumWsqI/$nWsqI));
  1094 #	if (sqrt($sumWsqI/$nWsqI) > 0.05) {
  1152 	if (sqrt($sumWsqI/$nWsqI) > 0.05) {
  1095 #		warning(0,"%.2f cm/s (large) reference-layer w_ocean away from boundaries\n",100*sqrt($sumWsqI/$nWsqI));
  1153 		warning(0,"%.2f cm/s (large) reference-layer w_ocean away from boundaries\n",100*sqrt($sumWsqI/$nWsqI));
  1096 #	} els
  1154 	} elsif (sqrt($sumWsqI/$nWsqI) > 0.15) {
  1097 	if (sqrt($sumWsqI/$nWsqI) > 0.15) {
       
  1098 		warning(2,"%.2f cm/s (implausibly large) reference-layer w_ocean away from boundaries\n",100*sqrt($sumWsqI/$nWsqI));
  1155 		warning(2,"%.2f cm/s (implausibly large) reference-layer w_ocean away from boundaries\n",100*sqrt($sumWsqI/$nWsqI));
  1099 	}
  1156 	}
  1100 } elsif ($nWsq > 0) {
  1157 } elsif ($nWsq > 0) {
  1101 	&antsAddParams('rms_w_reflr_err',sqrt($sumWsq/$nWsq),'rms_w_reflr_err_interior',nan);
  1158 	&antsAddParams('rms_w_reflr_err',sqrt($sumWsq/$nWsq),'rms_w_reflr_err_interior',nan);
  1102 	progress("\t%.2f cm/s rms reference-layer w_ocean\n",100*sqrt($sumWsq/$nWsq));
  1159 	progress("\t%.2f cm/s rms reference-layer w_ocean\n",100*sqrt($sumWsq/$nWsq));
  1109 #----------------------------------------------------------------------
  1166 #----------------------------------------------------------------------
  1110 
  1167 
  1111 progress("Calculating volume-scattering coefficients (Sv)...\n");
  1168 progress("Calculating volume-scattering coefficients (Sv)...\n");
  1112 calc_backscatter_profs($firstGoodEns,$lastGoodEns);
  1169 calc_backscatter_profs($firstGoodEns,$lastGoodEns);
  1113 
  1170 
  1114 if (@nSv) {
  1171 if (defined($Sv_ref_bin) && @nSv) {
  1115 	progress("\tapplying empirical Sv correction\n");
  1172 	progress("\tapplying empirical Sv correction\n");
       
  1173 	&antsAddParams('Sv_correction','empirical');
  1116 	correct_backscatter($firstGoodEns,$lastGoodEns);
  1174 	correct_backscatter($firstGoodEns,$lastGoodEns);
  1117 }
  1175 }
  1118 
  1176 
  1119 #----------------------------------------------------------------------------
  1177 #----------------------------------------------------------------------------
  1120 # Find Seabed & Edit data
  1178 # Find Seabed & Edit data
  1205 	        &antsAddParams('sidelobe_editing','surface+seabed','vessel_draft',$vessel_draft);
  1263 	        &antsAddParams('sidelobe_editing','surface+seabed','vessel_draft',$vessel_draft);
  1206 	    } else {
  1264 	    } else {
  1207 	        &antsAddParams('sidelobe_editing','seabed');
  1265 	        &antsAddParams('sidelobe_editing','seabed');
  1208 	    }
  1266 	    }
  1209 
  1267 
       
  1268 		$PPI_editing |= eval($PPI_seabed_editing_required);
  1210 		if ($PPI_editing) {
  1269 		if ($PPI_editing) {
  1211 			&antsAddParams('PPI_editing','seabed');
  1270 			&antsAddParams('PPI_editing','seabed');
  1212 			&antsAddParams('PPI_extend_upper_limit',$PPI_extend_upper_limit)
  1271 			&antsAddParams('PPI_extend_upper_limit',$PPI_extend_upper_limit)
  1213 				if numberp($PPI_extend_upper_limit);
  1272 				if numberp($PPI_extend_upper_limit);
  1214 			progress("Editing data to remove PPI from seabed...\n");
  1273 			progress("Editing data to remove PPI from seabed...\n");
  1265 }
  1324 }
  1266 
  1325 
  1267 #----------------------------------------------------------------------
  1326 #----------------------------------------------------------------------
  1268 # Data Editing after LADCP and CTD data have been merged
  1327 # Data Editing after LADCP and CTD data have been merged
  1269 #	1) surface layer editing
  1328 #	1) surface layer editing
  1270 #	2) user-supplied $edit_data_hook
  1329 #	2) Execute user-supplied $edit_data_hook
  1271 #----------------------------------------------------------------------
  1330 #----------------------------------------------------------------------
  1272 
  1331 
  1273 progress("Removing data from instrument at surface...\n");
  1332 progress("Removing data from instrument at surface...\n");
  1274 &antsAddParams('surface_layer_depth',$surface_layer_depth);
  1333 &antsAddParams('surface_layer_depth',$surface_layer_depth);
  1275 $nerm = editSurfLayer($firstGoodEns,$lastGoodEns,$surface_layer_depth);
  1334 $nerm = editSurfLayer($firstGoodEns,$lastGoodEns,$surface_layer_depth);
  1319 #	   has only a minute effect
  1378 #	   has only a minute effect
  1320 #---------------------------------------------------------------------------
  1379 #---------------------------------------------------------------------------
  1321 
  1380 
  1322 progress("Creating binned profiles at ${opt_o}m resolution...\n");
  1381 progress("Creating binned profiles at ${opt_o}m resolution...\n");
  1323 
  1382 
  1324 &antsAddParams('outgrid_dz',$opt_o,'outgrid_minsamp',$opt_k);					# used by LADCP_w_regrid
  1383 &antsAddParams('outgrid_dz',$opt_o,'outgrid_minsamp',$opt_k);					# used by LADCP_w_postproc
  1325 &antsAddParams('outgrid_firstbin',$outGrid_firstBin,'outgrid_lastbin',$outGrid_lastBin);
  1384 &antsAddParams('outgrid_firstbin',$outGrid_firstBin,'outgrid_lastbin',$outGrid_lastBin);
  1326 
  1385 
  1327 my($min_depth) = 9e99;
  1386 my($min_depth) = 9e99;
  1328 my($max_depth) = 0;
  1387 my($max_depth) = 0;
  1329 local($realLastGoodEns);
  1388 local($realLastGoodEns);
  1469 #	- improves solution but can introduce errors in ensembles with strong outliers => median instead of
  1528 #	- improves solution but can introduce errors in ensembles with strong outliers => median instead of
  1470 #	  mean, and outlier filter above
  1529 #	  mean, and outlier filter above
  1471 #------------------------------------------------------------------------------------------------------
  1530 #------------------------------------------------------------------------------------------------------
  1472 
  1531 
  1473 unless ($opt_q) {
  1532 unless ($opt_q) {
  1474 	progress("Removing ping-coherent residuals...\n");
  1533 	progress("Subtracting ping-coherent residuals...\n");
  1475 	
  1534 	
  1476 	for ($ens=$firstGoodEns; $ens<=$lastGoodEns; $ens++) {
  1535 	for ($ens=$firstGoodEns; $ens<=$lastGoodEns; $ens++) {
  1477 		next unless numberp($LADCP{ENSEMBLE}[$ens]->{CTD_DEPTH});
  1536 		next unless numberp($LADCP{ENSEMBLE}[$ens]->{CTD_DEPTH});
  1478 
  1537 
  1479 		my(@residuals) = ();												# calc median of residuals
  1538 		my(@residuals) = ();												# calc median of residuals
  1537 #----------------------------------------------------------------------
  1596 #----------------------------------------------------------------------
  1538 # remove ensembles with large rms residuals
  1597 # remove ensembles with large rms residuals
  1539 #----------------------------------------------------------------------
  1598 #----------------------------------------------------------------------
  1540 
  1599 
  1541 if (defined($opt_r)) {
  1600 if (defined($opt_r)) {
  1542 	progress("Removing ensembles with large residuals...\n");	
  1601 	progress("Applying residuals filters...\n");	
  1543 	
  1602 	
  1544 	$nerm = 0;
  1603 	progress("\trms residuals > $residuals_rms_max: ");
  1545 	for ($ens=$firstGoodEns; $ens<=$lastGoodEns; $ens++) {
  1604 	my($nerm) = editResiduals_rmsMax($firstGoodEns,$lastGoodEns,$residuals_rms_max);
  1546 		next unless numberp($LADCP{ENSEMBLE}[$ens]->{CTD_DEPTH});
  1605 	progress("$nerm ensembles removed (%d%% of total)\n",round(100*$nerm/($lastGoodEns-$firstGoodEns+1)));
  1547 
  1606 
  1548 		my($sum) = my($n) = 0;														# calculate rms residual
  1607 	if (defined($residuals_delta_max)) {											# filter based on difference between
  1549 		my(@bindepth) = binDepths($ens);
  1608 		progress("\tbeampair residuals difference > $residuals_delta_max [m/s]: ");    
  1550 		for ($bin=$LADCP_firstBin-1; $bin<=$LADCP_lastBin-1; $bin++) {
  1609 		my($nvrm) = editResiduals_deltaMax($firstGoodEns,$lastGoodEns,$residuals_delta_max);
  1551 			next unless ($bin+1>=$outGrid_firstBin && $bin+1<=$outGrid_lastBin);
  1610         progress("$nvrm velocities removed (%d%% of total in bins $LADCP_firstBin-$LADCP_lastBin)\n",round(100*$nvrm/$nvw));
  1552 		  	next unless numberp($LADCP{ENSEMBLE}[$ens]->{W}[$bin]);
  1611 	}
  1553 		  	my($bi) = $bindepth[$bin]/$opt_o;
       
  1554 			my($res) = ($ens < $LADCP_atbottom) ? 
       
  1555 						$LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W}[$bin] - $DNCAST{MEDIAN_W}[$bi] :
       
  1556 						$LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W}[$bin] - $UPCAST{MEDIAN_W}[$bi];
       
  1557 			$sum += &SQR($res); $n++;						
       
  1558 		}
       
  1559 
       
  1560 		if ($n == 0 || sqrt($sum/$n) > $opt_r) {									# ensemble is bad
       
  1561 			undef($LADCP{ENSEMBLE}[$ens]->{CTD_DEPTH});
       
  1562 			$nerm++;
       
  1563 		}
       
  1564 	}
       
  1565 	progress("\t$nerm ensembles removed (%d%% of total)\n",round(100*$nerm/($lastGoodEns-$firstGoodEns+1)));
       
  1566 
  1612 
  1567     progress("\tre-binning profile data...\n");
  1613     progress("\tre-binning profile data...\n");
  1568     undef(%DNCAST); undef(%UPCAST);
  1614     undef(%DNCAST); undef(%UPCAST);
  1569 	$min_depth = 9e99; my($max_depth) = 0;
  1615 	$min_depth = 9e99; my($max_depth) = 0;
  1570 	for ($ens=$firstGoodEns; $ens<$LADCP_atbottom; $ens++) {						# downcast
  1616 	for ($ens=$firstGoodEns; $ens<$LADCP_atbottom; $ens++) {						# downcast
  1805 
  1851 
  1806 if (@out_wsamp) {
  1852 if (@out_wsamp) {
  1807 	progress("Writing vertical-velocity data to ");
  1853 	progress("Writing vertical-velocity data to ");
  1808 	@antsNewLayout = ('ensemble','bin','elapsed','depth','CTD_depth','downcast',
  1854 	@antsNewLayout = ('ensemble','bin','elapsed','depth','CTD_depth','downcast',
  1809 					  'w','w12','w34','v12','v34','residual','residual12','residual34',
  1855 					  'w','w12','w34','v12','v34','residual','residual12','residual34',
  1810 					  'CTD_w','CTD_w_t','CTD_w_tt','LADCP_w',
  1856 					  'CTD_w','CTD_w_t','CTD_w_tt','LADCP_w','LADCP_reflr_w','winch_w',
  1811 					  'errvel','correlation','echo_amplitude','Sv',
  1857 					  'errvel','correlation','echo_amplitude','Sv',
  1812 					  'pitch','roll','tilt','heading','3_beam','svel');
  1858 					  'pitch','roll','tilt','heading','3_beam','svel');
  1813 
  1859 
  1814 	foreach my $of (@out_wsamp) {
  1860 	foreach my $of (@out_wsamp) {
  1815 	    progress("<$of> ");
  1861 	    progress("<$of> ");
  1844 				  $LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W34}[$bin] - $DNCAST{MEDIAN_W}[$bi],
  1890 				  $LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W34}[$bin] - $DNCAST{MEDIAN_W}[$bi],
  1845 				  $CTD{W}[$LADCP{ENSEMBLE}[$ens]->{CTD_SCAN}],
  1891 				  $CTD{W}[$LADCP{ENSEMBLE}[$ens]->{CTD_SCAN}],
  1846 				  $CTD{W_t}[$LADCP{ENSEMBLE}[$ens]->{CTD_SCAN}],
  1892 				  $CTD{W_t}[$LADCP{ENSEMBLE}[$ens]->{CTD_SCAN}],
  1847 				  $CTD{W_tt}[$LADCP{ENSEMBLE}[$ens]->{CTD_SCAN}],
  1893 				  $CTD{W_tt}[$LADCP{ENSEMBLE}[$ens]->{CTD_SCAN}],
  1848 				  $LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_W}[$bin],
  1894 				  $LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_W}[$bin],
       
  1895 				  $LADCP{ENSEMBLE}[$ens]->{REFLR_W},
       
  1896 				  $CTD{W_WINCH}[$LADCP{ENSEMBLE}[$ens]->{CTD_SCAN}],
  1849 				  $LADCP{ENSEMBLE}[$ens]->{ERRVEL}[$bin],
  1897 				  $LADCP{ENSEMBLE}[$ens]->{ERRVEL}[$bin],
  1850 				  median(@{$LADCP{ENSEMBLE}[$ens]->{CORRELATION}[$bin]}),
  1898 				  median(@{$LADCP{ENSEMBLE}[$ens]->{CORRELATION}[$bin]}),
  1851 				  median(@{$LADCP{ENSEMBLE}[$ens]->{ECHO_AMPLITUDE}[$bin]}),
  1899 				  median(@{$LADCP{ENSEMBLE}[$ens]->{ECHO_AMPLITUDE}[$bin]}),
  1852 				  $LADCP{ENSEMBLE}[$ens]->{SV}[$bin],
  1900 				  $LADCP{ENSEMBLE}[$ens]->{SV}[$bin],
  1853 				  $LADCP{ENSEMBLE}[$ens]->{GIMBAL_PITCH},
  1901 				  $LADCP{ENSEMBLE}[$ens]->{GIMBAL_PITCH},
  1882 				  $LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W34}[$bin] - $UPCAST{MEDIAN_W}[$bi],
  1930 				  $LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_OCEAN_W34}[$bin] - $UPCAST{MEDIAN_W}[$bi],
  1883 				  $CTD{W}[$LADCP{ENSEMBLE}[$ens]->{CTD_SCAN}],
  1931 				  $CTD{W}[$LADCP{ENSEMBLE}[$ens]->{CTD_SCAN}],
  1884 				  $CTD{W_t}[$LADCP{ENSEMBLE}[$ens]->{CTD_SCAN}],
  1932 				  $CTD{W_t}[$LADCP{ENSEMBLE}[$ens]->{CTD_SCAN}],
  1885 				  $CTD{W_tt}[$LADCP{ENSEMBLE}[$ens]->{CTD_SCAN}],
  1933 				  $CTD{W_tt}[$LADCP{ENSEMBLE}[$ens]->{CTD_SCAN}],
  1886 				  $LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_W}[$bin],
  1934 				  $LADCP{ENSEMBLE}[$ens]->{SSCORRECTED_W}[$bin],
       
  1935 				  $LADCP{ENSEMBLE}[$ens]->{REFLR_W},
       
  1936 				  $CTD{W_WINCH}[$LADCP{ENSEMBLE}[$ens]->{CTD_SCAN}],
  1887 				  $LADCP{ENSEMBLE}[$ens]->{ERRVEL}[$bin],
  1937 				  $LADCP{ENSEMBLE}[$ens]->{ERRVEL}[$bin],
  1888 				  median(@{$LADCP{ENSEMBLE}[$ens]->{CORRELATION}[$bin]}),
  1938 				  median(@{$LADCP{ENSEMBLE}[$ens]->{CORRELATION}[$bin]}),
  1889 				  median(@{$LADCP{ENSEMBLE}[$ens]->{ECHO_AMPLITUDE}[$bin]}),
  1939 				  median(@{$LADCP{ENSEMBLE}[$ens]->{ECHO_AMPLITUDE}[$bin]}),
  1890 				  $LADCP{ENSEMBLE}[$ens]->{SV}[$bin],
  1940 				  $LADCP{ENSEMBLE}[$ens]->{SV}[$bin],
  1891 				  $LADCP{ENSEMBLE}[$ens]->{GIMBAL_PITCH},
  1941 				  $LADCP{ENSEMBLE}[$ens]->{GIMBAL_PITCH},