author | A.M. Thurnherr <athurnherr@yahoo.com> |
Wed, 13 May 2015 21:30:27 +0000 | |
changeset 35 | 3d769eee8c4f |
parent 29 | f72cd642972c |
permissions | -rw-r--r-- |
1 | 1 |
#====================================================================== |
2 |
# L A D C P P R O C . L O A D C T D |
|
3 |
# doc: Thu Dec 9 18:39:01 2010 |
|
29 | 4 |
# dlm: Sun Sep 14 21:20:12 2014 |
1 | 5 |
# (c) 2010 A.M. Thurnherr |
29 | 6 |
# uE-Info: 37 0 NIL 0 0 72 2 2 4 NIL ofnI |
1 | 7 |
#====================================================================== |
8 |
||
9 |
# HISTORY: |
|
10 |
# Dec 9, 2010: - exported from LADCPproc |
|
11 |
# - added support for ASCII files |
|
12 |
# Dec 16, 2010: - BUG cnv read did not work any more |
|
2 | 13 |
# Jan 10, 2011: - added code to skip ANTS header |
14 |
# Jan 22, 2011: - adapted to new -g |
|
6 | 15 |
# Jul 15, 2011: - added $CTD{first_elapsed} |
16 |
# Feb 5, 2012: - BUG: ASCII file did not deal with leading spaces correctly |
|
9
48b2d27aaebf
after fixing bad magdec bug
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
6
diff
changeset
|
17 |
# Apr 11, 2012: - BUG: ASCII file did not handle nan latlons correctly |
48b2d27aaebf
after fixing bad magdec bug
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
6
diff
changeset
|
18 |
# Apr 17, 2012: - fiddled |
17 | 19 |
# Oct 19, 2012: - BUG: support for $CTD{first_elapsed} had not been implemented |
20 |
# for binary files |
|
21 |
# - BUG: CTD_badval had not been considered when setting $CTD{first_elapsed} |
|
22 |
# - BUG: CNV format error was not detected correctly any more |
|
19 | 23 |
# Jan 8, 2013: - added CTD_ASCII_header_lines |
20 | 24 |
# Jun 25, 2013: - adapted to :: %PARAM convention |
22
f6635c0384b7
beginning of DIMES US5 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
20
diff
changeset
|
25 |
# Sep 25, 2013: - renamed "std" %PARAMs %lat, %lon, %ITS to conform to new convention |
f6635c0384b7
beginning of DIMES US5 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
20
diff
changeset
|
26 |
# - added support for carry-through of lat/lon info |
23 | 27 |
# Nov 11, 2013: - BUG: lat/lon did not work any more?!? |
1 | 28 |
|
29 |
sub readCTD_ASCII($$) |
|
30 |
{ |
|
31 |
my($fn,$dtaR) = @_; |
|
32 |
||
33 |
croak("$fn: unknown pressure field\n") unless defined($CTD_ASCII_press_field); |
|
34 |
croak("$fn: unknown temperature field\n") unless defined($CTD_ASCII_temp_field); |
|
35 |
croak("$fn: unknown salinity field\n") unless defined($CTD_ASCII_salin_field); |
|
22
f6635c0384b7
beginning of DIMES US5 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
20
diff
changeset
|
36 |
unless (numberp($dtaR->{stn_lat})) { |
2 | 37 |
croak("$fn: unknown latitude field\n") unless defined($CTD_ASCII_lat_field); |
38 |
croak("$fn: unknown longitude field\n") unless defined($CTD_ASCII_lon_field); |
|
39 |
} |
|
1 | 40 |
|
41 |
$CTD_ASCII_badval = 9e99 unless defined($CTD_ASCII_badval); |
|
42 |
||
43 |
open(F,$fn) || croak("$fn: $!\n"); |
|
44 |
my($sumLat,$sumLon); my($nPos) = 0; |
|
45 |
my($ds); |
|
19 | 46 |
my($skip) = $CTD_ASCII_header_lines; |
1 | 47 |
while (chomp($ds = <F>)) { |
19 | 48 |
if (defined($CTD_ASCII_header_lines)) { # fixed header |
49 |
next if ($skip-- > 0); |
|
50 |
} else { # comments beginning with # allowed |
|
51 |
next if ($ds =~ /^#/); |
|
52 |
} |
|
53 |
$ds =~ s/^\s+//; # strip leading spaces |
|
1 | 54 |
my(@rec) = split('\s+',$ds); |
55 |
push(@{$dtaR->{press}},($rec[$CTD_ASCII_press_field-1] == $CTD_ASCII_badval) ? nan : $rec[$CTD_ASCII_press_field-1]); |
|
56 |
push(@{$dtaR->{temp}}, ($rec[$CTD_ASCII_temp_field-1] == $CTD_ASCII_badval) ? nan : $rec[$CTD_ASCII_temp_field-1]); |
|
57 |
push(@{$dtaR->{salin}},($rec[$CTD_ASCII_salin_field-1] == $CTD_ASCII_badval) ? nan : $rec[$CTD_ASCII_salin_field-1]); |
|
9
48b2d27aaebf
after fixing bad magdec bug
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
6
diff
changeset
|
58 |
if (defined($CTD_ASCII_lat_field) && |
48b2d27aaebf
after fixing bad magdec bug
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
6
diff
changeset
|
59 |
numberp($rec[$CTD_ASCII_lat_field-1]) && |
48b2d27aaebf
after fixing bad magdec bug
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
6
diff
changeset
|
60 |
$rec[$CTD_ASCII_lat_field-1] != $CTD_ASCII_badval) { |
22
f6635c0384b7
beginning of DIMES US5 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
20
diff
changeset
|
61 |
push(@{$dtaR->{lat}},$rec[$CTD_ASCII_lat_field-1]); |
f6635c0384b7
beginning of DIMES US5 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
20
diff
changeset
|
62 |
push(@{$dtaR->{lon}},$rec[$CTD_ASCII_lon_field-1]); |
9
48b2d27aaebf
after fixing bad magdec bug
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
6
diff
changeset
|
63 |
$nPos++; |
48b2d27aaebf
after fixing bad magdec bug
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
6
diff
changeset
|
64 |
$sumLat += $rec[$CTD_ASCII_lat_field-1]; |
48b2d27aaebf
after fixing bad magdec bug
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
6
diff
changeset
|
65 |
$sumLon += $rec[$CTD_ASCII_lon_field-1]; |
22
f6635c0384b7
beginning of DIMES US5 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
20
diff
changeset
|
66 |
} else { |
f6635c0384b7
beginning of DIMES US5 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
20
diff
changeset
|
67 |
push(@{$dtaR->{lat}},nan); |
f6635c0384b7
beginning of DIMES US5 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
20
diff
changeset
|
68 |
push(@{$dtaR->{lon}},nan); |
1 | 69 |
} |
70 |
} |
|
71 |
close(F); |
|
72 |
||
73 |
if ($nPos > 0) { |
|
22
f6635c0384b7
beginning of DIMES US5 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
20
diff
changeset
|
74 |
$dtaR->{stn_lat} = $sumLat / $nPos; |
f6635c0384b7
beginning of DIMES US5 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
20
diff
changeset
|
75 |
$dtaR->{stn_lon} = $sumLon / $nPos; |
1 | 76 |
} |
77 |
||
78 |
$dtaR->{sampint} = 1 / $CTD_ASCII_sampfreq; |
|
79 |
} |
|
80 |
||
81 |
sub readCTD_CNV($$) |
|
82 |
{ |
|
83 |
my($fn,$dtaR) = @_; |
|
6 | 84 |
my($CTD_nrecs,$CTD_nfields,$pressF,$tempF,$salinF,$elapsedF); |
1 | 85 |
my($CTD_badval,$CTD_file_type); |
86 |
||
87 |
open(F,$fn) || croak("$fn: $!\n"); |
|
88 |
while (1) { # parse header |
|
89 |
my($hdr); |
|
90 |
chomp($hdr = <F>); |
|
17 | 91 |
croak(" unexpected EOF (format error)!\n") unless defined($hdr); |
1 | 92 |
$hdr =~ s/\r*$//; |
93 |
last if ($hdr eq '*END*'); |
|
94 |
||
95 |
$CTD_nfields = $',next if ($hdr =~ /nquan = /); # Layout |
|
96 |
$CTD_nrecs = $',next if ($hdr =~ /nvalues = /); |
|
6 | 97 |
$elapsedF = $1,next if ($hdr =~ /name (\d+) = timeS:/); |
1 | 98 |
$pressF = $1,next if ($hdr =~ /name (\d+) = prDM:/); |
99 |
if ($opt_2) { |
|
100 |
$tempF = $1,next if ($hdr =~ /name (\d+) = t190C:/); |
|
101 |
$salinF = $1,next if ($hdr =~ /name (\d+) = sal11:/); |
|
102 |
} else { |
|
103 |
$tempF = $1,next if ($hdr =~ /name (\d+) = t090C:/); |
|
104 |
$salinF = $1,next if ($hdr =~ /name (\d+) = sal00:/); |
|
105 |
} |
|
22
f6635c0384b7
beginning of DIMES US5 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
20
diff
changeset
|
106 |
$latF = $1,next if ($hdr =~ /name (\d+) = latitude:/); |
f6635c0384b7
beginning of DIMES US5 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
20
diff
changeset
|
107 |
$lonF = $1,next if ($hdr =~ /name (\d+) = longitude:/); |
23 | 108 |
|
20 | 109 |
&antsAddParams('LADCPproc::CTD_start_time',$1),next # selected metadata |
1 | 110 |
if ($hdr =~ /start_time = (.*)/); |
111 |
||
20 | 112 |
&antsAddParams('LADCPproc::CTD_station',$1),next |
1 | 113 |
if ($hdr =~ /Station\s*:\s*(.*)/); |
20 | 114 |
&antsAddParams('LADCPproc::ship',$1),next |
1 | 115 |
if ($hdr =~ /Ship\s*:\s*(.*)\s*$/); |
20 | 116 |
&antsAddParams('LADCPproc::cruise',$1),next |
1 | 117 |
if ($hdr =~ /Cruise\s*:\s*(.*)\s*$/); |
20 | 118 |
&antsAddParams('LADCPproc::CTD_time',$1),next |
1 | 119 |
if ($hdr =~ /Time\s*:\s*(.*)/); |
20 | 120 |
&antsAddParams('LADCPproc::CTD_date',$1),next |
1 | 121 |
if ($hdr =~ /Date\s*:\s*(.*)/); |
122 |
||
123 |
if ($hdr =~ /Latitude\s*[=:]\s*/) { |
|
124 |
($deg,$min,$NS) = split(/ /,$'); |
|
22
f6635c0384b7
beginning of DIMES US5 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
20
diff
changeset
|
125 |
$dtaR->{stn_lat} = $deg + $min/60; |
f6635c0384b7
beginning of DIMES US5 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
20
diff
changeset
|
126 |
$dtaR->{stn_lat} *= -1 if ($NS eq 'S'); |
1 | 127 |
next; |
128 |
} |
|
129 |
if ($hdr =~ /Longitude\s*[=:]\s*/) { |
|
130 |
($deg,$min,$EW) = split(/ /,$'); |
|
22
f6635c0384b7
beginning of DIMES US5 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
20
diff
changeset
|
131 |
$dtaR->{stn_lon} = $deg + $min/60; |
f6635c0384b7
beginning of DIMES US5 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
20
diff
changeset
|
132 |
$dtaR->{stn_lon} *= -1 if ($EW eq 'W'); |
1 | 133 |
next; |
134 |
} |
|
135 |
||
136 |
if ($hdr =~ /interval = seconds: /) { |
|
137 |
$dtaR->{sampint} = 1*$'; |
|
138 |
next; |
|
139 |
} |
|
140 |
||
141 |
$CTD_badval = $',next |
|
142 |
if ($hdr =~ /bad_flag = /); |
|
143 |
$CTD_file_type = $',next |
|
144 |
if ($hdr =~ /file_type = /); |
|
145 |
} |
|
146 |
||
147 |
croak("$CTD_file: cannot determine CTD file layout\n") |
|
148 |
unless ($CTD_nfields && $CTD_nrecs); |
|
149 |
croak("$CTD_file: cannot determine missing value\n") |
|
150 |
unless defined($CTD_badval); |
|
151 |
croak("$CTD_file: not a CTD time series file\n") |
|
152 |
unless ($dtaR->{sampint}); |
|
153 |
croak("$CTD_file: no pressure field\n") |
|
154 |
unless defined($pressF); |
|
155 |
croak("$CTD_file: no suitable temperature field\n") |
|
156 |
unless defined($tempF); |
|
157 |
croak("$CTD_file: no suitable salinity field\n") |
|
158 |
unless defined($salinF); |
|
159 |
||
160 |
if ($CTD_file_type eq 'ascii') { |
|
161 |
while (1) { |
|
162 |
last unless (my(@rec) = &antsFileIn(F)); |
|
6 | 163 |
$dtaR->{first_elapsed} = $rec[$elapsedF] |
17 | 164 |
if !defined($dtaR->{first_elapsed}) && defined($elapsedF) && $rec[$elapsedF]!=$CTD_badval; |
1 | 165 |
push(@{$dtaR->{press}},($rec[$pressF] == $CTD_badval) ? nan : $rec[$pressF]); |
166 |
push(@{$dtaR->{temp}}, ($rec[$tempF] == $CTD_badval) ? nan : $rec[$tempF]); |
|
167 |
push(@{$dtaR->{salin}},($rec[$salinF] == $CTD_badval) ? nan : $rec[$salinF]); |
|
23 | 168 |
push(@{$dtaR->{lat}},(!defined($latF) || ($rec[$latF] == $CTD_badval)) ? nan : $rec[$latF]); |
169 |
push(@{$dtaR->{lon}},(!defined($lonF) || ($rec[$lonF] == $CTD_badval)) ? nan : $rec[$lonF]); |
|
1 | 170 |
} |
171 |
} elsif ($CTD_file_type eq 'binary') { |
|
172 |
||
173 |
my($fbits) = 8 * length(pack('f',0)); |
|
174 |
croak(sprintf("$0: incompatible native CPU float representation (%d instead of 32bits)\n",fbits)) |
|
175 |
unless ($fbits == 32); |
|
176 |
||
177 |
croak("$fn: can't read binary data\n") |
|
178 |
unless (read(F,my($dta),4*$CTD_nfields*$CTD_nrecs) == 4*$CTD_nfields*$CTD_nrecs); |
|
179 |
print(STDERR "$fn: WARNING: extraneous data at EOF\n") unless eof(F); |
|
180 |
||
181 |
$dta = pack('V*',unpack('N*',$dta)) # big-endian CPU |
|
182 |
if (unpack('h*', pack('s', 1)) =~ /01/); # c.f. perlport(1) |
|
183 |
||
184 |
my(@dta) = unpack("f*",$dta); |
|
185 |
||
186 |
for (my($r)=0; $r<$CTD_nrecs; $r++) { |
|
17 | 187 |
$dtaR->{first_elapsed} = $dta[$r*$CTD_nfields+$elapsedF] |
188 |
if !defined($dtaR->{first_elapsed}) && defined($elapsedF) && $dta[$r*$CTD_nfields+$elapsedF]!=$CTD_badval; |
|
1 | 189 |
push(@{$dtaR->{press}},($dta[$r*$CTD_nfields+$pressF] == $CTD_badval) ? nan : $dta[$r*$CTD_nfields+$pressF]); |
190 |
push(@{$dtaR->{temp}}, ($dta[$r*$CTD_nfields+$tempF] == $CTD_badval) ? nan : $dta[$r*$CTD_nfields+$tempF]); |
|
191 |
push(@{$dtaR->{salin}},($dta[$r*$CTD_nfields+$salinF] == $CTD_badval) ? nan : $dta[$r*$CTD_nfields+$salinF]); |
|
22
f6635c0384b7
beginning of DIMES US5 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
20
diff
changeset
|
192 |
push(@{$dtaR->{lat}},(!defined($latF) || ($dta[$r*$CTD_nfields+$latF] == $CTD_badval)) ? nan : $dta[$r*$CTD_nfields+$latF]); |
f6635c0384b7
beginning of DIMES US5 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
20
diff
changeset
|
193 |
push(@{$dtaR->{lon}},(!defined($lonF) || ($dta[$r*$CTD_nfields+$lonF] == $CTD_badval)) ? nan : $dta[$r*$CTD_nfields+$lonF]); |
1 | 194 |
} |
195 |
} else { |
|
196 |
croak("$fn: unknown CTD file type $CTD_file_type\n"); |
|
197 |
} |
|
198 |
close(F); |
|
199 |
} |
|
200 |
||
201 |
sub readCTD($$) |
|
202 |
{ |
|
203 |
my($fn,$dtaR) = @_; |
|
204 |
||
205 |
if (defined($CTD_ASCII_sampfreq)) { |
|
206 |
readCTD_ASCII($fn,$dtaR); |
|
207 |
} else { |
|
208 |
readCTD_CNV($fn,$dtaR); |
|
209 |
} |
|
210 |
||
22
f6635c0384b7
beginning of DIMES US5 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
20
diff
changeset
|
211 |
croak("$0: unknown latitude\n") unless defined($dtaR->{stn_lat}); |
f6635c0384b7
beginning of DIMES US5 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
20
diff
changeset
|
212 |
&antsAddParams('LADCPproc::CTD_lat',$dtaR->{stn_lat}); |
f6635c0384b7
beginning of DIMES US5 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
20
diff
changeset
|
213 |
croak("$0: unknown longitude\n") unless defined($dtaR->{stn_lon}); |
f6635c0384b7
beginning of DIMES US5 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
20
diff
changeset
|
214 |
&antsAddParams('LADCPproc::CTD_lon',$dtaR->{stn_lon}); |
1 | 215 |
|
20 | 216 |
&antsAddParams('LADCPproc::CTD_sampfreq',1/$dtaR->{sampint}); |
22
f6635c0384b7
beginning of DIMES US5 cruise
A.M. Thurnherr <athurnherr@yahoo.com>
parents:
20
diff
changeset
|
217 |
&antsAddParams('LADCPproc::CTD_ITS',$P{ITS} = 90); |
1 | 218 |
} |
219 |
||
220 |
1; |