NCCOOS Trac Projects: Top | Web | Platforms | Processing | Viz | Sprints | Sandbox | (Wind)

root/raw2proc/trunk/raw2proc/scr_read_avp_ysi_6600_v2_fixed_profiler.py

Revision 451 (checked in by cbc, 13 years ago)

Add various proc and config files not already under SVN.

Line 
1 #!/usr/bin/env python
2 # Last modified:  Time-stamp: <2008-09-09 12:56:46 haines>
3 """
4 parse ascii text file of YSI 6600 V2 water quality data (.dat)
5
6 load data file
7 parse data into variables for appending to netCDF data
8
9 """
10
11 REAL_RE_STR = '\\s*(-?\\d(\\.\\d+|)[Ee][+\\-]\\d\\d?|-?(\\d+\\.\\d*|\\d*\\.\\d+)|-?\\d+)\\s*'
12
13 import sys
14 import os
15 import re
16
17 def parse_avp_YSI_6600V2(fn, lines):
18     """
19     parse Automated Vertical Profile Station (AVP) Water Quality Data
20
21     month, day, year, hour, min, sec, temp (deg. C), conductivity
22     (mS/cm), salinity (ppt or PSU), depth (meters), pH, turbidity (NTU),
23     chlorophyll (micrograms per liter), DO (micrograms per liter)
24
25     Notes
26     -----
27     1. Column Format
28
29     temp, cond, salin, depth, pH, turb, chl, DO
30     (C), (mS/cm), (ppt), (m), pH, (NTU), (ug/l), (ug/l)
31
32     Profile Time: 00:30:00
33     Profile Date: 08/18/2008
34     Profile Depth: 255.0 cm
35     Profile Location: Stones Bay Serial No: 00016B79, ID: AVP1_SERDP
36     08/18/08 00:30:06 26.94  41.87  26.81   0.134  8.00     3.4   4.5   6.60
37     08/18/08 00:30:07 26.94  41.87  26.81   0.143  8.00     3.4   4.8   6.59
38     08/18/08 00:30:08 26.94  41.87  26.81   0.160  8.00     3.4   4.8   6.62
39     08/18/08 00:30:09 26.94  41.87  26.81   0.183  8.00     3.4   4.8   6.66
40
41     2. While each parameter is measured uniquely with time and depth such that, temp(t) and z(t)
42     match up with time, we want to grid depth every 1 cm and make each param as temp(t,z).
43
44     Tony Whipple at IMS says 'The AVPs sample at one second intervals.
45     Between the waves and the instrument descending from a spool of
46     line with variable radius it works out to about 3-5 cm between
47     observations on average.  When I process the data to make the
48     images, I bin the data every 10 cm and take the average of however
49     many observations fell within that bin.'
50
51     Do we interpolate or average samples in bin?
52
53     """
54     import numpy
55     from datetime import datetime
56     from time import strptime
57
58     # get sample datetime from filename
59     # fn = sensor_info['fn']
60     sample_dt_start = filt_datetime(fn)[0]
61
62     # how many profiles in one file, count number of "Profile Time:" in lines
63     nprof = 0
64     for line in lines:
65         m=re.search("Profile Time:", line)
66         if m:
67             nprof=nprof+1
68
69     # remove first occurrence of blank line if within first 10-40 lines
70     # and put it on the end to signal end of profile after last profile
71     for i in range(len(lines[0:40])):
72         if re.search("^ \r\n", lines[i]):
73             # print str(i) + " " + lines[i] + " " + lines[i+1]
74             blank_line = lines.pop(i)
75     lines.append(blank_line)
76    
77     bin_size = 0.1 # 10cm or 0.1m
78     z = numpy.arange(0,4.0,bin_size,dtype=float)
79    
80     N = nprof
81     nbins = len(z)
82     data = {
83         'dt' : numpy.array(numpy.ones((N,), dtype=object)*numpy.nan),
84         'time' : numpy.array(numpy.ones((N,), dtype=long)*numpy.nan),
85         'water_depth' : numpy.array(numpy.ones((N,), dtype=long)*numpy.nan),
86         'wtemp' : numpy.array(numpy.ones((N,nbins), dtype=float)*numpy.nan),
87         'cond' : numpy.array(numpy.ones((N,nbins), dtype=float)*numpy.nan),
88         'salin' : numpy.array(numpy.ones((N,nbins), dtype=float)*numpy.nan),
89         'turb' : numpy.array(numpy.ones((N,nbins), dtype=float)*numpy.nan),
90         'ph' : numpy.array(numpy.ones((N,nbins), dtype=float)*numpy.nan),
91         'chl' : numpy.array(numpy.ones((N,nbins), dtype=float)*numpy.nan),
92         'do' : numpy.array(numpy.ones((N,nbins), dtype=float)*numpy.nan),
93         }
94
95     # current profile count
96     i = 0
97
98     for line in lines:
99         ysi = []
100         # split line and parse float and integers
101         sw = re.split('[\s/\:]*', line)
102         for s in sw:
103             m = re.search(REAL_RE_STR, s)
104             if m:
105                 ysi.append(float(m.groups()[0]))
106
107         if re.search("Profile Time:", line):
108             HH=ysi[0]
109             MM=ysi[1]
110             SS=ysi[2]
111
112         elif re.search("Profile Date:", line):
113             dd=ysi[0]
114             mm=ysi[1]
115             yyyy=ysi[2]
116
117         elif re.search("Profile Depth:", line):
118             water_depth = ysi[0]/100.  # cm to meters
119             sample_str = '%02d-%02d-%d %02d:%02d:%02d' % (mm,dd,yyyy,HH,MM,SS)
120             # if  sensor_info['utc_offset']:
121             #     sample_dt = scanf_datetime(sample_str, fmt='%m-%d-%Y %H:%M:%S') + \
122             #                 timedelta(hours=sensor_info['utc_offset'])
123             # else:
124             sample_dt = scanf_datetime(sample_str, fmt='%m-%d-%Y %H:%M:%S')
125                                                                        
126             # initialize for new profile at zero for averaging samples within each bin
127             wtemp = numpy.zeros(nbins)
128             cond = numpy.zeros(nbins)
129             salin = numpy.zeros(nbins)
130             turb = numpy.zeros(nbins)
131             ph = numpy.zeros(nbins)
132             chl = numpy.zeros(nbins)
133             do = numpy.zeros(nbins)
134
135             Ns = numpy.zeros(nbins) # count samples per bin for averaging
136
137         elif len(ysi)==14:                                                                             
138             # get sample datetime from data
139             # sample_str = '%02d-%02d-%2d %02d:%02d:%02d' % tuple(ysi[0:6])
140             # if  sensor_info['utc_offset']:
141             #     sample_dt = scanf_datetime(sample_str, fmt='%m-%d-%Y %H:%M:%S') + \
142             #                 timedelta(hours=sensor_info['utc_offset'])
143             # else:
144             # sample_dt = scanf_datetime(sample_str, fmt='%m-%d-%y %H:%M:%S')
145
146             depth = ysi[9] # depth (m)
147             ibin = ((z)<=depth)*(depth<(z+bin_size))
148
149             Ns[ibin] = Ns[ibin]+1
150             wtemp[ibin] = wtemp[ibin]+ysi[6] # water temperature (C)
151             cond[ibin] = cond[ibin]+ysi[7]   # conductivity (mS/cm)
152             salin[ibin] = salin[ibin]+ysi[8] # salinity (ppt or PSU??)
153             #
154             ph[ibin] = ph[ibin]+ysi[10]      # ph
155             turb[ibin] = turb[ibin]+ysi[11]  # turbidity (NTU)
156             chl[ibin] = chl[ibin]+ysi[12]    # chlorophyll (ug/l)
157             do[ibin] = do[ibin]+ysi[13]      # dissolved oxygen (ug/l)
158
159         elif (len(ysi)==0):
160             # average summations by sample count per bin
161             # where count is zero make it NaN so average is not divide by zero
162             Ns[Ns==0]=numpy.nan*Ns[Ns==0]
163            
164             data['dt'][i] = sample_dt # sample datetime
165             data['time'][i] = dt2es(sample_dt) # sample time in epoch seconds
166             data['water_depth'][i] = water_depth
167             # divide by counts
168             data['wtemp'][i] =  wtemp/Ns
169             data['cond'][i] = cond/Ns
170             data['salin'][i] = salin/Ns
171             data['turb'][i] = turb/Ns
172             data['ph'][i] = ph/Ns
173             data['chl'][i] = chl/Ns
174             data['do'][i] = do/Ns
175            
176             i=i+1
177            
178         # if-elif
179     # for line
180
181     return data
182    
183
184 def load_data(inFile):
185     lines=None
186     if os.path.exists(inFile):
187         f = open(inFile, 'r')
188         lines = f.readlines()
189         f.close()
190         if len(lines)<=0:
191             print 'Empty file: '+ inFile           
192     else:
193         print 'File does not exist: '+ inFile
194     return lines
195
196 # from jpier_config_20080411 import *
197 from raw2proc import *
198
199 def test1(fn):
200     lines = load_data(fn)
201     return parse_avp_YSI_6600V2(fn, lines)
202
203 def test2(logFile):
204     pi = get_config('stones_config_YYYYMMDD.platform_info')
205     asi = get_config('stones_config_YYYYMMDD.sensor_info')
206     si = asi['met']
207     lines = load_data(logFile)
208     si['fn'] = logFile
209     (parse, create, update) = import_processors(si['process_module'])
210     return parse(pi, si, logFile)
211
212 if __name__ == '__main__':
213     fn = '/seacoos/data/nccoos/level0/stones/avp/2008_08/AVP1_20080811.dat'
214     # dataFile = 'D:/haines/nc-coos/raw2proc/stones/met/2008_08/AVP1_20080811.wnd'
215
216     # logFile = sys.argv[1]
217     try:
218         data = test1(fn)
219     except:
220         pass
221    
Note: See TracBrowser for help on using the browser.