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

root/raw2proc/trunk/raw2proc/proc_rdi_rawdata_adcp.py

Revision 101 (checked in by haines, 16 years ago)

first commit of code

Line 
1 #!/usr/bin/env python
2 # Last modified:  Time-stamp: <2007-12-27 15:16:33 haines>
3 """
4 how to parse data, and assert what data and info goes into
5 creating and updating monthly netcdf files
6
7 RDI/Wavesmon processed adcp current profile data
8
9 parser : sample date and time, ensemble number, currents
10          and wave summary output from WavesMon software
11 nc_creator :
12 nc_updator :
13
14 Examples
15 --------
16
17 >> (parse, create, update) = load_processors('proc_rdi_logdata')
18 >> data = parse(lines)
19 >> create(platform_info, sensor_info, data)
20 >> update(platform_info, sensor_info, data)
21
22 """
23
24 def parser(lines):
25     """
26     parse and assign currents data from RDI ADCP Log Data
27
28     """
29     i = 0
30    
31     for line in lines:
32         # split line and parse float and integers
33         rdi = []
34         sw = re.split(',', line)
35         for s in sw:
36             m = re.search(REAL_RE_STR, s)
37             if m:
38                 rdi.append(float(m.groups()[0]))
39
40         # assign specific fields
41         n = len(rdi)
42         burst_num = int(rdi[0]) # Ensemble Number
43
44         # get sample datetime from data
45         sample_str = '%02d-%02d-%02d %02d:%02d:%02d' % tuple(rdi[1:7])
46         sample_dt = datetime(*strptime(sample_str, "%y-%m-%d %H:%M:%S")[0:6])
47
48         # get sample datetime from filename
49         # compare with datetime from filename
50
51         sig_wave_ht = rdi[8]         # Significant Wave Height (Hs, meters)
52         peak_wave_period = rdi[9]    # Peak Wave Period (Tp, sec)
53         peak_wave_dir = rdi[10]      # Peak Wave Direction (deg N)
54         max_wave_ht = rdi[12]        # Maximum Wave Height (Hmax, meters)
55         max_wave_period = rdi[13]    # Maximum Wave Period (Tmax, sec)
56
57         water_depth = rdi[11]/1000   # Water Depth (meters) (based on ADCP backscatter or input config??)
58         nbins = int(rdi[14])         # Number of bins
59
60         current_spd = numpy.array(rdi[15::2]) # starting at idx=15 skip=2 to end
61         current_dir = numpy.array(rdi[16::2]) # starting at idx=16 skip=2 to end
62
63         if nbins!=sensor_info['adcp']['nbins']:
64             print 'Number of bins reported in data ('+ \
65                   str(nbins)+') does not match config number ('+ \
66                   str(sensor_info['adcp']['nbins'])+')'
67
68         if len(current_spd)!=nbins or len(current_dir)!=nbins:
69             print 'Data length does not match number of bins in data'
70
71         ibad = (current_spd==-32768) | (current_dir==-32768)
72         current_spd[ibad] = numpy.nan
73         current_dir[ibad] = numpy.nan
74
75         # these items can also be teased out of raw adcp but for now get from config file
76         th = sensor_info['adcp']['transducer_ht'# Transducer height above bottom (meters)
77         bh = sensor_info['adcp']['blanking_ht']    # Blanking height above Transducer (meters)
78         bin_size = sensor_info['adcp']['bin_size'] # Bin Size (meters)
79
80         # compute height for each bin above the bottom
81         bins = numpy.arange(1,nbins+1)
82         bin_habs = (bins*bin_size+bin_size/2)+th+bh
83
84         # compute water mask
85         # Using George Voulgaris' method based on water depth
86         # minus half of the significant wave height (Hs)
87         # and computed habs
88         # if positive is up, what's less than zero depth?
89         bin_depths =  bin_habs-(water_depth-sig_wave_ht/2)
90         iwater = bin_depths+bin_size/2 < 0
91
92         z = bin_habs
93         # check that length of bin_depths is equal to nbins
94         u = numpy.ones(nbins)*numpy.nan
95         v = numpy.ones(nbins)*numpy.nan
96
97         u[iwater] = current_spd[iwater]*numpy.sin(current_dir[iwater]*numpy.pi/180)
98         v[iwater] = current_spd[iwater]*numpy.cos(current_dir[iwater]*numpy.pi/180)
99
100         # set up dict of data if first line
101         if i==0:
102             data = {
103                 'en' : numpy.array(numpy.ones((len(lines),), dtype=float)*numpy.nan),
104                 'dt' : numpy.array(numpy.ones((len(lines),), dtype=object)*numpy.nan),
105                 'nbins' : numpy.array(numpy.zeros((len(lines),), dtype=int)),
106                 'z' : numpy.array(numpy.ones((len(lines),nbins), dtype=float)*numpy.nan),
107                 'u' : numpy.array(numpy.ones((len(lines),nbins), dtype=float)*numpy.nan),
108                 'v' : numpy.array(numpy.ones((len(lines),nbins), dtype=float)*numpy.nan),
109                 }
110        
111         data['en'][i] = burst_num
112         data['dt'][i] = sample_dt
113         data['nbins'][i] =  nbins
114         data['z'][i] =  z
115         data['u'][i] =  u
116         data['v'][i] =  v
117         i = i+1
118
119     return data
120
121 def creator(platform_info, sensor_info, data):
122     #
123     #
124     title_str = sensor_info['description']+' at '+ platform_info['location']
125     global_atts = {
126         'title' : title_str,
127         'institution' : 'Unversity of North Carolina at Chapel Hill (UNC-CH)',
128         'institution_url' : 'http://nccoos.unc.edu',
129         'institution_dods_url' : 'http://nccoos.unc.edu',
130         'metadata_url' : 'http://nccoos.unc.edu',
131         'references' : 'http://nccoos.unc.edu',
132         'contact' : 'Sara Haines (haines@email.unc.edu)',
133         #
134         'source' : 'fixed-profiler (acoustic doppler) observation',
135         'history' : 'Data processed by NCCOOS',
136         'comment' : 'File created using pycdf'+pycdfVersion()+' and numpy '+pycdfArrayPkg(),
137         # conventions
138         'Conventions' : 'CF-1.0; SEACOOS-CDL-v2.0',
139         # SEACOOS CDL codes
140         'format_category_code' : 'fixed-profiler',
141         'institution_code' : platform_info['instituion'],
142         'platform_code' : platform_info['id'],
143         'package_code' : sensor_info['id'],
144         # institution specific
145         'project' : 'North Carolina Coastal Ocean Observing System (NCCOOS)',
146         'project_url' : 'http://nccoos.unc.edu',
147         # timeframe of data contained in file yyyy-mm-dd HH:MM:SS
148         'start_date' : data['sample_dt'].strftime("%Y-%m-%d %H:%M:%S"),
149         'end_date' : data['sample_dt'].strftime("%Y-%m-%d %H:%M:%S"),
150         'release_date' : now.strftime("%Y-%m-%d %H:%M:%S"),
151         #
152         'creation_date' : now.strftime("%Y-%m-%d %H:%M:%S"),
153         'modification_date' : now.strftime("%Y-%m-%d %H:%M:%S"),
154         'process_level' : 'level1',
155         #
156         # must type match to data (e.g. fillvalue is real if data is real)
157         '_FillValue' : -99999.,
158         }
159
160     var_atts = {
161         # coordinate variables
162         'time' : {'short_name': 'time',
163                   'long_name': 'Time',
164                   'standard_name': 'time',
165                   'units': 'seconds since 1970-1-1 00:00:00 -0', # UTC
166                   'axis': 'T',
167                   },
168         'lat' : {'short_name': 'lat',
169              'long_name': 'Latitude',
170              'standard_name': 'latitude',
171              'reference':'geographic coordinates',
172              'units': 'degrees_north',
173              'valid_range':(-90.,90.),
174              'axis': 'Y',
175              },
176         'lon' : {'short_name': 'lon',
177                  'long_name': 'Longtitude',
178                  'standard_name': 'longtitude',
179                  'reference':'geographic coordinates',
180                  'units': 'degrees_east',
181                  'valid_range':(-180.,180.),
182                  'axis': 'Y',
183                  },
184         'z' : {'short_name': 'z',
185                'long_name': 'Height',
186                'standard_name': 'height',
187                'reference':'zero at sea-surface',
188                'units': 'm',
189                'axis': 'Z',
190                },
191         # data variables
192         'u': {'long_name': 'East/West Component of Current',
193               'standard_name': 'eastward_current',
194               'units': 'm s-1',
195               'reference': 'clockwise from True East',
196               },
197         'v': {'long_name': 'North/South Component of Current',
198               'standard_name': 'northward_current',                         
199               'units': 'm s-1',
200               'reference': 'clockwise from True North',
201               },
202         'w': {'long_name': 'Upward/Downward Component of Current',
203               'standard_name': 'upward_current',                         
204               'units': 'm s-1',
205               'positive': 'up',
206               },
207         'back_scatter':{'long_name': 'Backscatter',
208                         'standard_name': 'back_scatter',                   
209                         'units': 'decibels',
210                         },
211         'wtemp': {'long_name': 'Water Temperature',
212                   'standard_name': 'water_temperature',
213                   'units': 'degrees Celsius',
214                   },
215         }
216
217
218     # integer values
219     ntime=NC.UNLIMITED
220     nlat=1
221     nlon=1
222     nz=sensor_info['nbins']
223    
224     # dimension names use tuple so order of initialization is maintained
225     dimensions = ('ntime', 'nlat', 'nlon', 'nz')
226    
227     # using tuple of tuples so order of initialization is maintained
228     # using dict for attributes order of init not important
229     # use dimension names not values
230     # (varName, varType, (dimName1, [dimName2], ...))
231     var_inits = (
232         # coordinate variables
233         ('time', NC.INT, ('ntime',)),
234         ('lat', NC.FLOAT, ('nlat',)),
235         ('lon', NC.FLOAT, ('nlon',)),
236         ('z',  NC.FLOAT, ('nz',)),
237         # data variables
238         ('u', NC.FLOAT, ('ntime', 'nz')),
239         ('v', NC.FLOAT, ('ntime', 'nz')),
240         ('w', NC.FLOAT, ('ntime', 'nz')),
241         ('back_scatter', NC.FLOAT, ('ntime', 'nz')),
242         ('wtemp', NC.FLOAT, ('ntime',)),
243         )
244    
245     # var data
246     var_data = (
247         ('lat',  platform_info['lat']),
248         ('lon', platform_info['lon']),
249         ('z', []),
250         ('u', []),
251         ('v', []),
252         ('w', []),
253         ('back_scatter', []),
254         ('wtemp', []),
255         )
256
257     return (global_atts, dimensions, var_inits, var_data)
258
259 def updater(platform_info, sensor_info, data):
260     #
261     global_atts = {
262         # timeframe of data contained in file yyyy-mm-dd HH:MM:SS
263         'end_date' : data['sample_dt'].strftime("%Y-%m-%d %H:%M:%S"),
264         'release_date' : now.strftime("%Y-%m-%d %H:%M:%S"),
265         #
266         'creation_date' : now.strftime("%Y-%m-%d %H:%M:%S"),
267         'modification_date' : now.strftime("%Y-%m-%d %H:%M:%S"),
268         }
269     # var data
270     var_data = (
271         ('u', data['u']),
272         ('v', data['v']),
273         ('w',  data['w']),
274         ('back_scatter', data['back_scatter']),
275         ('wtemp', data['wtemp']),
276         )
277     return (global_atts, var_data)
278 #
279
Note: See TracBrowser for help on using the browser.