plot_attitude_residuals.pl
author A.M. Thurnherr <athurnherr@yahoo.com>
Fri, 05 Aug 2016 11:02:51 -0400
changeset 47 2ccb81b7cea5
parent 46 cc6c4309828a
permissions -rw-r--r--
version found on whoosher after repair

#======================================================================
#                    P L O T _ A T T I T U D E _ R E S I D U A L S . P L 
#                    doc: Sun May 15 16:08:59 2016
#                    dlm: Wed Jun  8 22:12:19 2016
#                    (c) 2016 A.M. Thurnherr
#                    uE-Info: 92 0 NIL 0 0 72 2 2 4 NIL ofnI
#======================================================================

# HISTORY:
#	May 15, 2016: - created from [plot_mean_residuals.pl]
#	May 16, 2016: - continued
#	May 17, 2016: - changed from w{12,34} to residual{12,34}
#				  - added pitch/roll means
#	May 18, 2016: - added version
#                 - expunged $realLastGoodEns
#	May 19, 2016: - added notes about beam planes
#   May 24, 2016: - calc_binDepths() -> binDepths()
#   Jun  8, 2016: - adapted to correct tilt axis

# IMPORTANT NOTE:
#   - the variables prefixed with p/r refer to beam-pairs 1,2 and 3,4 respectively,
#     i.e. the p variables correspond to the roll plane and the r variables
#     correspond to the pitch plane. This is confusing.

require "$ANTS/libGMT.pl";

sub plot_attitude_residuals($)
{
	my($pfn) = @_;																	# plot file name

	my($xmin) = -round($opt_t);														# full tilt range 
	my($xmax) =  round($opt_t);
	my($ymin) =  -0.03;
	my($ymax) =   0.03;

	my($min_thin) = 200;
	my($min_fat)  = 500;
	my($btstrp_ndraw) = 20;
	my($excluded_surf_layer) = 150;
	my($hist_height)  = 0.015;

	#-------------------------------------------------------
	# Bin-Average & Create Histogram from Beampair Residuals 
	#	- use 1-degree bins for simplicity
	#	- use gimbal pitch (not RDI pitch)
	#	- also calculate mean/rms pitch
	#-------------------------------------------------------

	my(@pHistDC,@rHistDC,@pSumDC,@rSumDC,$pHistDC,$rHistDC,$pSumDC,$rSumDC);
	my(@pHistUC,@rHistUC,@pSumUC,@rSumUC,$pHistUC,$rHistUC,$pSumUC,$rSumUC);
	my(@pValsDC,@rValsDC,@pValsUC,@rValsUC,$mode);
	my(@pitchSumDC,@rollSumDC,@pitchSumUC,@rollSumUC);
	for (my($e)=$firstGoodEns; $e<=$lastGoodEns; $e++) {
		next unless numberp($LADCP{ENSEMBLE}[$e]->{CTD_DEPTH});
		my(@bindepth) = binDepths($e);

		for (my($bin)=$LADCP_firstBin-1; $bin<=$LADCP_lastBin-1; $bin++) {
			next if ($bindepth[$bin] <= $excluded_surf_layer);
			next unless ($bin+1>=$outGrid_firstBin && $bin+1<=$outGrid_lastBin);
			next unless numberp($LADCP{ENSEMBLE}[$e]->{SSCORRECTED_OCEAN_W12}[$bin]) &&
						numberp($LADCP{ENSEMBLE}[$e]->{SSCORRECTED_OCEAN_W34}[$bin]);

			my($ri) = int($LADCP{ENSEMBLE}[$e]->{GIMBAL_PITCH}+$opt_t);							# pitch/roll indices
			my($pi) = int($LADCP{ENSEMBLE}[$e]->{ROLL}+$opt_t);
			my($bi) = $bindepth[$bin]/$opt_o;

			if ($e < $LADCP_atbottom) {															# downcast
				$pitchSumDC  += $LADCP{ENSEMBLE}[$e]->{GIMBAL_PITCH};	$pHistDC++; 
				$rollSumDC += $LADCP{ENSEMBLE}[$e]->{ROLL};				$rHistDC++;
				$pSumDC += $LADCP{ENSEMBLE}[$e]->{SSCORRECTED_OCEAN_W12}[$bin] - $DNCAST{MEDIAN_W}[$bi]; 
				$rSumDC += $LADCP{ENSEMBLE}[$e]->{SSCORRECTED_OCEAN_W34}[$bin] - $DNCAST{MEDIAN_W}[$bi]; 
			 	push(@{$pValsDC[$pi]},$LADCP{ENSEMBLE}[$e]->{SSCORRECTED_OCEAN_W12}[$bin] - $DNCAST{MEDIAN_W}[$bi]);
			 	push(@{$rValsDC[$ri]},$LADCP{ENSEMBLE}[$e]->{SSCORRECTED_OCEAN_W34}[$bin] - $DNCAST{MEDIAN_W}[$bi]);
				$pSumDC[$pi] += $LADCP{ENSEMBLE}[$e]->{SSCORRECTED_OCEAN_W12}[$bin] - $DNCAST{MEDIAN_W}[$bi]; $pHistDC[$pi]++; 
				$rSumDC[$ri] += $LADCP{ENSEMBLE}[$e]->{SSCORRECTED_OCEAN_W34}[$bin] - $DNCAST{MEDIAN_W}[$bi]; $rHistDC[$ri]++;
				$mode = $pHistDC[$pi] if ($pHistDC[$pi] > $mode);
				$mode = $rHistDC[$ri] if ($rHistDC[$ri] > $mode);
			} else { 																			# upcast
				$pitchSumUC += $LADCP{ENSEMBLE}[$e]->{GIMBAL_PITCH};	$pHistUC++; 
				$rollSumUC  += $LADCP{ENSEMBLE}[$e]->{ROLL};			$rHistUC++;
				$pSumUC += $LADCP{ENSEMBLE}[$e]->{SSCORRECTED_OCEAN_W12}[$bin] - $UPCAST{MEDIAN_W}[$bi]; 
				$rSumUC += $LADCP{ENSEMBLE}[$e]->{SSCORRECTED_OCEAN_W34}[$bin] - $UPCAST{MEDIAN_W}[$bi];
			 	push(@{$pValsUC[$pi]},$LADCP{ENSEMBLE}[$e]->{SSCORRECTED_OCEAN_W12}[$bin] - $UPCAST{MEDIAN_W}[$bi]);
			 	push(@{$rValsUC[$ri]},$LADCP{ENSEMBLE}[$e]->{SSCORRECTED_OCEAN_W34}[$bin] - $UPCAST{MEDIAN_W}[$bi]);
				$pSumUC[$pi] += $LADCP{ENSEMBLE}[$e]->{SSCORRECTED_OCEAN_W12}[$bin] - $UPCAST{MEDIAN_W}[$bi]; $pHistUC[$pi]++; 
				$rSumUC[$ri] += $LADCP{ENSEMBLE}[$e]->{SSCORRECTED_OCEAN_W34}[$bin] - $UPCAST{MEDIAN_W}[$bi]; $rHistUC[$ri]++;
				$mode = $pHistUC[$pi] if ($pHistUC[$pi] > $mode);
				$mode = $rHistUC[$ri] if ($rHistUC[$ri] > $mode);
			}
		}
	}

	#----------
	# Plot Data
	#----------

	my($R) = "-R$xmin/$xmax/$ymin/$ymax";														# plot frame
	GMT_begin($pfn,'-JX10/10',$R,"-P -Bg5f1a5:'Pitch/Roll [\260]':/g0.01f0.001a0.01:'Beam-Plane Residual Vertical Velocity [m/s]':WeSn");

	# ZERO LINE
	GMT_psxy('-W4,CornflowerBlue');
		print(GMT "$xmin 0\n$xmax 0\n");

	# DC BEAMS 1,2
	GMT_psxy('-Ey0.2/2,coral');																	# error bars
		for (my($i)=0; $i<2*round($opt_t); $i++) {
			next unless ($pHistDC[$i] >= $min_fat);
			my($minLim,$maxLim) = &bootstrap($btstrp_ndraw,0.95,\&avg,@{$pValsDC[$i]});			# 95% bootstrap conf limits
			printf(GMT "%f %f %f\n",$i-round($opt_t)-0.3,($maxLim+$minLim)/2,($maxLim-$minLim)/2);
		}
	GMT_psxy('-Ey0.2/1,coral');
		for (my($i)=0; $i<2*round($opt_t); $i++) {
			next unless ($pHistDC[$i]>=$min_thin && $pHistDC[$i]<$min_fat);
			my($minLim,$maxLim) = &bootstrap($btstrp_ndraw,0.95,\&avg,@{$pValsDC[$i]});
			printf(GMT "%f %f %f\n",$i-round($opt_t)-0.3,($maxLim+$minLim)/2,($maxLim-$minLim)/2);
		}
	GMT_psxy('-Sc0.15 -Gcoral');
		for (my($i)=0; $i<2*round($opt_t); $i++) {
			next unless ($pHistDC[$i] >= $min_thin);
			printf(GMT "%f %f\n",$i-round($opt_t)-0.3,$pSumDC[$i]/$pHistDC[$i]);				# errorbar center symbol 
			printf(GMT "%f %f\n",$i-round($opt_t)-0.3,$ymin+$hist_height*$pHistDC[$i]/$mode);	# histogram symbol
		}
	if ($pHistDC) {
		GMT_psxy('-W1,coral,8_2:0');															# averages (lines)
			printf(GMT ">\n%f %f\n%f %f\n",$xmin,$pSumDC/$pHistDC,$xmax,$pSumDC/$pHistDC);		# 	bias
			printf(GMT ">\n%f %f\n%f %f\n",$pitchSumDC/$pHistDC,$ymin,$pitchSumDC/$pHistDC,$ymax);# roll
	}
	GMT_psxy('-W2,coral,8_2:0');
		for (my($i)=0; $i<2*round($opt_t); $i++) {
			next unless ($pHistDC[$i] >= $min_thin);
			printf(GMT ">\n%f %f\n%f %f\n%f %f\n>\n%f %f\n%f %f\n",								# histogram bar
					$i-round($opt_t)-0.3-0.5,$ymin,
					$i-round($opt_t)-0.3-0.5,$ymin+$hist_height*$pHistDC[$i]/$mode,
					$i-round($opt_t)-0.3+0.5,$ymin+$hist_height*$pHistDC[$i]/$mode,
					$i-round($opt_t)-0.3+0.5,$ymin,
					$i-round($opt_t)-0.3+0.5,$ymin+$hist_height*$pHistDC[$i]/$mode);
		}

	# DC BEAMS 3,4
	GMT_psxy('-Ey0.2/2,coral');															
		for (my($i)=0; $i<2*round($opt_t); $i++) {
			next unless ($rHistDC[$i] >= $min_fat);
			my($minLim,$maxLim) = &bootstrap($btstrp_ndraw,0.95,\&avg,@{$rValsDC[$i]});
			printf(GMT "%f %f %f\n",$i-round($opt_t)-0.1,($maxLim+$minLim)/2,($maxLim-$minLim)/2);
		}
	GMT_psxy('-Ey0.2/1,coral');
		for (my($i)=0; $i<2*round($opt_t); $i++) {
			next unless ($rHistDC[$i]>=$min_thin && $rHistDC[$i]<$min_fat);
			my($minLim,$maxLim) = &bootstrap($btstrp_ndraw,0.95,\&avg,@{$rValsDC[$i]});
			printf(GMT "%f %f %f\n",$i-round($opt_t)-0.1,($maxLim+$minLim)/2,($maxLim-$minLim)/2);
		}
	GMT_psxy('-Sx0.25 -W2,coral');
		for (my($i)=0; $i<2*round($opt_t); $i++) {
			next unless ($rHistDC[$i] >= $min_thin);
			printf(GMT "%f %f\n",$i-round($opt_t)-0.1,$rSumDC[$i]/$rHistDC[$i]);
			printf(GMT "%f %f\n",$i-round($opt_t)-0.1,$ymin+$hist_height*$rHistDC[$i]/$mode);
		}
	if ($rHistDC) {
		GMT_psxy('-W1,coral,2_2:0');
			printf(GMT ">\n%f %f\n%f %f\n",$xmin,$rSumDC/$rHistDC,$xmax,$rSumDC/$rHistDC);
			printf(GMT ">\n%f %f\n%f %f\n",$rollSumDC/$rHistDC,$ymin,$rollSumDC/$rHistDC,$ymax);
	}
	GMT_psxy('-W2,coral,2_2:0');
		for (my($i)=0; $i<2*round($opt_t); $i++) {
			next unless ($rHistDC[$i] >= $min_thin);
			printf(GMT ">\n%f %f\n%f %f\n%f %f\n>\n%f %f\n%f %f\n",
					$i-round($opt_t)-0.1-0.5,$ymin,
					$i-round($opt_t)-0.1-0.5,$ymin+$hist_height*$rHistDC[$i]/$mode,
					$i-round($opt_t)-0.1+0.5,$ymin+$hist_height*$rHistDC[$i]/$mode,
					$i-round($opt_t)-0.1+0.5,$ymin,
					$i-round($opt_t)-0.1+0.5,$ymin+$hist_height*$rHistDC[$i]/$mode);
		}

	# UC BEAMS 1,2
	GMT_psxy('-Ey0.2/2,SeaGreen');													
		for (my($i)=0; $i<2*round($opt_t); $i++) {
			next unless ($pHistUC[$i] >= $min_fat);
			my($minLim,$maxLim) = &bootstrap($btstrp_ndraw,0.95,\&avg,@{$pValsUC[$i]});
			printf(GMT "%f %f %f\n",$i-round($opt_t)+0.1,($maxLim+$minLim)/2,($maxLim-$minLim)/2);
		}
	GMT_psxy('-Ey0.2/1,SeaGreen');
		for (my($i)=0; $i<2*round($opt_t); $i++) {
			next unless ($pHistUC[$i]>=$min_thin && $pHistUC[$i]<$min_fat);
			my($minLim,$maxLim) = &bootstrap($btstrp_ndraw,0.95,\&avg,@{$pValsUC[$i]});
			printf(GMT "%f %f %f\n",$i-round($opt_t)+0.1,($maxLim+$minLim)/2,($maxLim-$minLim)/2);
		}
	GMT_psxy('-Sc0.15 -GSeaGreen');
		for (my($i)=0; $i<2*round($opt_t); $i++) {
			next unless ($pHistUC[$i] >= $min_thin);
			printf(GMT "%f %f\n",$i-round($opt_t)+0.1,$pSumUC[$i]/$pHistUC[$i]);
			printf(GMT "%f %f\n",$i-round($opt_t)+0.1,$ymin+$hist_height*$pHistUC[$i]/$mode);
		}
	if ($pHistUC) {
		GMT_psxy('-W1,SeaGreen,8_2:0');
			printf(GMT ">\n%f %f\n%f %f\n",$xmin,$pSumUC/$pHistUC,$xmax,$pSumUC/$pHistUC);
			printf(GMT ">\n%f %f\n%f %f\n",$pitchSumUC/$pHistUC,$ymin,$pitchSumUC/$pHistUC,$ymax);
	}
	GMT_psxy('-W2,SeaGreen,8_2:0');
		for (my($i)=0; $i<2*round($opt_t); $i++) {
			next unless ($pHistUC[$i] >= $min_thin);
			printf(GMT ">\n%f %f\n%f %f\n%f %f\n>\n%f %f\n%f %f\n",
					$i-round($opt_t)+0.1-0.5,$ymin,
					$i-round($opt_t)+0.1-0.5,$ymin+$hist_height*$pHistUC[$i]/$mode,
					$i-round($opt_t)+0.1+0.5,$ymin+$hist_height*$pHistUC[$i]/$mode,
					$i-round($opt_t)+0.1+0.5,$ymin,
					$i-round($opt_t)+0.1+0.5,$ymin+$hist_height*$pHistUC[$i]/$mode);
		}

	# UC BEAMS 3,4
	GMT_psxy('-Ey0.2/2,SeaGreen');													
		for (my($i)=0; $i<2*round($opt_t); $i++) {
			next unless ($rHistUC[$i] >= $min_fat);
			my($minLim,$maxLim) = &bootstrap($btstrp_ndraw,0.95,\&avg,@{$rValsUC[$i]});
			printf(GMT "%f %f %f\n",$i-round($opt_t)+0.3,($maxLim+$minLim)/2,($maxLim-$minLim)/2);
		}
	GMT_psxy('-Ey0.2/1,SeaGreen');													
		for (my($i)=0; $i<2*round($opt_t); $i++) {
			next unless ($rHistUC[$i]>=$min_thin && $rHistUC[$i]<$min_fat);
			my($minLim,$maxLim) = &bootstrap($btstrp_ndraw,0.95,\&avg,@{$rValsUC[$i]});
			printf(GMT "%f %f %f\n",$i-round($opt_t)+0.3,($maxLim+$minLim)/2,($maxLim-$minLim)/2);
		}
	GMT_psxy('-Sx0.25 -W2,SeaGreen');
		for (my($i)=0; $i<2*round($opt_t); $i++) {
			next unless ($rHistUC[$i] >= $min_thin);
			printf(GMT "%f %f\n",$i-round($opt_t)+0.3,$rSumUC[$i]/$rHistUC[$i]);
			printf(GMT "%f %f\n",$i-round($opt_t)+0.3,$ymin+$hist_height*$rHistUC[$i]/$mode);
		}
	if ($rHistUC) {
		GMT_psxy('-W1,SeaGreen,2_2:0');
			printf(GMT ">\n%f %f\n%f %f\n",$xmin,$rSumUC/$rHistUC,$xmax,$rSumUC/$rHistUC);
			printf(GMT ">\n%f %f\n%f %f\n",$rollSumUC/$rHistUC,$ymin,$rollSumUC/$rHistUC,$ymax);
	}
	GMT_psxy('-W2,SeaGreen,2_2:0');
		for (my($i)=0; $i<2*round($opt_t); $i++) {
			next unless ($rHistUC[$i] >= $min_thin);
			printf(GMT ">\n%f %f\n%f %f\n%f %f\n>\n%f %f\n%f %f\n",
					$i-round($opt_t)+0.3-0.5,$ymin,
					$i-round($opt_t)+0.3-0.5,$ymin+$hist_height*$rHistUC[$i]/$mode,
					$i-round($opt_t)+0.3+0.5,$ymin+$hist_height*$rHistUC[$i]/$mode,
					$i-round($opt_t)+0.3+0.5,$ymin,
					$i-round($opt_t)+0.3+0.5,$ymin+$hist_height*$rHistUC[$i]/$mode);
		}

	GMT_unitcoords();																	# LABELS
	GMT_pstext('-F+f9,Helvetica,orange+jTR -N -Gwhite');
        print(GMT "0.99 0.99 V$VERSION\n");
	        
	GMT_pstext('-F+f14,Helvetica,blue+jBL -N');											# profile id
		print(GMT "0.0 1.03 $P{out_basename} $P{run_label}\n");

	GMT_setR($R);																		# FINISH PLOT
	GMT_end();
}

1; # return true on require