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

root/raw2proc/trunk/raw2proc/proc_avp_ascii_met.py

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

corrected lon to negative for (longitude W) in config files; corrected misspelled field in all proc_*.py

Line 
1 #!/usr/bin/env python
2 # Last modified:  Time-stamp: <2008-10-01 12:46:26 haines>
3 """
4 how to parse data, and assert what data and info goes into
5 creating and updating monthly netcdf files
6
7
8 parser : output delimited ASCII file from onsite perl script
9 creator : lat, lon, z, time, wspd, wdir, cdir, u, v, nwnd
10
11 updater : time, wspd, wdir, cdir, u, v, nwnd
12
13
14 Examples
15 --------
16
17 >> (parse, create, update) = load_processors('proc_avp_ascii_wnd')
18 or
19 >> si = get_config(cn+'.sensor_info')
20 >> (parse, create, update) = load_processors(si['met']['proc_module'])
21
22 >> lines = load_data(filename)
23 >> data = parse(platform_info, sensor_info, lines)
24 >> create(platform_info, sensor_info, data) or
25 >> update(platform_info, sensor_info, data)
26
27 """
28
29 from raw2proc import *
30 from procutil import *
31 from ncutil import *
32 import time
33
34 now_dt = datetime.utcnow()
35 now_dt.replace(microsecond=0)
36
37 def parser(platform_info, sensor_info, lines):
38     """
39     parse Automated Vertical Profile Station (AVP) Wind data
40
41     Notes
42     -----
43     1. Wind:
44
45     Date, time, speed, dir, compass dir, North , East, n-samples
46         (m/s) (magN) (magN)      (m/s)   (m/s)
47
48     08/11/2008 00:00:00    5.881  197  197  -5.638  -1.674     696
49     08/11/2008 00:30:00    5.506  216  197  -4.448  -3.246     699
50     08/11/2008 01:00:00    7.233  329  159   6.183  -3.754     705
51
52     """
53     import numpy
54     from datetime import datetime
55     from time import strptime
56
57     # get sample datetime from filename
58     fn = sensor_info['fn']
59     sample_dt_start = filt_datetime(fn)[0]
60     N = len(lines)
61     data = {
62         'dt' : numpy.array(numpy.ones((N,), dtype=object)*numpy.nan),
63         'time' : numpy.array(numpy.ones((N,), dtype=long)*numpy.nan),
64         'wspd' : numpy.array(numpy.ones((N,), dtype=float)*numpy.nan),
65         'wdir' : numpy.array(numpy.ones((N,), dtype=float)*numpy.nan),
66         'cdir' : numpy.array(numpy.ones((N,), dtype=float)*numpy.nan),
67         'v' : numpy.array(numpy.ones((N,), dtype=float)*numpy.nan),
68         'u' : numpy.array(numpy.ones((N,), dtype=float)*numpy.nan),
69         'nwnd' : numpy.array(numpy.ones((N,), dtype=int)*numpy.nan),
70         }
71
72     i = 0
73     lines.sort()
74
75     mvar = platform_info['mvar']  # Magnetic Variation at station
76     # mvar = -8.0 # (??????)
77
78     wnd = []
79     for line in lines:
80         wnd = []
81         # split line and parse float and integers
82         sw = re.split('[\s/\:]*', line)
83         for s in sw:
84             m = re.search(REAL_RE_STR, s)
85             if m:
86                 wnd.append(float(m.groups()[0]))
87
88         if len(wnd)==12:                                                                             
89             # get sample datetime from data
90             sample_str = '%02d-%02d-%4d %02d:%02d:%02d' % tuple(wnd[0:6])
91             if  sensor_info['utc_offset']:
92                 sample_dt = scanf_datetime(sample_str, fmt='%m-%d-%Y %H:%M:%S') + \
93                             timedelta(hours=sensor_info['utc_offset'])
94             else:
95                 sample_dt = scanf_datetime(sample_str, fmt='%m-%d-%Y %H:%M:%S')
96
97             wspd = int(wnd[6]) # wind speed (m/s)
98             wdir = int(wnd[7]) # wind dir (mag N)
99             cdir = wnd[8]      # compass dir (mag N)
100             u = wnd[9]         # Easterly (?) Component (m/s) (mag or true??)
101             v = wnd[10]        # Northerly (?) Component (m/s) (mag or true??)
102             nwnd = int(wnd[11]) # Number of samples in wind average
103
104             # combine wind dir and buoy compass direction
105             # correct direction from magnetic N to true N
106             # rotate u, v to true N
107             # or
108             # recompute u, v from direction and speed
109
110             data['dt'][i] = sample_dt # sample datetime
111             data['time'][i] = dt2es(sample_dt) # sample time in epoch seconds
112             data['wspd'][i] =  wspd
113             data['wdir'][i] = wdir
114             data['cdir'][i] = cdir
115             data['u'][i] = u
116             data['v'][i] = v
117             data['nwnd'][i] = nwnd
118
119             i=i+1
120
121         # if len(wnd)==12
122     # for line
123
124     return data
125
126 def creator(platform_info, sensor_info, data):
127         #
128         #
129         title_str = sensor_info['description']+' at '+ platform_info['location']
130         global_atts = {
131                 'title' : title_str,
132                 'institution' : 'University of North Carolina at Chapel Hill (UNC-CH)',
133                 'institution_url' : 'http://nccoos.org',
134                 'institution_dods_url' : 'http://nccoos.org',
135                 'metadata_url' : 'http://nccoos.org',
136                 'references' : 'http://nccoos.org',
137                 'contact' : 'Sara Haines (haines@email.unc.edu)',
138                 #
139                 'source' : 'AVP Wind Observations',
140                 'history' : 'raw2proc using ' + sensor_info['process_module'],
141                 'comment' : 'File created using pycdf'+pycdfVersion()+' and numpy '+pycdfArrayPkg(),
142                 # conventions
143                 'Conventions' : 'CF-1.0; SEACOOS-CDL-v2.0',
144                 # SEACOOS CDL codes
145                 'format_category_code' : 'fixed-point',
146                 'institution_code' : platform_info['institution'],
147                 'platform_code' : platform_info['id'],
148                 'package_code' : sensor_info['id'],
149                 # institution specific
150                 'project' : 'North Carolina Coastal Ocean Observing System (NCCOOS)',
151                 'project_url' : 'http://nccoos.org',
152                 # timeframe of data contained in file yyyy-mm-dd HH:MM:SS
153                 'start_date' : data['dt'][0].strftime("%Y-%m-%d %H:%M:%S"),
154                 'end_date' : data['dt'][-1].strftime("%Y-%m-%d %H:%M:%S"),
155                 'release_date' : now_dt.strftime("%Y-%m-%d %H:%M:%S"),
156                 #
157                 'creation_date' : now_dt.strftime("%Y-%m-%d %H:%M:%S"),
158                 'modification_date' : now_dt.strftime("%Y-%m-%d %H:%M:%S"),
159                 'process_level' : 'level1',
160                 #
161                 # must type match to data (e.g. fillvalue is real if data is real)
162                 '_FillValue' : -99999.,
163                 }
164
165         var_atts = {
166                 # coordinate variables
167                 'time' : {'short_name': 'time',
168                           'long_name': 'Sample Time',
169                           'standard_name': 'time',
170                           'units': 'seconds since 1970-1-1 00:00:00 -0', # UTC
171                           'axis': 'T',
172                           },
173                 'lat' : {'short_name': 'lat',
174                          'long_name': 'Latitude in Decimal Degrees',
175                          'standard_name': 'latitude',
176                          'reference':'geographic coordinates',
177                          'units': 'degrees_north',
178                          'valid_range':(-90.,90.),
179                          'axis': 'Y',
180                          },
181                 'lon' : {'short_name': 'lon',
182                          'long_name': 'Longitude in Decimal Degrees',
183                          'standard_name': 'longitude',
184                          'reference':'geographic coordinates',
185                          'units': 'degrees_east',
186                          'valid_range':(-180.,180.),
187                          'axis': 'Y',
188                          },
189                 'z' : {'short_name': 'z',
190                        'long_name': 'Height',
191                        'standard_name': 'height',
192                        'reference':'zero at sea-surface',
193                        'positive': 'up',
194                        'units': 'm',
195                        'axis': 'Z',
196                        },
197                 # data variables
198                 'wspd' : {'short_name': 'wspd',
199                           'long_name': 'Wind Speed',
200                           'standard_name': 'wind_speed',
201                           'units': 'm s-1',
202                           'can_be_normalized': 'no',
203                           'z' : sensor_info['anemometer_height'],
204                           },
205                 'wdir' : {'short_name': 'wdir',
206                           'long_name': 'Wind Direction from',
207                           'standard_name': 'wind_from_direction',
208                           'reference': 'clockwise from Magnetic North',
209                           'valid_range': (0., 360),
210                           'units': 'degrees',
211                           'z' : sensor_info['anemometer_height'],
212                           },
213                 'cdir' :  {'short_name': 'cdir',
214                            'long_name': 'Buoy Orientation',
215                            'standard_name': 'compass_direction',
216                            'reference': 'clockwise from Magnetic North',
217                            'valid_range': (0., 360),
218                            'units': 'degrees',
219                            },
220                 'u' : {'short_name': 'u',
221                        'long_name': 'East/West Component of Wind',
222                        'standard_name': 'eastward_wind',
223                        'reference': 'relative to True East (?)',
224                        'units': 'm s-1',
225                        'can_be_normalized': 'no',
226                        'z' : sensor_info['anemometer_height'],
227                        },
228                 'v' : {'short_name': 'v',
229                        'long_name': 'North/South Component of Wind',
230                        'standard_name': 'northward_wind',
231                        'reference': 'relative to True North (?)',
232                        'units': 'm s-1',
233                        'can_be_normalized': 'no',
234                        'z' : sensor_info['anemometer_height'],
235                        },
236                 'nwnd' : {'short_name': 'nwnd',
237                        'long_name': 'Number of wind samples in sample period',
238                        'standard_name': 'number_of_samples',
239                        'units': 'm s-1',
240                        },
241                
242         }
243        
244         # dimension names use tuple so order of initialization is maintained
245         dim_inits = (
246                 ('ntime', NC.UNLIMITED),
247                 ('nlat', 1),
248                 ('nlon', 1),
249                 ('nz', 1)
250                 )
251
252         # using tuple of tuples so order of initialization is maintained
253         # using dict for attributes order of init not important
254         # use dimension names not values
255         # (varName, varType, (dimName1, [dimName2], ...))
256         var_inits = (
257                 # coordinate variables
258                 ('time', NC.INT, ('ntime',)),
259                 ('lat', NC.FLOAT, ('nlat',)),
260                 ('lon', NC.FLOAT, ('nlon',)),
261                 ('z',  NC.FLOAT, ('nz',)),
262                 # data variables
263                 ('wspd', NC.FLOAT, ('ntime',)),
264                 ('wdir', NC.FLOAT, ('ntime',)),
265                 ('cdir', NC.FLOAT, ('ntime',)),
266                 ('u', NC.FLOAT, ('ntime',)),
267                 ('v', NC.FLOAT, ('ntime',)),
268                 ('nwnd', NC.FLOAT, ('ntime',)),
269                 )
270
271         # subset data only to month being processed (see raw2proc.process())
272         i = data['in']
273
274         # var data
275         var_data = (
276                 ('lat',  platform_info['lat']),
277                 ('lon', platform_info['lon']),
278                 ('z', 1),
279                 #
280                 ('time', data['time'][i]),
281                 ('wspd', data['wspd'][i]),
282                 ('wdir', data['wdir'][i]),
283                 ('cdir', data['cdir'][i]),
284                 ('u', data['u'][i]),
285                 ('v', data['v'][i]),
286                 ('nwnd', data['nwnd'][i]),
287                 )
288                
289         return (global_atts, var_atts, dim_inits, var_inits, var_data)
290
291 def updater(platform_info, sensor_info, data):
292         #
293         global_atts = {
294                 # update times of data contained in file (yyyy-mm-dd HH:MM:SS)
295                 # last date in monthly file
296                 'end_date' : data['dt'][-1].strftime("%Y-%m-%d %H:%M:%S"),
297                 'release_date' : now_dt.strftime("%Y-%m-%d %H:%M:%S"),
298                 #
299                 'modification_date' : now_dt.strftime("%Y-%m-%d %H:%M:%S"),
300                 }
301
302         # data variables
303         # update any variable attributes like range, min, max
304         var_atts = {}
305         # var_atts = {
306         #       'u': {'max': max(data.u),
307         #                 'min': min(data.v),
308         #                 },
309         #       'v': {'max': max(data.u),
310         #                 'min': min(data.v),
311         #                 },
312         #       }
313        
314         # subset data only to month being processed (see raw2proc.process())
315         i = data['in']
316
317         # data
318         var_data = (
319                 ('time', data['time'][i]),
320                 ('wspd', data['wspd'][i]),
321                 ('wdir', data['wdir'][i]),
322                 ('cdir', data['cdir'][i]),
323                 ('u', data['u'][i]),
324                 ('v', data['v'][i]),
325                 ('nwnd', data['nwnd'][i]),
326                 )
327
328         return (global_atts, var_atts, var_data)
329
330 #
Note: See TracBrowser for help on using the browser.