mkProfile
changeset 12 0f89b1523648
parent 11 9c3b147b4372
child 14 8c79b38a7086
equal deleted inserted replaced
11:9c3b147b4372 12:0f89b1523648
     1 #!/usr/bin/perl
     1 #!/usr/bin/perl
     2 #======================================================================
     2 #======================================================================
     3 #                    M K P R O F I L E 
     3 #                    M K P R O F I L E 
     4 #                    doc: Sun Jan 19 18:55:26 2003
     4 #                    doc: Sun Jan 19 18:55:26 2003
     5 #                    dlm: Fri Apr 12 09:24:14 2013
     5 #                    dlm: Tue May 14 11:37:04 2013
     6 #                    (c) 2003 A.M. Thurnherr
     6 #                    (c) 2003 A.M. Thurnherr
     7 #                    uE-Info: 269 72 NIL 0 0 72 2 2 4 NIL ofnI
     7 #                    uE-Info: 169 15 NIL 0 0 72 2 2 4 NIL ofnI
     8 #======================================================================
     8 #======================================================================
     9 
     9 
    10 # Make an LADCP Profile by Integrating W (similar to Firing's scan*).
    10 # Make an LADCP Profile by Integrating W (similar to Firing's scan*).
    11 
    11 
    12 # HISTORY:
    12 # HISTORY:
    77 #				  - BUG: post-recovery rotations were always zero
    77 #				  - BUG: post-recovery rotations were always zero
    78 #	Sep  9, 2011: - BUG: range calculation for Earth coordinate data included bins without
    78 #	Sep  9, 2011: - BUG: range calculation for Earth coordinate data included bins without
    79 #						 valid velocities
    79 #						 valid velocities
    80 #	Sep 21, 2010: - added %rms_heave_acceleration
    80 #	Sep 21, 2010: - added %rms_heave_acceleration
    81 #	Apr 12, 2013: - added -p
    81 #	Apr 12, 2013: - added -p
       
    82 #	May 10, 2013: - BUG: mkProfile bombed when ADCP file is truncated at deepest location
       
    83 #	May 14, 2013: - added heading to output
       
    84 #				  - added err_vel to output
       
    85 #				  - finally removed -d/-g
    82 
    86 
    83 # NOTES:
    87 # NOTES:
    84 #	- the battery values are based on transmission voltages (different
    88 #	- the battery values are based on transmission voltages (different
    85 #	  from battery voltages) and reported without units (raw 8-bit a2d
    89 #	  from battery voltages) and reported without units (raw 8-bit a2d
    86 #	  values)
    90 #	  values)
   102 
   106 
   103 $USAGE = "$0 @ARGV";
   107 $USAGE = "$0 @ARGV";
   104 die("Usage: $0 " .
   108 die("Usage: $0 " .
   105 	"[-Q)uiet] [-F)ilter <script>] " .
   109 	"[-Q)uiet] [-F)ilter <script>] " .
   106 	"[-s)uppress checkensemble()] " .
   110 	"[-s)uppress checkensemble()] " .
   107 	"[require -4)-beam solutions] " .
   111 	"[require -4)-beam solutions] [-d)iscard <beam#>] [apply beamvel-m)ask <file>] " .
   108 	"[-r)ef-layer <bin|1,bin|6>] [-n) vels <min|2>] " .
   112 	"[-r)ef-layer <bin|1,bin|6>] [-n) vels <min|2>] " .
   109 	"[-e)rr-vel <max[0.1]] [-c)orrelation <min>] [-p)ct-good <min[100]>] " .
   113 	"[-e)rr-vel <max[0.1]] [-c)orrelation <min>] [-p)ct-good <min[100]>] " .
   110 	"[-m)ax <gap>] " .
   114 	"[max -g)ap <len>] " .
   111 	"[-d)rift <dx,dy>] [-g)ps <start lat,lon/end lat,lon>] " .
       
   112 	"[output -f)ields <field[,...]> " .
   115 	"[output -f)ields <field[,...]> " .
   113 	"[-M)agnetic <declination>] [profile -B)ottom <depth>] " .
   116 	"[-M)agnetic <declination>] [profile -B)ottom <depth>] " .
   114 	"<RDI file>\n")
   117 	"<RDI file>\n")
   115 		unless (&Getopts("4AB:F:M:Qd:r:n:e:c:g:f:m:sp:") && @ARGV == 1);
   118 		unless (&Getopts("4AB:F:M:Qd:g:r:n:e:c:f:m:sp:") && @ARGV == 1);
   116 
   119 
   117 $RDI_Coords::minValidVels = 4 if ($opt_4);			# no 3-beam solutions
   120 $RDI_Coords::minValidVels = 4 if ($opt_4);			# no 3-beam solutions
   118 
   121 
   119 require $opt_F if defined($opt_F);					# load filter
   122 require $opt_F if defined($opt_F);					# load filter
   120 
   123 
   121 $opt_r = "1,6" 	unless defined($opt_r);				# defaults
   124 $opt_r = "1,6" 	unless defined($opt_r);				# defaults
   122 $opt_n = 2	   	unless defined($opt_n);
   125 $opt_n = 2	   	unless defined($opt_n);
   123 $opt_e = 0.1   	unless defined($opt_e);
   126 $opt_e = 0.1   	unless defined($opt_e);
   124 $opt_c = 70	   	unless defined($opt_c);
   127 $opt_c = 70	   	unless defined($opt_c);
   125 $opt_m = 120	unless defined($opt_m);
   128 $opt_g = 120	unless defined($opt_g);
   126 $opt_p = 100	unless defined($opt_p);
   129 $opt_p = 100	unless defined($opt_p);
   127 
   130 
   128 ($minb,$maxb) = split(',',$opt_r);					# reference layer
   131 ($minb,$maxb) = split(',',$opt_r);					# reference layer
   129 die("$0: can't decode -r $opt_r\n") unless defined($maxb);
   132 die("$0: can't decode -r $opt_r\n") unless defined($maxb);
   130                                         
   133                                         
   131 if ($opt_g) {										# GPS info
       
   132 	($s_lat,$s_lon,$e_lat,$e_lon) = gps_to_deg($opt_g);
       
   133 	$lat = $s_lat/2 + $e_lat/2;
       
   134 	$lon = $s_lon/2 + $e_lon/2;
       
   135 	$ddx = dist($lat,$s_lon,$lat,$e_lon);
       
   136 	$ddy = dist($s_lat,$lon,$e_lat,$lon);
       
   137 }
       
   138 
       
   139 if ($opt_d) {										# ship drift
       
   140 	($ddx,$ddy) = split(',',$opt_d);
       
   141 	die("$0: can't decode -d $opt_d\n") unless defined($ddy);
       
   142 }
       
   143 
       
   144 print(STDERR "Reading $ARGV[0]...");				# read data
   134 print(STDERR "Reading $ARGV[0]...");				# read data
   145 readData($ARGV[0],\%dta);
   135 readData($ARGV[0],\%dta);
   146 print(STDERR "done\n");
   136 print(STDERR "done\n");
   147 
   137 
   148 die("$ARGV[0]: not enough bins for choice of -r\n")	# enough bins?
   138 die("$ARGV[0]: not enough bins for choice of -r\n")	# enough bins?
   149 	unless ($dta{N_BINS} >= $maxb);
   139 	unless ($dta{N_BINS} >= $maxb);
   150 if ($dta{BEAM_COORDINATES}) {						# coords used
   140 if ($dta{BEAM_COORDINATES}) {						# coords used
   151 	$beamCoords = 1;
   141 	$beamCoords = 1;
   152 } elsif (!$dta{EARTH_COORDINATES}) {
   142 } elsif (!$dta{EARTH_COORDINATES}) {
   153 	die("$ARGV[0]: only beam and earth coordinates implemented so far\n");
   143 	die("$ARGV[0]: only beam and earth coordinates implemented so far\n");
       
   144 }
       
   145 
       
   146 if (defined($opt_m) && -r $opt_m) {
       
   147 	die("$ARGV[0]: -m only implemented for data collected in beam coordinates\n")
       
   148 		unless ($beamCoords);
       
   149 	print(STDERR "Masking beam velocities as prescribed in $opt_m...");
       
   150 
       
   151 	open(BVM,$opt_m) || die("$opt_m: $!\n");
       
   152 	while (<BVM>) {
       
   153 		s/#.*//;
       
   154 		s/^\s*$//;
       
   155 		next if ($_ eq '');
       
   156 		my($fe,$te,$db) = split;
       
   157 		die("$opt_m: cannot decode $_\n")
       
   158 			unless (numberp($fe) && numberp($te) && $te>=$fe && $db>=1 && $db<=4);
       
   159 		die("$0: assertion failed")
       
   160 			unless ($dta{ENSEMBLE}[$fe-1]->{NUMBER} == $fe &&
       
   161 					$dta{ENSEMBLE}[$te-1]->{NUMBER} == $te);
       
   162 		for (my($ens)=$fe-1; $ens<=$te-1; $ens++) {
       
   163 			$nens++;
       
   164 			for (my($bin)=0; $bin<$dta{N_BINS}; $bin++) {
       
   165 				undef($dta{ENSEMBLE}[$ens]->{VELOCITY}[$bin][$db-1]);
       
   166 			}
       
   167 	    }       
       
   168     }
       
   169 	close(BVM);
       
   170 	print(STDERR " $nens ensembles edited\n");
       
   171 }
       
   172 
       
   173 if (defined($opt_d)) {								# discard entire beam
       
   174 	die("$ARGV[0]: -d only implemented for data collected in beam coordinates\n")
       
   175 		unless ($beamCoords);
       
   176 	print(STDERR "Discarding beam-$opt_d velocities...");
       
   177     for (my($ens)=0; $ens<=$#{$dta{ENSEMBLE}}; $ens++) {
       
   178         for (my($bin)=0; $bin<$dta{N_BINS}; $bin++) {
       
   179             undef($dta{ENSEMBLE}[$ens]->{VELOCITY}[$bin][$opt_d-1]);
       
   180         }
       
   181     }       
       
   182 	print(STDERR "done\n");
   154 }
   183 }
   155 
   184 
   156 if (defined($opt_M)) {								# magnetic declination
   185 if (defined($opt_M)) {								# magnetic declination
   157 	$dta{HEADING_BIAS} = -1*$opt_M;
   186 	$dta{HEADING_BIAS} = -1*$opt_M;
   158 } else {
   187 } else {
   176 #	print(STDERR "addFields = $addFields\n");
   205 #	print(STDERR "addFields = $addFields\n");
   177 #	print(STDERR "\@f = @f\n");
   206 #	print(STDERR "\@f = @f\n");
   178 }
   207 }
   179 
   208 
   180 #======================================================================
   209 #======================================================================
   181 # Misc funs used to decode options
       
   182 #======================================================================
       
   183 
       
   184 sub dist($$$$)										# distance
       
   185 {
       
   186 	my($lat1,$lon1,$lat2,$lon2) = @_;
       
   187 	my($a) = 6378139; 								# Earth's radius
       
   188 
       
   189 	$lat1 = rad($lat1); $lon1 = rad($lon1);
       
   190 	$lat2 = rad($lat2); $lon2 = rad($lon2);
       
   191 	$ct1 = cos($lat1); $st1 = sin($lat1); $cp1 = cos($lon1);
       
   192 	$sp1 = sin($lon1); $ct2 = cos($lat2); $st2 = sin($lat2);
       
   193 	$cp2 = cos($lon2); $sp2 = sin($lon2);
       
   194 	$cos = $ct1*$cp1*$ct2*$cp2 + $ct1*$sp1*$ct2*$sp2 + $st1*$st2;
       
   195 	$cos =  1 if ($cos >  1);
       
   196 	$cos = -1 if ($cos < -1);
       
   197 	return $a * acos($cos);
       
   198 }
       
   199 
       
   200 sub deg_to_dec($)									# parse degrees
       
   201 {
       
   202 	my($deg,$min) = split(':',$_[0]);
       
   203 	return $deg + $min/60;
       
   204 }
       
   205 
       
   206 sub gps_to_deg($)									# decode lat/lon
       
   207 {
       
   208 	my($start,$end) = split('/',$_[0]);
       
   209 	my($sa,$so,$ea,$eo);
       
   210 
       
   211 	my($lat,$lon) = split(',',$start);
       
   212 	if ($lat =~ m{N$}) 		{ $sa =  deg_to_dec($`); }
       
   213 	elsif ($lat =~ m{S$}) 	{ $sa = -deg_to_dec($`); }
       
   214 	else 					{ $sa = $lat; }
       
   215 	if ($lon =~ m{E$}) 		{ $so =  deg_to_dec($`); }
       
   216 	elsif ($lon =~ m{W$}) 	{ $so = -deg_to_dec($`); }
       
   217 	else 					{ $so = $lon; }
       
   218 
       
   219 	my($lat,$lon) = split(',',$end);
       
   220 	if ($lat =~ m{N$}) 		{ $ea =  deg_to_dec($`); }
       
   221 	elsif ($lat =~ m{S$}) 	{ $ea = -deg_to_dec($`); }
       
   222 	else 					{ $ea = $lat; }
       
   223 	if ($lon =~ m{E$}) 		{ $eo =  deg_to_dec($`); }
       
   224 	elsif ($lon =~ m{W$}) 	{ $eo = -deg_to_dec($`); }
       
   225 	else 					{ $eo = $lon; }
       
   226 
       
   227 	return ($sa,$so,$ea,$eo);
       
   228 }
       
   229 
       
   230 #======================================================================
       
   231 # Step 0: Check data & Calculate Ping Rates
   210 # Step 0: Check data & Calculate Ping Rates
   232 #======================================================================
   211 #======================================================================
   233 
   212 
   234 unless ($dta{NARROW_BANDWIDTH}) {
   213 unless ($dta{NARROW_BANDWIDTH}) {
   235 	print(STDERR "WARNING: $0 WIDE BANDWIDTH!\n");
   214 	print(STDERR "WARNING: $0 WIDE BANDWIDTH!\n");
   264 #======================================================================
   243 #======================================================================
   265 # Step 1: Integrate w & determine water depth 
   244 # Step 1: Integrate w & determine water depth 
   266 #======================================================================
   245 #======================================================================
   267 
   246 
   268 ($firstgood,$lastgood,$atbottom,$w_gap_time,$zErr,$maxz,$rms_heave_accel) =
   247 ($firstgood,$lastgood,$atbottom,$w_gap_time,$zErr,$maxz,$rms_heave_accel) =
   269 	mk_prof(\%dta,!$opt_s,$opt_F,$minb,$maxb,$opt_c,$opt_e,$opt_m,$opt_p);
   248 	mk_prof(\%dta,!$opt_s,$opt_F,$minb,$maxb,$opt_c,$opt_e,$opt_g,$opt_p);
   270 
   249 
   271 unless (($atbottom > $firstgood) && ($lastgood > $atbottom)) {
   250 unless (($atbottom > $firstgood) && ($lastgood > $atbottom)) {
   272 	if ($opt_Q) {
   251 	if ($opt_Q) {
   273 		print(STDERR "$ARGV[0]: no valid cast data found\n");
   252 		print(STDERR "$ARGV[0]: no valid cast data found\n");
   274 		exit(0);
   253 		exit(0);
   573     }
   552     }
   574 }
   553 }
   575 $gb = ($gb[0]+$gb[1]+$gb[2]+$gb[3]) / 4;
   554 $gb = ($gb[0]+$gb[1]+$gb[2]+$gb[3]) / 4;
   576 
   555 
   577 #======================================================================
   556 #======================================================================
   578 # Step 5: Remove Ship Drift (probably not useful)
   557 # Step 5: Remove Ship Drift (probably not useful => removed)
   579 #======================================================================
   558 #======================================================================
   580 
       
   581 if (defined($opt_M) && defined($ddx)) {						# remove barotropic
       
   582 	$du = $ddx / $dta{ENSEMBLE}[$lastgood]->{ELAPSED_TIME};# mean drift vel
       
   583 	$dv = $ddy / $dta{ENSEMBLE}[$lastgood]->{ELAPSED_TIME};
       
   584 	$iu = $dta{ENSEMBLE}[$lastgood]->{X} /				# mean obs vel
       
   585 			$dta{ENSEMBLE}[$lastgood]->{ELAPSED_TIME};
       
   586 	$iv = $dta{ENSEMBLE}[$lastgood]->{Y} /
       
   587 			$dta{ENSEMBLE}[$lastgood]->{ELAPSED_TIME};
       
   588 	
       
   589 	for ($e=$firstgood; $e<=$lastgood; $e++) {
       
   590 		next unless (defined($dta{ENSEMBLE}[$e]->{X}) &&
       
   591 					 defined($dta{ENSEMBLE}[$e]->{Y}));
       
   592 		$dta{ENSEMBLE}[$e]->{U} -= $du;
       
   593 		$dta{ENSEMBLE}[$e]->{V} -= $dv;
       
   594 		$dta{ENSEMBLE}[$e]->{X} += $dta{ENSEMBLE}[$e]->{ELAPSED_TIME} * ($du-$iu);
       
   595 		$dta{ENSEMBLE}[$e]->{Y} += $dta{ENSEMBLE}[$e]->{ELAPSED_TIME} * ($dv-$iv);
       
   596 	}
       
   597 }
       
   598 
   559 
   599 #======================================================================
   560 #======================================================================
   600 # Step 6: Pitch, Roll, Rotation
   561 # Step 6: Pitch, Roll, Rotation
   601 #======================================================================
   562 #======================================================================
   602 
   563 
   650 $uprot   /= 360;
   611 $uprot   /= 360;
   651 $postrot /= 360;
   612 $postrot /= 360;
   652 
   613 
   653 $prrms 	 = sqrt($prrms/($lastgood-$firstgood));
   614 $prrms 	 = sqrt($prrms/($lastgood-$firstgood));
   654 $dnprrms = sqrt($dnprrms/($atbottom-$firstgood));
   615 $dnprrms = sqrt($dnprrms/($atbottom-$firstgood));
   655 $upprrms = sqrt($upprrms/($lastgood-$atbottom));
   616 
       
   617 if ($lastgood == $atbottom) {
       
   618 	print(STDERR "WARNING: $0 NO UPCAST DATA\n");
       
   619 	$upprrms = nan;
       
   620 } else {
       
   621 	$upprrms = sqrt($upprrms/($lastgood-$atbottom));
       
   622 }
   656 
   623 
   657 $rotrms = sqrt($rotrms/($lastgood-$firstgood));
   624 $rotrms = sqrt($rotrms/($lastgood-$firstgood));
   658 
   625 
   659 #======================================================================
   626 #======================================================================
   660 # PRODUCE OUTPUT
   627 # PRODUCE OUTPUT
   716 
   683 
   717 print("#ANTS# [] $USAGE\n");
   684 print("#ANTS# [] $USAGE\n");
   718 $uFields = "{u} {u_err} {v} {v_err} {x} {x_err} {y} {y_err}"
   685 $uFields = "{u} {u_err} {v} {v_err} {x} {x_err} {y} {y_err}"
   719 	if defined($opt_M);
   686 	if defined($opt_M);
   720 print("#ANTS#FIELDS# {ens} {time} {elapsed} {secno} {downcast} " .
   687 print("#ANTS#FIELDS# {ens} {time} {elapsed} {secno} {downcast} " .
   721 					"{w} {w_err} {depth} {depth_err} {depth_BT} " .
   688 					"{w} {w_err} {err_vel} {depth} {depth_err} {depth_BT} " .
   722 					"{pitchroll} {rotation} " .
   689 					"{pitchroll} {heading} {rotation} " .
   723 					"$uFields $addFields\n");
   690 					"$uFields $addFields\n");
   724 
   691 
   725 printf("#ANTS#PARAMS# date{$dta{ENSEMBLE}[$firstgood]->{DATE}} " .
   692 printf("#ANTS#PARAMS# date{$dta{ENSEMBLE}[$firstgood]->{DATE}} " .
   726 			   "start_time{$dta{ENSEMBLE}[$firstgood]->{TIME}} " .
   693 			   "start_time{$dta{ENSEMBLE}[$firstgood]->{TIME}} " .
   727 			  "bottom_time{$dta{ENSEMBLE}[$atbottom]->{TIME}} " .
   694 			  "bottom_time{$dta{ENSEMBLE}[$atbottom]->{TIME}} " .
   782 	$uErr, $dta{ENSEMBLE}[$lastgood]->{X}, $x_err,
   749 	$uErr, $dta{ENSEMBLE}[$lastgood]->{X}, $x_err,
   783 	$dta{ENSEMBLE}[$lastgood]->{Y} /
   750 	$dta{ENSEMBLE}[$lastgood]->{Y} /
   784 		$dta{ENSEMBLE}[$lastgood]->{ELAPSED_TIME},
   751 		$dta{ENSEMBLE}[$lastgood]->{ELAPSED_TIME},
   785 	$vErr, $dta{ENSEMBLE}[$lastgood]->{Y}, $y_err,
   752 	$vErr, $dta{ENSEMBLE}[$lastgood]->{Y}, $y_err,
   786 ) if defined ($opt_M);
   753 ) if defined ($opt_M);
   787 print("#ANTS#PARAMS# start_lat{$s_lat} start_lon{$s_lon} " .
       
   788 					  "end_lat{$e_lat} end_lon{$e_lon} " .
       
   789 						  "lat{$lat} lon{$lon}\n")
       
   790 	if defined($lat);
       
   791 if ($dta{TIME_BETWEEN_PINGS} == 0) {
   754 if ($dta{TIME_BETWEEN_PINGS} == 0) {
   792 	 print("#ANTS#PARAMS# pinging_rate{staggered}\n");
   755 	 print("#ANTS#PARAMS# pinging_rate{staggered}\n");
   793 } else {
   756 } else {
   794 	 printf("#ANTS#PARAMS# pinging_rate{%.2f}\n",
   757 	 printf("#ANTS#PARAMS# pinging_rate{%.2f}\n",
   795 		1/$dta{TIME_BETWEEN_PINGS});
   758 		1/$dta{TIME_BETWEEN_PINGS});
   796 }	    
   759 }	    
   797 printf("#ANTS#PARAMS# drift_x{%d} drift_y{%d} " .
       
   798 					 "drift_u{%.3f} drift_v{%.3f} " .
       
   799 	   "\n",$ddx,$ddy,$du,$dv) if defined($ddx);
       
   800 if (defined($water_depth)) {
   760 if (defined($water_depth)) {
   801 	printf("#ANTS#PARAMS# water_depth{%d} sig-water_depth{%d}\n",
   761 	printf("#ANTS#PARAMS# water_depth{%d} sig-water_depth{%d}\n",
   802 				$water_depth,$sig_wd);
   762 				$water_depth,$sig_wd);
   803 } else {
   763 } else {
   804 	print("#ANTS#PARAMS# water_depth{nan} sig-water_depth{nan}\n");
   764 	print("#ANTS#PARAMS# water_depth{nan} sig-water_depth{nan}\n");
   813 	p($dta{ENSEMBLE}[$e]->{ELAPSED_TIME});
   773 	p($dta{ENSEMBLE}[$e]->{ELAPSED_TIME});
   814 	p($dta{ENSEMBLE}[$e]->{SECNO});
   774 	p($dta{ENSEMBLE}[$e]->{SECNO});
   815 	pb($dta{ENSEMBLE}[$e]->{UNIX_TIME} < $dta{ENSEMBLE}[$atbottom]->{UNIX_TIME});
   775 	pb($dta{ENSEMBLE}[$e]->{UNIX_TIME} < $dta{ENSEMBLE}[$atbottom]->{UNIX_TIME});
   816 	p($dta{ENSEMBLE}[$e]->{W});
   776 	p($dta{ENSEMBLE}[$e]->{W});
   817 	p($dta{ENSEMBLE}[$e]->{W_ERR});
   777 	p($dta{ENSEMBLE}[$e]->{W_ERR});
       
   778 	p($dta{ENSEMBLE}[$e]->{ERR_VEL});
   818 	p($dta{ENSEMBLE}[$e]->{DEPTH});
   779 	p($dta{ENSEMBLE}[$e]->{DEPTH});
   819 	p($dta{ENSEMBLE}[$e]->{DEPTH_ERR});
   780 	p($dta{ENSEMBLE}[$e]->{DEPTH_ERR});
   820 	p($dta{ENSEMBLE}[$e]->{DEPTH_BT});
   781 	p($dta{ENSEMBLE}[$e]->{DEPTH_BT});
   821 	p($dta{ENSEMBLE}[$e]->{PITCHROLL});
   782 	p($dta{ENSEMBLE}[$e]->{PITCHROLL});
       
   783 	p($dta{ENSEMBLE}[$e]->{HEADING});
   822 	p($dta{ENSEMBLE}[$e]->{ROTATION});
   784 	p($dta{ENSEMBLE}[$e]->{ROTATION});
   823 	if (defined($opt_M)) {
   785 	if (defined($opt_M)) {
   824 		p($dta{ENSEMBLE}[$e]->{U}); p($dta{ENSEMBLE}[$e]->{U_ERR});
   786 		p($dta{ENSEMBLE}[$e]->{U}); p($dta{ENSEMBLE}[$e]->{U_ERR});
   825 		p($dta{ENSEMBLE}[$e]->{V}); p($dta{ENSEMBLE}[$e]->{V_ERR});
   787 		p($dta{ENSEMBLE}[$e]->{V}); p($dta{ENSEMBLE}[$e]->{V_ERR});
   826 		p($dta{ENSEMBLE}[$e]->{X}); p($dta{ENSEMBLE}[$e]->{X_ERR});
   788 		p($dta{ENSEMBLE}[$e]->{X}); p($dta{ENSEMBLE}[$e]->{X_ERR});