LADCP_w_postproc
changeset 49 5006e9158207
parent 47 2ccb81b7cea5
child 56 8f120b9f795a
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 _ P O S T P R O C 
     3 #                    L A D C P _ W _ P O S T P R O C 
     4 #                    doc: Fri Apr 24 17:15:59 2015
     4 #                    doc: Fri Apr 24 17:15:59 2015
     5 #                    dlm: Thu May 26 18:21:11 2016
     5 #                    dlm: Thu Nov  1 10:55:34 2018
     6 #                    (c) 2015 A.M. Thurnherr
     6 #                    (c) 2015 A.M. Thurnherr
     7 #                    uE-Info: 101 35 NIL 0 0 72 2 2 4 NIL ofnI
     7 #                    uE-Info: 71 77 NIL 0 0 72 2 2 4 NIL ofnI
     8 #======================================================================
     8 #======================================================================
     9 
     9 
    10 $antsSummary = 'edit and re-grid LADCP vertical-velocity samples';
    10 $antsSummary = 'edit and re-grid LADCP vertical-velocity samples';
    11 
    11 
    12 # HISTORY:
    12 # HISTORY:
    63 #	Mar 16, 2016: - adapted to gmt5
    63 #	Mar 16, 2016: - adapted to gmt5
    64 #   Mar 31, 2016: - changed version %PARAM
    64 #   Mar 31, 2016: - changed version %PARAM
    65 #	Apr 14, 2016: - added profile id to warning messages
    65 #	Apr 14, 2016: - added profile id to warning messages
    66 #	May 24, 2016: - improved plot
    66 #	May 24, 2016: - improved plot
    67 #	May 26, 2016: - added automatic directory creation on -d
    67 #	May 26, 2016: - added automatic directory creation on -d
       
    68 #	Nov 28, 2017: - removed wcorr plot
       
    69 #	Dec  9, 2017: - added $antsSuppressCommonOptions = 1;
       
    70 #	Oct 31, 2018: - improved label (no longer explained/residual stddev)
       
    71 #	Nov  1, 2018: - made layout consistent for dual- and single-head profiles
       
    72 
    68 
    73 
    69 ($ANTS)  = (`which ANTSlib` =~ m{^(.*)/[^/]*$});
    74 ($ANTS)  = (`which ANTSlib` =~ m{^(.*)/[^/]*$});
    70 ($WCALC) = ($0              =~ m{^(.*)/[^/]*$});
    75 ($WCALC) = ($0              =~ m{^(.*)/[^/]*$});
    71 $WCALC = '.' if ($WCALC eq '');
    76 $WCALC = '.' if ($WCALC eq '');
    72 
    77 
    77 require "$ANTS/ants.pl";
    82 require "$ANTS/ants.pl";
    78 require "$ANTS/libstats.pl";
    83 require "$ANTS/libstats.pl";
    79 require "$ANTS/libGMT.pl";
    84 require "$ANTS/libGMT.pl";
    80 &antsAddParams('LADCP_w_postproc::version',$VERSION);
    85 &antsAddParams('LADCP_w_postproc::version',$VERSION);
    81 
    86 
       
    87 $antsSuppressCommonOptions = 1;
    82 &antsUsage('b:d:i:k:l:o:p:v:w:',1,
    88 &antsUsage('b:d:i:k:l:o:p:v:w:',1,
    83 	'[profile -i)d <id>]',
    89 	'[profile -i)d <id>]',
    84 	'[-o)utput bin <resolution>] [-k) require <min> samples]',
    90 	'[-o)utput bin <resolution>] [-k) require <min> samples]',
    85 	'[-v)alid bins <DL first>,<DL last>[,<UL first>,<UL_last>]',
    91 	'[-v)alid bins <DL first>,<DL last>[,<UL first>,<UL_last>]',
    86 	'[-w) <DL_dc_field>,<DL_uc_field>[,<UL_dc_field>,<UL_uc_field>]',
    92 	'[-w) <DL_dc_field>,<DL_uc_field>[,<UL_dc_field>,<UL_uc_field>]',
   148 #----------------------------------------------------------------------
   154 #----------------------------------------------------------------------
   149 # Redirect STDOUT to %.wprof & create plots if STDOUT is a tty
   155 # Redirect STDOUT to %.wprof & create plots if STDOUT is a tty
   150 #----------------------------------------------------------------------
   156 #----------------------------------------------------------------------
   151 
   157 
   152 if (-t STDOUT) {
   158 if (-t STDOUT) {
   153 	$opt_p = defined($opt_d) ? "$opt_d/%03d_wprof.ps,$opt_d/%03d_wcorr.ps"
   159 #	$opt_p = defined($opt_d) ? "$opt_d/%03d_wprof.ps,$opt_d/%03d_wcorr.ps"
   154 							 : '%03d_wprof.ps,%03d_wcorr.ps'
   160 #							 : '%03d_wprof.ps,%03d_wcorr.ps'
       
   161 #		unless defined($opt_p);
       
   162 	$opt_p = defined($opt_d) ? "$opt_d/%03d_wprof.ps" : '%03d_wprof.ps'
   155 		unless defined($opt_p);
   163 		unless defined($opt_p);
   156 	$outfile = defined($opt_d) ? sprintf('%s/%03d.wprof',$opt_d,$id)
   164 	$outfile = defined($opt_d) ? sprintf('%s/%03d.wprof',$opt_d,$id)
   157 							   : sprintf('%03d.wprof',$id);
   165 							   : sprintf('%03d.wprof',$id);
   158 	open(STDOUT,">$outfile") || die("$outfile: $!\n");
   166 	open(STDOUT,">$outfile") || die("$outfile: $!\n");
   159 }
   167 }
   253 		$sxx += $xt * $xt;
   261 		$sxx += $xt * $xt;
   254 		$syy += $yt * $yt;
   262 		$syy += $yt * $yt;
   255 		$sxy += $xt * $yt;
   263 		$sxy += $xt * $yt;
   256 	}
   264 	}
   257 	my($R) = $sxy/(sqrt($sxx * $syy) + 1e-16);
   265 	my($R) = $sxy/(sqrt($sxx * $syy) + 1e-16);
   258 	my($esig) = sqrt(($R**2)*$sxx/$n);
   266 	my($rms) = sqrt($sxx/$n);
   259 	my($rsig) = sqrt((1-$R**2)*$sxx/$n);
   267 	return ($R,$rms);
   260 	return ($R,$esig,$rsig);
       
   261 }
   268 }
   262 
   269 
   263 sub uc_corr(@)
   270 sub uc_corr(@)
   264 {
   271 {
   265 	my($n) = 0;
   272 	my($n) = 0;
   283 		$sxx += $xt * $xt;
   290 		$sxx += $xt * $xt;
   284 		$syy += $yt * $yt;
   291 		$syy += $yt * $yt;
   285 		$sxy += $xt * $yt;
   292 		$sxy += $xt * $yt;
   286 	}
   293 	}
   287 	my($R) = $sxy/(sqrt($sxx * $syy) + 1e-16);
   294 	my($R) = $sxy/(sqrt($sxx * $syy) + 1e-16);
   288 	my($esig) = sqrt(($R**2)*$sxx/$n);
   295 	my($sig) = sqrt(($sxx+$syy)/(2*$n));			# stddev of average w signal from DL & UL
   289 	my($rsig) = sqrt((1-$R**2)*$sxx/$n);
   296 	return ($R,$sig);
   290 	return ($R,$esig,$rsig);
       
   291 }
   297 }
   292 
   298 
   293 #----------------------------------------------------------------------
   299 #----------------------------------------------------------------------
   294 
   300 
   295 $dcwF = &fnr($Ddwf); $ucwF = &fnr($Duwf);
   301 $dcwF = &fnr($Ddwf); $ucwF = &fnr($Duwf);
   307 	unless defined($dayNoP);
   313 	unless defined($dayNoP);
   308 
   314 
   309 if (defined($opt_p)) {
   315 if (defined($opt_p)) {
   310 	($sumPF,$corrPF) = split(/,/,$opt_p);
   316 	($sumPF,$corrPF) = split(/,/,$opt_p);
   311 	croak("$0: cannot decode -p $opt_p\n")
   317 	croak("$0: cannot decode -p $opt_p\n")
   312 		unless (length($corrPF)>0);
   318 		unless (length($sumPF)>0);
   313 }
   319 }
   314 
   320 
   315 my($R,$R2);
   321 my($R,$R2);
   316 if (defined($opt_p)) {												# begin summary plot
   322 if (defined($opt_p)) {												# begin summary plot
   317 	$xmin = -0.1; $x2min = -700;
   323 	$xmin = -0.1; $x2min = -700;
   472 					  ? $DL_dc_median[$bi] - $UL_dc_median[$bi] : nan;
   478 					  ? $DL_dc_median[$bi] - $UL_dc_median[$bi] : nan;
   473 		$uc_diff[$bi] = numberp($DL_uc_median[$bi]) && numberp($UL_uc_median[$bi])
   479 		$uc_diff[$bi] = numberp($DL_uc_median[$bi]) && numberp($UL_uc_median[$bi])
   474 					  ? $DL_uc_median[$bi] - $UL_uc_median[$bi] : nan;
   480 					  ? $DL_uc_median[$bi] - $UL_uc_median[$bi] : nan;
   475 	}
   481 	}
   476 
   482 
   477 	($dc_R,$dc_esig,$dc_rsig) = &dc_corr();										# correlation statistics
   483 	($dc_R,$dc_sig) = &dc_corr();												# correlation statistics
   478 	($uc_R,$uc_esig,$uc_rsig) = &uc_corr();
   484 	($uc_R,$uc_sig) = &uc_corr();
   479 	&antsAddParams('dc_R',$dc_R,'uc_R',$uc_R,
   485 	&antsAddParams('dc_R',$dc_R,'uc_R',$uc_R,'dc_w.sig',$dc_sig,'uc_w.sig',$uc_sig);
   480 				   'dc_explained_stddev',$dc_esig,'uc_explained_stddev',$uc_esig,
       
   481 				   'dc_residual_stddev',$dc_rsig,'uc_residual_stddev',$uc_rsig);
       
   482 
   486 
   483 	if (defined($opt_p)) {														# plot 2nd-instrument profiles
   487 	if (defined($opt_p)) {														# plot 2nd-instrument profiles
   484 		GMT_psxy('-W1,coral,.');
   488 		GMT_psxy('-W1,coral,.');
   485 		for (my($bi)=0; $bi<=$#dcw1; $bi++) {
   489 		for (my($bi)=0; $bi<=$#dcw1; $bi++) {
   486 			printf(GMT "%f %f\n",$UL_dc_median[$bi],($bi+0.5)*$opt_o);
   490 			printf(GMT "%f %f\n",$UL_dc_median[$bi],($bi+0.5)*$opt_o);
   497 
   501 
   498 #----------------------------------------------------------------------
   502 #----------------------------------------------------------------------
   499 # Average and Output Profiles, Add to Summary Plot
   503 # Average and Output Profiles, Add to Summary Plot
   500 #----------------------------------------------------------------------
   504 #----------------------------------------------------------------------
   501 
   505 
       
   506 @antsNewLayout = ('depth','hab',
       
   507 				  'dc_elapsed','dc_w','dc_w.mad','dc_w.nsamp',
       
   508                   'uc_elapsed','uc_w','uc_w.mad','uc_w.nsamp',
       
   509 				  'dc_w.diff','uc_w.diff');										# DL-UL differences
       
   510 
   502 if ($dual_head) {																# dual-head output
   511 if ($dual_head) {																# dual-head output
   503 	@antsNewLayout = ('depth','hab',
       
   504 					  'dc_elapsed','dc_w','dc_w.mad','dc_w.nsamp',
       
   505 	                  'uc_elapsed','uc_w','uc_w.mad','uc_w.nsamp',
       
   506 					  'dc_w.diff','uc_w.diff');									# DL-UL differences
       
   507 	&antsAddParams('profile_id',$id,'lat',$P{lat},'lon',$P{lon});				# selected %PARAMs
   512 	&antsAddParams('profile_id',$id,'lat',$P{lat},'lon',$P{lon});				# selected %PARAMs
   508 	&antsAddParams($dayNoP,$dn,'run_label',"$first_label & $P{run_label}");
   513 	&antsAddParams($dayNoP,$dn,'run_label',"$first_label & $P{run_label}");
   509 	&antsAddParams('outgrid_dz',$opt_o,'outgrid_minsamp',$opt_k);
   514 	&antsAddParams('outgrid_dz',$opt_o,'outgrid_minsamp',$opt_k);
   510 	&antsAddParams('min_depth',round($min_depth),'max_depth',round($max_depth));
   515 	&antsAddParams('min_depth',round($min_depth),'max_depth',round($max_depth));
   511 	&antsAddParams('water_depth',$P{water_depth},'water_depth.sig',$P{water_depth.sig});
   516 	&antsAddParams('water_depth',$P{water_depth},'water_depth.sig',$P{water_depth.sig});
   512 	&antsAddParams('ADCP_bin_length',$bin_length,'ADCP_pulse_length',$pulse_length);
   517 	&antsAddParams('ADCP_bin_length',$bin_length,'ADCP_pulse_length',$pulse_length);
   513 	&antsAddParams('ADCP_blanking_distance',$blanking_dist);
   518 	&antsAddParams('ADCP_blanking_distance',$blanking_dist);
   514 	undef($antsOldHeaders);
   519 	undef($antsOldHeaders);
   515 } else {
       
   516 	@antsNewLayout = ('depth','hab',											# single-head output
       
   517 					  'dc_elapsed','dc_w','dc_w.mad','dc_w.nsamp',
       
   518 	                  'uc_elapsed','uc_w','uc_w.mad','uc_w.nsamp');
       
   519 }
   520 }
   520 
   521 
   521 #&antsInfo("WARNING: unknown water depth (no height-above-bottom)")
   522 #&antsInfo("WARNING: unknown water depth (no height-above-bottom)")
   522 #	unless numberp($P{water_depth});
   523 #	unless numberp($P{water_depth});
   523 
   524 
   536 			 (($dcns[$bi]>=$opt_k)?$dcwm[$bi]:nan),(($dcns[$bi]>=$opt_k)?$dcwmad[$bi]:nan),
   537 			 (($dcns[$bi]>=$opt_k)?$dcwm[$bi]:nan),(($dcns[$bi]>=$opt_k)?$dcwmad[$bi]:nan),
   537 			 scalar(@{$dcw[$bi]}),
   538 			 scalar(@{$dcw[$bi]}),
   538 			 avg(@{$uce[$bi]}),
   539 			 avg(@{$uce[$bi]}),
   539 			 (($ucns[$bi]>=$opt_k)?$ucwm[$bi]:nan),(($ucns[$bi]>=$opt_k)?$ucwmad[$bi]:nan),
   540 			 (($ucns[$bi]>=$opt_k)?$ucwm[$bi]:nan),(($ucns[$bi]>=$opt_k)?$ucwmad[$bi]:nan),
   540 			 scalar(@{$ucw[$bi]}));
   541 			 scalar(@{$ucw[$bi]}));
   541 	push(@{$out[$bi]},$dc_diff[$bi],$uc_diff[$bi])
   542 	if ($dual_head) {
   542 		if ($dual_head);
   543 		push(@{$out[$bi]},$dc_diff[$bi],$uc_diff[$bi]);
       
   544 	} else {
       
   545 		push(@{$out[$bi]},nan,nan);
       
   546 	}
   543 	&antsOut(@{$out[$bi]});				 
   547 	&antsOut(@{$out[$bi]});				 
   544 }
   548 }
   545 
   549 
   546 if (defined($opt_p)) {																# complete summary plot
   550 if (defined($opt_p)) {																# complete summary plot
   547 	GMT_setR($R);
   551 	GMT_setR($R);
   589 		GMT_psxy('-W1,100/100/255');												# surface layer limit
   593 		GMT_psxy('-W1,100/100/255');												# surface layer limit
   590 			print(GMT "-0.1 $opt_s\n0.07 $opt_s\n");
   594 			print(GMT "-0.1 $opt_s\n0.07 $opt_s\n");
   591 		GMT_unitcoords();
   595 		GMT_unitcoords();
   592 		if ($dc_R < 0.3 || !numberp($dc_R)) {										# correlation statistics
   596 		if ($dc_R < 0.3 || !numberp($dc_R)) {										# correlation statistics
   593 			&antsInfo("WARNING: low dc correlation (r = %.1f) between UL and DL data in profile #$id",$dc_R);
   597 			&antsInfo("WARNING: low dc correlation (r = %.1f) between UL and DL data in profile #$id",$dc_R);
   594 			GMT_pstext('-F+f12,Helvetica,coral+jTL -Gred');
   598 									GMT_pstext('-F+f12,Helvetica,coral+jTL -Gred');
   595 		} elsif ($dc_R < 0.5) { 	GMT_pstext('-F+f12,Helvetica,coral+jTL -Gyellow'); }
   599 		} elsif ($dc_R < 0.5) { 	GMT_pstext('-F+f12,Helvetica,coral+jTL -Gyellow'); }
   596 		else {						GMT_pstext('-F+f12,Helvetica,coral+jTL -Gwhite'); }
   600 		else {						GMT_pstext('-F+f12,Helvetica,coral+jTL -Gwhite'); }
   597 	        printf(GMT "%f %f r = %.1f\n",0.61,0.01,$dc_R);
   601 	        printf(GMT "%f %f r = %.1f\n",0.62,0.01,$dc_R);
   598 	}
   602 		GMT_pstext('-F+f12,Helvetica,coral+jTR -Gwhite');
   599 	GMT_pstext('-F+f12,Helvetica,coral+jTR -Gwhite');
   603 			printf(GMT "%f %f [%.1f cm/s stddev]\n",0.99,0.01,100*$dc_sig);
   600 		printf(GMT "%f %f [%.1f/%.1f cm/s @~s@~\@-e/r\@-]\n",
       
   601 			0.99,0.01,100*$dc_esig,100*$dc_rsig) if ($dual_head);
       
   602 	if ($dual_head) {
       
   603 		if ($uc_R < 0.3 || !numberp($uc_R)) {
   604 		if ($uc_R < 0.3 || !numberp($uc_R)) {
   604 			&antsInfo("WARNING: low uc correlation (r = %.1f) between UL and DL data in profile #$id",$uc_R);
   605 			&antsInfo("WARNING: low uc correlation (r = %.1f) between UL and DL data in profile #$id",$uc_R);
   605 			GMT_pstext('-F+f12,Helvetica,SeaGreen+jTL -Gred');
   606 									GMT_pstext('-F+f12,Helvetica,SeaGreen+jTL -Gred');
   606 		} elsif ($uc_R < 0.5) { 	GMT_pstext('-F+f12,Helvetica,SeaGreen+jTL -Gyellow'); }
   607 		} elsif ($uc_R < 0.5) { 	GMT_pstext('-F+f12,Helvetica,SeaGreen+jTL -Gyellow'); }
   607 		else {						GMT_pstext('-F+f12,Helvetica,SeaGreen+jTL -Gwhite'); }
   608 		else {						GMT_pstext('-F+f12,Helvetica,SeaGreen+jTL -Gwhite'); }
   608 	        printf(GMT "%f %f r = %.1f\n",0.61,0.05,$uc_R);
   609 	        printf(GMT "%f %f r = %.1f\n",0.62,0.05,$uc_R);
   609 	}
   610 		GMT_pstext('-F+f12,Helvetica,SeaGreen+jTR -Gwhite');
   610 	GMT_pstext('-F+f12,Helvetica,SeaGreen+jTR -Gwhite');
   611 			printf(GMT "%f %f [%.1f cm/s stddev]\n",0.99,0.05,100*$uc_sig);
   611 		printf(GMT "%f %f [%.1f/%.1f cm/s @~s@~\@-e/r\@-]\n",
   612 	}
   612 			0.99,0.05,100*$uc_esig,100*$uc_rsig) if ($dual_head);
       
   613 
   613 
   614 	GMT_pstext('-F+f14,Helvetica,blue+jTL -N');
   614 	GMT_pstext('-F+f14,Helvetica,blue+jTL -N');
   615 	if (defined($outfile)) { print(GMT "0.01 -0.06 $outfile [$P{run_label}]\n"); }
   615 	if (defined($outfile)) { print(GMT "0.01 -0.06 $outfile [$P{run_label}]\n"); }
   616 	else { 					printf(GMT "0.01 -0.06 %03d\n [$P{run_label}]",$id); }
   616 	else { 					printf(GMT "0.01 -0.06 %03d\n [$P{run_label}]",$id); }
   617 	GMT_pstext('-F+f12,Helvetica+jMR');
   617 	GMT_pstext('-F+f12,Helvetica+jMR');
   619 	GMT_pstext('-F+f9,Helvetica,orange+jBR -N -Gwhite');
   619 	GMT_pstext('-F+f9,Helvetica,orange+jBR -N -Gwhite');
   620 		print(GMT "0.99 0.99 V$VERSION\n");
   620 		print(GMT "0.99 0.99 V$VERSION\n");
   621         
   621         
   622 	GMT_end();
   622 	GMT_end();
   623 
   623 
   624 	if ($dual_head) {																# correlation plot
   624 	if ($dual_head && length($corrPF)>0) {												# correlation plot
   625 		my($mwm) = 0.05; # max(|w|) for axes
   625 		my($mwm) = 0.05; # max(|w|) for axes
   626 		for (my($bi)=0; $bi<@DL_dc_median; $bi++) {
   626 		for (my($bi)=0; $bi<@DL_dc_median; $bi++) {
   627 			next unless numberp($DL_dc_median[$bi]) && numberp($UL_dc_median[$bi]);
   627 			next unless numberp($DL_dc_median[$bi]) && numberp($UL_dc_median[$bi]);
   628 			$mwm = abs($DL_dc_median[$bi]) if abs($DL_dc_median[$bi]) > $mwm;
   628 			$mwm = abs($DL_dc_median[$bi]) if abs($DL_dc_median[$bi]) > $mwm;
   629 			$mwm = abs($UL_dc_median[$bi]) if abs($UL_dc_median[$bi]) > $mwm;
   629 			$mwm = abs($UL_dc_median[$bi]) if abs($UL_dc_median[$bi]) > $mwm;
   680 			if (defined($outfile)) { printf(GMT "%f %f $outfile [$P{run_label}]\n",-$mwm,1.1*$mwm); }
   680 			if (defined($outfile)) { printf(GMT "%f %f $outfile [$P{run_label}]\n",-$mwm,1.1*$mwm); }
   681 		    else { 					 printf(GMT "%f %f %03d\n [$P{run_label}]",$id,-$mwm,1.1*$wmw); }
   681 		    else { 					 printf(GMT "%f %f %03d\n [$P{run_label}]",$id,-$mwm,1.1*$wmw); }
   682 		GMT_psbasemap('-Bf0.01a0.05:"DL Vertical Velocity [m/s]":/f0.01a0.05:"UL Vertical Velocity [m/s]":WeSn');
   682 		GMT_psbasemap('-Bf0.01a0.05:"DL Vertical Velocity [m/s]":/f0.01a0.05:"UL Vertical Velocity [m/s]":WeSn');
   683 		GMT_end();
   683 		GMT_end();
   684 		
   684 		
   685     } # if dual_head		
   685     } # if dual_head && length(corrPF) > 0 
   686 
   686 
   687 }
   687 }
   688 
   688 
   689 &antsExit(0);
   689 &antsExit(0);